2

我有一个RazorEngine项目在升级到 Razor 2.0 和 RazorEngine 3.2.0 后失败

这在以前基于 Razor 1.0 的 RazorEngine (3.0.8) 版本中运行良好。

我有myInstance一个类 ( ) 的实例 ( )MyClass和扩展方法:

namespace MyCompany.Extensions 
{
    public static class MyClassExtensions
    {
        public static string ExtensionMethod(this MyClass thing) 
        {
            // do stuff
        }
    }
}

我想在 RazorEngine 视图中调用它(简化示例,有很多这些方法,并且都以相同的方式失败):

@using MyCompany.Extensions
@using MyCompany
@{
    var myInstance = new MyClass(Model, ...);
}

Some text @myInstance.ExtensionMethod() some more text

这是在 RazorEngine 编译的文本文件中:

string parsedResult = RE::Razor.Parse(fileContent, myModel, "testfile.txt");

问题是这条线(以前可以工作)抛出一个RuntimeBinderException

“MyCompany.MyClass”不包含“ExtensionMethod”的定义

请注意,如果我将文本文件更改为:

Some text @MyClassExtensions.ExtensionMethod(myInstance) some more text

它工作正常,所以我认为它必须找到扩展方法的命名空间。

我的第一个想法是它必须将传递的模型视为 a dynamic(因此也将任何从它派生的模型视为dynamic),但它知道RuntimeBinderException. 由于异常是运行时的,我认为在编译模板时它一定无法识别扩展方法,但为什么会改变呢?

我不确定 3.0.8 和 3.2.0 之间发生了什么变化,或者为什么会出现这种情况。是否需要添加一些内容以便在编译模板时可以找到扩展方法?

4

1 回答 1

5

这是RazorEngine 中的一个错误Razor.Compile工作TemplateBase<dynamic>(因此Model以及从它派生的所有内容也是dynamic如此),这意味着没有扩展方法经过“编译器魔术”将它们转换为静态调用。然后Razor.Run将 .Model作为正确的类型传递,但扩展方法语法被称为实例方法。

可能很快就会解决这个问题(这个错误只有几天前,这是一个极端情况),但与此同时我有一个解决方法:在 Razor 模板中显式键入Model

@using MyCompany.Extensions
@using MyCompany
@{
    ExpectedModelClass strongTypeModel = Model as ExpectedModelClass;
    MyClass myInstance = new MyClass(strongTypeModel , ...);
}

Some text @myInstance.ExtensionMethod() some more text

这现在有效,因为即使Modeldynamic处于编译时,也不会再传播myInstance

这并不理想,我Model现在使用的任何地方都必须是strongTypeModel,但这是一个更简单的替换。

于 2013-01-31T16:36:47.743 回答