【问题标题】:RazorEngine 3.4 throws System.ArgumentException: with cached @Layout and different ModelsRazorEngine 3.4 抛出 System.ArgumentException:缓存 @Layout 和不同的模型
【发布时间】:2014-08-05 15:35:26
【问题描述】:

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

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

我在"IsolatedTemplateServiceTestFixture.cs" 中写了 2 个单元测试来显示问题。第一个通过,但第二个失败,因为 TemplateService.SetModelExplicit() 函数想要为 Layout 设置具有不同 Model 类型的 template.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),两个测试都通过了。这样问题就解决了。

【问题讨论】:

  • 寻求调试帮助的问题(“为什么这段代码不起作用?”)必须在问题本身中包含所需的行为、特定问题或错误以及重现它所需的最短代码 。一个链接很好,但只是希望每个人都回答问题以链接到另一个网站,这意味着当该链接消失时,这个问题将毫无用处。
  • 可能不值得尝试与之抗争。只需制作一堆视图,每个模型一个。
  • 但是为 15 个模板使用具有大量属性的“大”模型并不酷。另一位开发人员不知道必须为特定模板设置哪个。我报告了这个问题,但还没有答案。也许我会创建一个拉取请求并自己修复它......
  • 请注意,现在在最新的 RazorEngine 版本中“正常工作”。

标签: c# unit-testing razorengine


【解决方案1】:

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

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

这应该可以解决问题。实际模板无需更改。

【讨论】:

  • 嗨,谢谢它的工作原理。但我读到它在高负载时有一些问题github.com/Antaris/RazorEngine/issues/180 可能是 ViewBag 是更好的解决方案......
  • ViewBag 对我来说似乎是一个非常糟糕的解决方案,因为您没有视图中强类型模型的好处。我实际上看到了您链接的那个问题并忽略了它,但是现在您再次提到它,我们可能在我们的项目中遇到了同样的问题。我们的应用程序每天最多只发送几百封电子邮件,但它确实会在几周内耗尽内存。我怀疑有一些 COM 调用,但无法通过负载测试确定它。也许我找错地方了。我可能应该运行不同的负载测试。
猜你喜欢
  • 2016-06-01
  • 2022-01-06
  • 2012-10-16
  • 2019-01-29
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-20
相关资源
最近更新 更多