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
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.
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;
Here are a few hints you might try:
Make your razor view strongly typed to a model:
@model Foo
<div>
<div>
Link:
<a href="@Model.ActivationLink" style="color:#666" target="_blank">
@Model.ActivationLink
</a>
</div>
</div>
When rendering it pass a Foo
model:
_emailService.Render(
TemplatePath,
"Email.cshtml",
new Foo { ActivationLink = activationLink }
)
If you are trying to send emails from your Views make sure you checkout Postal before reinventing something.