TemplateService.Parse дает недопустимый токен для олицетворения — его нельзя дублировать при использовании анонимной модели и имени кеша.

Я следовал этому руководству, чтобы использовать RazorEngine для создания электронных писем в формате HTML. (без ASP.NET MVC). Это работало нормально, когда я использовал либо строго типизированное представление, либо анонимный объект в качестве модели:

Layout.cshtml

@model dynamic
// html contents...

Фрагмент C#

var template = Encoding.UTF8.GetString(Properties.Resources.ContractList);

var model = new
{
    ContractList = list
};

var templateService = new TemplateService();
var html = templateService.Parse(template, model, null, null);

Затем я дал ему имя кеша, как рекомендовано в третья часть руководства:

templateService.Parse(template, model, null, nameof(Properties.Resources.ContractList));

Он отлично работал со строго типизированным объектом, но с анонимным объектом я начал получать это сообщение со второго запуска:

Недопустимый токен для олицетворения — его нельзя дублировать

Как я могу решить эту проблему и по-прежнему использовать анонимный объект для модели?

Я видел решения (здесь, здесь), которые предлагают преобразовать анонимный объект в ExpandoObject, но я бы хотел чтобы избежать этого, если это возможно.


person Marcos Dimitrio    schedule 10.12.2015    source источник


Ответы (1)


Прочитав документацию RazorEngine, я нашел несколько примеров на их странице обновления, которые показал, как использовать Engine.Razor. Самый простой способ сделать это:

var html = Engine.Razor.RunCompile(
    template,
    nameof(Properties.Resources.ContractList),
    null,
    model
);

Это решило проблему. Просто имейте в виду, что они не рекомендуют указанный выше формат, потому что внутренне он будет вызывать AddTemplate каждый раз и будет вызывать исключение, когда вы используете один и тот же cache_name для разных шаблонов. Вместо этого они рекомендуют выполнять предварительную компиляцию при запуске:

// Once at startup (not required when using an ITemplateManager which knows how to
// resolve cache_name)
Engine.Razor.AddTemplate(cache_name, razorTemplate)
// On startup
Engine.Razor.Compile(
    cache_name, 
    typeof(MyModel) /* or model.GetType() or null for 'dynamic'*/
)

// instead of the Razor.Parse call
var result = Engine.Razor.Run(
    cache_name,
    typeof(MyModel), /* or model.GetType() or null for 'dynamic'*/
    model
)
person Marcos Dimitrio    schedule 10.12.2015