4

我想知道是否可以在预处理器模板中采用现有的局部视图逻辑并将其重用于动态电子邮件生成?

在查看 T4ToolKit 的智能感知选项时

<#@ import namespace="System.Web.Mvc" #>

mvc的命名空间没有出现,是否可以包含命名空间并调用

Html.RenderPartial("viewName", this.Model)

从预处理器模板中?

IE

<#@ template language="C#" #>
This is a header
<#= Html.RenderPartial("<%PATH%>/MyPartialRazerView", this.Model) #>
This is a Footer
<#+
  public MyType Model { get; set; }
#>

所以我可以以编程方式访问我的模板,重用视图的显示逻辑并构建,即时说电子邮件(我知道电子邮件行是胡说八道,为了简单起见只是简写)

var template = MyTemplate(){ Model = MyViewModel };

Email.Send(emailAddress, title, template.TransformText(), null) etc..

TIA

4

1 回答 1

0

This can be done for sure, but you need to use a different extension methods than RenderPartial, because these write directly to the response. I tried Partial extension methods, which return the MvcHtmlString which works fine in the template. This is my test T4 runtime template, RuntimeTextTemplate1.tt:

<#@ template language="C#" #>
<#@ import namespace="System.Web.Mvc.Html" #>
LogOnPartial:
<#= Html.Partial("_LogOnPartial") #>

Then you also need to jump some ASP.NET MVC hoops to get the actual HtmlHelper instance into your template.

I created a partial class, to add the Html property to the template and instantiate the HtmlHelper and to provide a constructor:

public partial class RuntimeTextTemplate1
{
    public HtmlHelper Html
    {
        get;
        private set;
    }

    public RuntimeTextTemplate1(ViewContext viewContext, IViewDataContainer viewDataContainer)
    {
        Html = new HtmlHelper(viewContext, viewDataContainer);
    }
}

A HtmlHelper needs a ViewContext and IViewDataContainer to be created and those in turn have another dependencies. I provided what is needed from the controller using some dummy classes:

public class HomeController : Controller
{
    public ActionResult TemplateTest()
    {
        var viewContext = new ViewContext(ControllerContext, new DummyView(), ViewData, TempData, TextWriter.Null);
        var template = new RuntimeTextTemplate1(viewContext, new ControllerViewDataContainer(this));
        return Content(template.TransformText());
    }
}

public class DummyView : IView
{
    public void Render(ViewContext viewContext, TextWriter writer)
    {
        // Do nothing
    }
}

public class ControllerViewDataContainer : IViewDataContainer
{
    private Controller controller;

    public ViewDataDictionary ViewData
    {
        get { return controller.ViewData; }
        set { }
    }

    public ControllerViewDataContainer(Controller controller)
    {
        this.controller = controller;
    }
}

And I successfully get the template output out of it.

So while this can be done, it depends on your specific situation, how exactly you need to use it, how your view is parametrized, and how you can assemble the required classes together to get to the HtmlHelper instance.

In the end, you may find that making the template the primary source of the required output, and using this in your views and outside them is easier than the other way around.

于 2013-04-04T14:33:23.453 回答