Подтвердить что ты не робот

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

4b9b3361

Ответ 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 перед тем как изобретать что-то.