【问题标题】:TemplateCompilationError with RazorEngine and LayoutsRazorEngine 和布局的 TemplateCompilationError
【发布时间】:2012-10-30 22:56:29
【问题描述】:

我一直在尝试在我的一个小项目中使用 RazorEngine,但是当我尝试使用模板布局时无法克服这个错误。

无法编译模板。 “对象”不包含定义 'Description' 并且没有扩展方法 'Description' 接受第一个 可以找到“对象”类型的参数(您是否缺少使用 指令还是程序集引用?)

我的设置: 我有这样的模板布局:

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

然后是这样的页面模板:

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

这是我用来尝试解决这个问题的测试 Main 函数:

    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 替换动态模型对象,它会起作用。我还用

尝试了 Parse 的类型化版本

动态

ExpandoObjectIDictionary&lt;string, object&gt; 但它们都有相同的错误。

更新: 我在 Github 上发现了这个项目,它似乎以某种方式使它工作: https://github.com/mikoskinen/graze/blob/master/src/core/Graze.cs#L174

【问题讨论】:

  • 是否可以使用常规 POCO 作为模型?
  • 是的,但我需要它是动态的。

标签: c# razor razorengine


【解决方案1】:

我认为使用模板服务的Parse 重载(采用ViewBag)并在您的视图中使用ViewBag 而不是模型更合适。

编辑:

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

【讨论】:

  • 该应用程序不是 MVC 应用程序,因此我没有 ViewBag 对象。
  • 当前版本的 RazorEngine (github.com/Antaris/RazorEngine) 有一个接受 ViewBag 的 Parse 方法。这就是我的建议(见编辑)。
  • 抱歉,我以为您指的是 ControllerBase 上的 ViewBag 属性。我还没有尝试过 DynamicViewBay。这种方法让我感到困惑,因为我可以传入“模型”,为什么要使用 viewBag?
  • 您可以将模型(强类型类)、视图袋(动态对象)或两者都用于您的模板。选择是你如何使用它们,但看到你的选择是将动态数据而不是强类型数据传递给模板,viewbag 似乎更合适。
  • 感谢您的解决方法建议,但这并不能真正帮助我理解我想做的事情有什么问题。
【解决方案2】:

您不能将匿名类型传递给动态类型视图,因为匿名类型被编译为内部类型。由于 CSHTML 视图被编译为单独的程序集,因此它无法访问匿名类型的属性。

【讨论】:

  • 看起来只有基本布局有问题。如果我只有单一布局并且没有 _Layout = "Layout.cshtml";
【解决方案3】:

像上面那样创建模型

在您的索引模板中,将 ViewBag.Description 设置为 Model.Description

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

<div>Hello John </div>

在布局页面中使用viewbag代替模型

<!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>

不知道为什么布局页面不能使用动态模型。这就是我在项目中使用它的方式

【讨论】:

  • 感谢另一个解决方法。我仍然想知道我最初的方法有什么问题。
  • 我不知道为什么布局页面不接受动态模型。希望有深入了解razor引擎架构的人来回答。
猜你喜欢
  • 2012-07-09
  • 2012-05-12
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多