RazorEngine 3.4 抛出 System.ArgumentException:带有缓存的 @Layout 和不同的模型

Maj*_*jor 4 c# unit-testing razorengine

我有 RazorEngine 3.4 缓存问题。我有几个电子邮件模板,每个模板都相同@Layout但不同Models。它工作正常,直到我尝试使用我读过的不使用 cache: "will result in both dreadful performances and memory leaks" from here的 Cache 。

所以我打开了它。这很简单,但导致了一个问题:_Layout.cshtml它也与第一个模型类型一起缓存,当我尝试使用不同的模型解析另一个模板时,它会抛出异常:"System.ArgumentException: Object of type '....model1...' cannot be converted to type '...model2...'."

我写了 2 个单元测试"IsolatedTemplateServiceTestFixture.cs"来显示问题。第一个通过,但第二个失败,因为该TemplateService.SetModelExplicit()函数想要ModelLayout.

private Mock<ITemplateResolver> _templateResolver;

    [Test]
    public void IsolatedTemplateService_CanParseTemplateWithLayout_WithOneSerializableModels_UseCache()
    {
        _templateResolver = new Mock<ITemplateResolver>();
        var config = new TemplateServiceConfiguration()
        {
            Resolver = _templateResolver.Object
        };

        using (var service = new TemplateService(config))
        {
            _templateResolver.Setup(i => i.Resolve("test")).Returns("<html>@RenderBody()</html>");

            const string template = @"@{Layout=""test"";}<h1>Hello @Model.Item1</h1>";
            const string expected = "<html><h1>Hello World</h1></html>";

            var model = new Tuple<string>("World");
            string result = service.Parse(template, model, null, "C1");
            string result2 = service.Parse(template, model, null, "C1");

            Assert.That(result == expected, "Result does not match expected: " + result);
            Assert.That(result2 == expected, "Result does not match expected: " + result2);
        }
    }

    [Test]
    public void IsolatedTemplateService_CanParseTemplateWithLayout_WithDifferentSerializableModels_UseCache()
    {
        _templateResolver = new Mock<ITemplateResolver>();
        var config = new TemplateServiceConfiguration()
        {
            Resolver = _templateResolver.Object
        };

        using (var service = new TemplateService(config))
        {
            _templateResolver.Setup(i => i.Resolve("test")).Returns("<html>@RenderBody()</html>");

            const string template = @"@{Layout=""test"";}<h1>Hello @Model.Item1</h1>";
            const string expected = "<html><h1>Hello World</h1></html>";

            var model = new Tuple<string>("World");
            string result = service.Parse(template, model, null, "C1");
            string result2 = service.Parse(template, model, null, "C1");

            const string template2 = @"@{Layout=""test"";}<h1>Hello2 @Model.Item1</h1>";
            const string expected2 = "<html><h1>Hello2 123</h1></html>";
            var model2 = new Tuple<int>(123);

            string result3 = service.Parse(template2, model2, null, "C2");

            Assert.That(result == expected, "Result does not match expected: " + result);
            Assert.That(result2 == expected, "Result does not match expected: " + result2);

            Assert.That(result3 == expected2, "Result does not match expected: " + result3);
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是:有人有同样的问题吗?在它被修复之前,有什么“好”的方法来解决它(如果它发生了)?

更新:

使用最新版本(当前是 v.3.10),两个测试都通过了。于是问题就解决了。

bst*_*zel 5

正如在 RazorEngine 中一样,布局具有固定类型,即使您没有在其中声明模型。第一次通过编译模板来编译布局时,模板的模型类型也成为布局的类型。正如您所注意到的,当您尝试编译具有不同类型的另一个模板时,这会发生冲突。

您可以通过声明动态布局的模型类型来解决这个问题,即 @model dynamic

这应该够了吧。不需要更改实际模板。