Razorlight: How to pass ExpandoObject as Model?

Created on 13 Aug 2018  路  8Comments  路  Source: toddams/RazorLight

Hello,

iam trying to pass a ExpandoObject as Model to the RazorLightEngineBuilder and always receive:

"InvalidOperationException: Can not resolve a content for the template "{0}" as there is no project set.You can only render a template by passing it's content directly via string using coresponding function overload"

I dont understand the error in this case. Why do I need to set a project when the model changes?
The quick and dirty code iam using:

            var engine = new RazorLightEngineBuilder()
              .UseMemoryCachingProvider()
              .Build();

            string template = "Hello, @Model.Name. Welcome to RazorLight repository";
            dynamic expando = new ExpandoObject();
            expando.Name = "John Doe";

            string result = engine.CompileRenderAsync("templateKey", template, expando).Result;

When switching to a stronglyTyped Model it does work.

Any code samples showing me how to handle "dynamic properties"/ExpandoObject would be great!

Thanks alot!

Most helpful comment

@smcl Thanks! Hope my stepping into help Ivan maintain this is helping your company and projects out! This is a great project, so keep on giving this great feedback. Great communities = great open source software = YOU are a great person.

All 8 comments

I'm hitting that as well. @C0d1ngJammer have you found a way around that issue?

var engine = new RazorLightEngineBuilder().UseMemoryCachingProvider().Build();
string temp = "Hello, @Model.Name. Welcome to RazorLight repository";
dynamic o = new ExpandoObject();
o.Model = new { Name = "Bar" }.ToExpando();

I don't know what the original issue was, but with 2.0.0-betaX in master what's happening is that this method is called:

public Task<string> CompileRenderAsync<T>(string key, T model, ExpandoObject viewBag = null)
{
    return _handler.CompileRenderAsync(key, model, viewBag);
}

Which also fails. What @C0d1ngJammer probably wants (if they are still interested) is the IRazorLightEngine.CompileRenderStringAsync() method, so the original snippet would look like this

var engine = new RazorLightEngineBuilder()
  .UseMemoryCachingProvider()
  .Build();

string template = "Hello, @Model.Name. Welcome to RazorLight repository";
dynamic expando = new ExpandoObject();
expando.Name = "John Doe";

string result = engine.CompileRenderStringAsync("templateKey", template, expando).Result;

Both strongly-typed objects and dynamic work fine in this scenario, I think it can be closed - unless @C0d1ngJammer has any objections?

@smcl That makes sense to me. Thanks for contributing. To be clear, since I started helping with this project at 2.0.0-Beta2, are you saying Razorlight 1.x had a version of CompileRenderAsync that is potentially a silent "compiler error" due to implicit conversions? That's what I heard you say, which is a bit scary.

Hey @jzabroski. I can put your mind at ease a little, I think. RazorLight didn't have a method called CompileRenderAsync so there wasn't a weird compiler error there.

Maybe it's worth me giving a little more detail on why I think this is a non-issue and can be closed. Going by the date this issue was reported it is likely that 2.0 beta 1 was used, I recreated the issue using this version and it seems that it's a pretty straightforward case of user error. The code _does_ compile just fine because the parameters used happen to match a valid overload of CompileRenderAsync (the one I mentioned in my previous comment). But at runtime that overload doesn't do what the user intended - it doesn't render a template that's passed in via a that second parameter, it can only render those it can lookup by the "key" parameter. The CompileRenderString method I suggested _does_ do what the person intended, but that must have been introduced in a later beta.

So yeah, no weird scary behaviour :-)

@smcl Thanks! Hope my stepping into help Ivan maintain this is helping your company and projects out! This is a great project, so keep on giving this great feedback. Great communities = great open source software = YOU are a great person.

Same to you man, keep up the good work :+1:

@smcl Sorry, I owe you an answer. Almost more than a half year past and I did not expect any response anymore.
With the version 2.0.0-beta7 it does work indeed now. I Added UseEmbeddedResourcesProject(typeof(RazorTemplateEngine)) and used the new method CompileRenderStringAsync.
My user is able to choose between different Template-Parser. I had 2 fallback template-parser, thats why I did not track this INC anymore.
Thanks alot
-Manuel

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AdrianPell picture AdrianPell  路  4Comments

Hubert-Rybak picture Hubert-Rybak  路  5Comments

IInvocation picture IInvocation  路  6Comments

Wolftousen picture Wolftousen  路  5Comments

dombarnes picture dombarnes  路  7Comments