Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RazorEngine and parsing physical view files always causes exception

I have the following RazorEngine call:

public class RazorEngineRender
{
    public static string RenderPartialViewToString(string templatePath, string viewName, object model)
    {            
        string text = System.IO.File.ReadAllText(Path.Combine(templatePath, viewName));
        string renderedText = Razor.Parse(text, model);
        return renderedText;
    }
}

This is called from:

_emailService.Render(TemplatePath, "Email.cshtml", new { ActivationLink = activationLink });

I also have this view file (email.cshtml):

    <div>
      <div>
            Link: <a href="@Model.ActivationLink" style="color:#666" target="_blank">@Model.ActivationLink</a>
      </div>
    </div>

When the call to Razor.Parse() occurs, I always get a: Unable to compile template. Check the Errors list for details.

The error list is:

error CS1061: 'object' does not contain a definition for 'ActivationLink' and no extension method 'ActivationLink' accepting a first argument of type 'object' could be found 

I've tried everything under the sun, including trying a concrete type as opposed to anonymous type, declaring the @Model line at the top of the view file but no luck. I'm wondering if the library is at fault or definately me?

By the way, the razorengine I am referring to is available here at codeplex: RazorEngine

like image 772
jaffa Avatar asked Mar 09 '11 16:03

jaffa


2 Answers

If you make the call like so:

Razor.Parse(System.IO.File.ReadAllText(YourPath), 
            new { ActivationLink = activationLink });

That should give you the correct output. But after I see your method posted above I'll be able to make a determination where the problem lies.

Update

Change your method to the following:

public class RazorEngineRender {
    public static string RenderPartialViewToString<T>(string templatePath, string viewName, T model) {            
        string text = System.IO.File.ReadAllText(Path.Combine(templatePath, viewName));
        string renderedText = Razor.Parse(text, model);
        return renderedText;
    }
}

and you can call it like you do above.

The reason it doesn't work is because you're telling the Parser that the model is of type object rather than passing in what type it really is. In this case an anonymous type.

like image 197
Buildstarted Avatar answered Sep 21 '22 14:09

Buildstarted


The accepted answer was perfect in 2011 (I believe pre-v3 of RazorEngine) but this code is now marked as obsolete in latest version (in time of typing it is 3.7.3).

For newer version your method can be typed like this:

public static string RenderPartialViewToString<T>(string templatePath, string templateName, string viewName, T model)
        {
            string template = File.ReadAllText(Path.Combine(templatePath, viewName));
            string renderedText = Engine.Razor.RunCompile(template, templateName, typeof(T), model);
            return renderedText;
        }

and in order for it to work you need to add

using RazorEngine.Templating;
like image 38
Zoran P. Avatar answered Sep 20 '22 14:09

Zoran P.