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

TemplateCompilationError с RazorEngine и макетами

Я пытаюсь использовать RazorEngine в небольшом проекте, но не могу пройти мимо этой ошибки, когда я пытаюсь использовать шаблоны шаблонов.

Невозможно скомпилировать шаблон. "объект" не содержит определения для "Описание" и никакой метод расширения "Описание", принимающий первый аргумент типа "объект" можно найти (если вы не используете директива или ссылка на сборку?)

Моя настройка: У меня есть шаблон, подобный этому:

<html>
<head>
    <title>@Model.Description</title>
</head>
<body>
    @RenderBody()
</body>
</html>

И затем шаблон страницы, который выглядит следующим образом:

@{
    _Layout = "Layout.cshtml";
}
<h1>@Model.Description</h1>

Вот тестовая основная функция, которую я использую, чтобы попытаться понять это:

    static void Main(string[] args)
    {
        // Configuration for RazorEngine
        var config = new TemplateServiceConfiguration
        {
            EncodedStringFactory = new RawStringFactory(),

            Resolver = new DelegateTemplateResolver(name =>
            {
                var file = name;
                var content = File.ReadAllText("Templates/" + file);
                return content;
            })
        };

        // Try to render output using Razor
        using (var service = new TemplateService(config))
        {
            string template = File.ReadAllText("Templates/Default.cshtml");

            dynamic model = new ExpandoObject();
            model.Description = "This is a test";
            string result = service.Parse(template, model);
            Console.WriteLine(result);
            if (Debugger.IsAttached)
            {
                Console.ReadLine();
            }

        }
    }

Любая идея, что мне не хватает?

Обновление: оно работает, если я заменю объект динамической модели на POCO с свойством Description. Я также попробовал типизированную версию Parse с помощью

динамический

ExpandoObject и IDictionary<string, object>, но все они имеют одинаковую ошибку.

Update: Я нашел этот проект на Github, который, похоже, как-то работает: https://github.com/mikoskinen/graze/blob/master/src/core/Graze.cs#L174

4b9b3361

Ответ 1

Я считаю, что более целесообразно использовать перегрузку шаблона Parse, которая принимает ViewBag и использует ViewBag в вашем представлении, а не в модели.

Edit:

public virtual string Parse(string razorTemplate, object model, DynamicViewBag viewBag, string cacheName)

Ответ 2

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

Ответ 3

Создайте модель, как вы делаете выше

В вашем шаблоне индекса установите ViewBag.Description для Model.Description

@{
    _Layout = "Layout.cshtml";
    ViewBag.Description = Model.Description;
}

<div>Hello John </div>

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
    <head>
        <title>@ViewBag.Description</title>
    </head>
    <body>
        <div id="content">
            @RenderBody()
        </div> 
        @if (IsSectionDefined("Footer"))
        { 
            <div id="footer">
                @RenderSection("Footer")
            </div>
        }
    </body>
</html>

Я не знаю, почему динамическая модель не может использоваться на странице макета. Вот как я использую его в своем проекте