Шаблонирование с использованием нового API RazorEngine
Некоторое время назад рендеринг шаблона с использованием RazorEngine
было так же просто, как:
string s = RazorEngine.Razor.Parse()
Однако по какой-то причине его авторы изменили свое мнение об API, и теперь самый простой способ визуализации шаблона:
var key = new RazorEngine.Templating.NameOnlyTemplateKey("EmailTemplate", RazorEngine.Templating.ResolveType.Global, null);
RazorEngine.Engine.Razor.AddTemplate(key, new RazorEngine.Templating.LoadedTemplateSource("Ala ma kota"));
StringBuilder sb = new StringBuilder();
StringWriter sw = new StringWriter(sb);
RazorEngine.Engine.Razor.RunCompile(key, sw);
string s = sb.ToString();
(По крайней мере, это то, что я вывел из нового API. Старый помечен как устаревший.) Есть ли способ использовать новый API для рендеринга шаблона без кеширования, ключей и прочего? Все официальные примеры просто не работают.
4 ответа
После поиска кода я нашел несколько полезных примеров ( https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Hosts.Console/Program.cs) и обнаружил, что если вы включите
using RazorEngine.Templating;
В верхней части вашего класса вы можете использовать некоторые методы расширения ( https://github.com/Antaris/RazorEngine/blob/master/src/source/RazorEngine.Core/Templating/RazorEngineServiceExtensions.cs), которые помогут вам.
Безболезненная подборка шаблонов:
Engine.Razor.Compile(templatePath, "templateNameInTheCache", modelType);
Разбор шаблона:
Engine.Razor.Run("templateNameInTheCache", modelType, model);
И теперь вы можете сделать оба одновременно!
string myParsedTemplate = Engine.Razor.RunCompile(templatePath, "templateNameInTheCache", null, model)
Что эквивалентно делать это
Engine.Razor.AddTemplate("templateNameInTheCache", TemplateLoader.GetTemplate(templatePath));
Engine.Razor.Compile("templateNameInTheCache", modelType);
string finallyThisIsMyParsedTemplate = Engine.Razor.Run("templateNameInTheCache", modelType);
Обратите внимание, что в настоящее время я тестирую это, но, похоже, работает нормально.
Следующий код работает для ResolvePathTemplateManager
(Октябрь 2017 г.):
var templateManager = new ResolvePathTemplateManager(new[] { rootPath });
var config = new TemplateServiceConfiguration
{
TemplateManager = templateManager
};
Engine.Razor = RazorEngineService.Create(config);
// ...
var html = Engine.Razor.RunCompile("Test.cshtml", null, model);
Источник: в RazorEngineServiceTestFixture.cs, ищите ResolvePathTemplateManager
,
К вашему сведению, использование RazorEngine API приводит к утечке памяти. Сообщается об официальной проблеме, заключающейся в том, что при компиляции шаблонов постоянно создаются временные файлы, от которых очень трудно избавиться. Так что будьте очень осторожны, если используете это в продакшене.
В последний раз, когда я использовал это, он продолжал добавлять +1 МБ к памяти при каждой компиляции шаблона, даже при использовании кешированных шаблонов!
Основываясь на ответе @turdus-merula, я хотел, чтобы временные файлы были очищены при выгрузке AppDomain по умолчанию. Я отключил временную блокировку файла в конфиге, что позволяет удалять временную папку.
var config = new TemplateServiceConfiguration
{
TemplateManager = new ResolvePathTemplateManager(new[] {"EmailTemplates"}),
DisableTempFileLocking = true
};
Engine.Razor = RazorEngineService.Create(config);
var html = Engine.Razor.RunCompile("Test.cshtml", null, model);