RazorEngine - 如何使用复杂的模型视图?

时间:2015-11-14 12:47:39

标签: razorengine

任何人都有使用复杂模型和RazorEngine的经验吗?

使用RazorEngine版本3.7.3生成HTML,但遇到了我们所拥有的复杂模型视图的问题。看起来我们应该能够使用模板让RazorEngine发现下面的SubSample,但是没有找到告诉RazorEngine关于相关cshtml文件的正确方法。

在下面的示例中,我们希望使用SubSample.cshtml文件为SubSample类使用共享模板。从结果中可以看出,显示了类名称空间(ReportSample.SubSample)而不是HTML行数据。

我们尝试过实现ITemplateManager,但是从不使用要求SubSample的密钥调用Resolve()。还在服务上尝试了AddTemplate(),但仍然没有快乐。

以下是一个简化的示例模型来说明问题:

namespace ReportSample
{
    public class SubSample
    {
        public string Name { get; set; }
        public string Value { get; set; }
    }

    public class SampleModel
    {
        public SubSample SubSample { get; set; }
    }
}

SampleModel.cshtml

@using ReportSample
@*@model ReportSample.SampleModel*@
<table style="width: 7.5in" align="center">
    <tr>
        <td align="center">
            <h1>
                Sample Report
            </h1>
        </td>
    </tr>
    <tr>
        <td>
            <table style="width: 100%">
                <tr>
                    <td colspan="2">
                        <b>Name:</b> @Model.SubSample.Name
                    </td>
                    <td colspan="2">
                        <b>Value:</b> @Model.SubSample.Value
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="center">
            <h1>
                Sub-sample Data
            </h1>
        </td>
        <td>
            <table style="width: 100%">
                @Model.SubSample
            </table>
        </td>
    </tr>
</table>

SubSample.cshtml

@model ReportSample.SubSample
@using FSWebportal.Infrastructure.Mvc;
<tr class="observation-row">
    <td class="observation-label">
        @model.Name
    </td>
    <td class="observation-view">
        @model.Value
    </td>
</tr>

基本的RazorEngine调用:

private void html_Click(object sender, EventArgs e)
{
    var gen = new RazorEngineGenerator();
    var cshtmlTemplate = File.ReadAllText("Sample.cshtml");

    var sample = new SampleModel() { SubSample = new SubSample() { Name = "name", Value = "value" } };

    var html = gen.GenerateHtml(sample, cshtmlTemplate);
}

public string GenerateHtml<T>(T model, string cshtmlTemplate)
{
    var config = new TemplateServiceConfiguration();
    using (var service = RazorEngineService.Create(config))
    {
        return service.RunCompile(cshtmlTemplate, "", typeof(T), model);
    }
}

示例HTML输出:                                            

                    样本报告                 

                                                                                                                                       姓名:姓名                                                                               价值:价值                                                                                                                            

                    子样本数据                 

                                                               ReportSample.SubSample                                            

1 个答案:

答案 0 :(得分:0)

我很抱歉,但我不认为我完全理解你的问题,但我对你想要做的事情有一个小小的想法......

我认为您想要搜索的是部分模板(使用@Include)!

using RazorEngine;
using RazorEngine.Templating;
using System;

namespace TestRunnerHelper
{
    public class SubModel
    {
        public string SubModelProperty { get; set; }
    }

    public class MyModel
    {
        public string ModelProperty { get; set; }
        public SubModel SubModel { get; set; }
    }

    class Program
    {

        static void Main(string[] args)
        {
            var service = Engine.Razor;
            // In this example I'm using the default configuration, but you should choose a different template manager: http://antaris.github.io/RazorEngine/TemplateManager.html
            service.AddTemplate("part", @"my template");
            // If you leave the second and third parameters out the current model will be used.
            // If you leave the third we assume the template can be used for multiple types and use "dynamic".
            // If the second parameter is null (which is default) the third parameter is ignored.
            // To workaround in the case you want to specify type "dynamic" without specifying a model use Include("p", new object(), null)
            service.AddTemplate("template", @"<h1>@Include(""part"", @Model.SubModel, typeof(TestRunnerHelper.SubModel))</h1>");
            service.Compile("template", typeof(MyModel));
            service.Compile("part", typeof(SubModel));
            var result = service.Run("template", typeof(MyModel), new MyModel { ModelProperty = "model", SubModel = new SubModel { SubModelProperty = "submodel"} });
            Console.WriteLine("Result is: {0}", result);
        }
    }
}

我在此处添加了相关文档:https://antaris.github.io/RazorEngine/LayoutAndPartial.html

但是我认为也可以使@Model.SubSample正常工作,您可以将SubSample属性更改为TemplateWriter类型,也可以使SubSample类实现IEncodedString。但我认为你应该首先考虑部分模板!