RazorEngine 3.4抛出系统.ArgumentException:与缓存@Layout和不同的模型

本文关键字:@Layout 缓存 模型 ArgumentException 系统 RazorEngine | 更新日期: 2023-09-27 18:16:24

我有一个问题与RazorEngine 3.4缓存。我有几个电子邮件模板与相同的@Layout,但不同的Models为每个模板。它工作得很好,直到我尝试使用缓存,我读不使用缓存:"will result in both dreadful performances and memory leaks"从这里。

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

我在"IsolatedTemplateServiceTestFixture.cs"中编写了2个单元测试来显示问题。第一个通过了,但是第二个失败了,因为TemplateService.SetModelExplicit()函数想要设置模板。为Layout使用不同的Model类型的模型属性。

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);
        }
    }
我的问题是:有人有同样的问题吗?什么是一个"好"的方法来解决它,直到它将被修复(如果它发生)?

更新:

对于最新版本(目前是v.3.10),这两个测试都通过了。

RazorEngine 3.4抛出系统.ArgumentException:与缓存@Layout和不同的模型

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

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

应该可以了。实际的模板不需要修改