RazorEngine и анализ файлов физического вида всегда вызывают исключение - PullRequest
13 голосов
/ 09 марта 2011

У меня есть следующий вызов 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 

Я пробовал все под солнцем, включая попытку конкретного типа, а не анонимного типа, объявив @Модельная строка вверху файла просмотра, но не повезло.Я задаюсь вопросом, виновата ли библиотека или определенно я?

Кстати, разоренгин, на который я ссылаюсь, доступен здесь в codeplex: RazorEngine

Ответы [ 3 ]

18 голосов
/ 09 марта 2011

Если вы делаете вызов так:

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

Это должно дать вам правильный вывод. Но после того, как я увижу ваш метод, опубликованный выше, я смогу определить причину проблемы.

Обновление

Измените свой метод на следующий:

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;
    }
}

и вы можете называть это, как вы делаете выше.

Причина, по которой это не работает, заключается в том, что вы говорите парсеру, что модель имеет тип объекта, а не указываете, какой это тип на самом деле. В этом случае анонимный тип.

6 голосов
/ 24 октября 2015

Принятый ответ был идеальным в 2011 году (я полагаю, до версии 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;
1 голос
/ 09 марта 2011

Вот несколько советов, которые вы можете попробовать:

  1. Сделайте свой бритвенный вид строго типизированным для модели:

    @model Foo
    <div>
        <div>
            Link: 
            <a href="@Model.ActivationLink" style="color:#666" target="_blank">
                @Model.ActivationLink
            </a>
        </div>
    </div>
    
  2. Когдарендеринг проходит Foo модель:

    _emailService.Render(
        TemplatePath, 
        "Email.cshtml", 
        new Foo { ActivationLink = activationLink }
    )
    
  3. Если вы пытаетесь отправлять электронные письма из ваших представлений, убедитесь, что вы извлекаете почту , прежде чем что-то изобретать.1018 *

...