RazorEngine и синтаксический анализ файлов физического представления всегда вызывает исключение
У меня есть следующий вызов RazorEngine:
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;
}
}
Вызывается из:
_emailService.Render(TemplatePath, "Email.cshtml", new { ActivationLink = activationLink });
У меня также есть этот файл вида (email.cshtml):
<div>
<div>
Link: <a href="@Model.ActivationLink" style="color:#666" target="_blank">@Model.ActivationLink</a>
</div>
</div>
Когда происходит вызов Razor.Parse(), я всегда получаю:
Невозможно скомпилировать шаблон. Подробнее см. В списке "Ошибки".
Список ошибок:
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
Я пробовал все под солнцем, включая попытку конкретного типа, а не анонимного типа, объявляя строку @Model в верхней части файла представления, но не повезло. Мне интересно, если библиотека виновата или определенно меня?
Кстати, razorengine, о котором я говорю, доступен здесь, в codeplex:
RazorEngine
Ответы
Ответ 1
Если вы выполните вызов следующим образом:
Razor.Parse(System.IO.File.ReadAllText(YourPath),
new { ActivationLink = activationLink });
Это должно дать вам правильный результат. Но после того, как я увижу ваш метод выше, я смогу сделать определение, где проблема.
Update
Измените свой метод на следующее:
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;
}
}
и вы можете называть его, как вы делаете выше.
Причина, по которой он не работает, заключается в том, что вы сообщаете Parser, что модель имеет объект типа, а не передает то, что на самом деле. В этом случае анонимный тип.
Ответ 2
Принятый ответ был прекрасным в 2011 году (я считаю, pre-v3 из RazorEngine), но этот код теперь помечается как устаревший в последней версии (во время ввода - 3.7.3).
Для более новой версии ваш метод можно ввести следующим образом:
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;
}
и для его работы вам нужно добавить
using RazorEngine.Templating;
Ответ 3
Вот несколько советов, которые вы можете попробовать:
-
Сделайте свой вид бритвы строго типизированным для модели:
@model Foo
<div>
<div>
Link:
<a href="@Model.ActivationLink" style="color:#666" target="_blank">
@Model.ActivationLink
</a>
</div>
</div>
-
При рендеринге он передает модель Foo
:
_emailService.Render(
TemplatePath,
"Email.cshtml",
new Foo { ActivationLink = activationLink }
)
-
Если вы пытаетесь отправить электронные сообщения из своих представлений, убедитесь, что вы checkout Postal перед тем как изобретать что-то.