RenderPartial () in T4 template

I am wondering if it is possible to take the existing partial view logic and reuse it to dynamically generate email in the preprocessor template?

When viewing Intellisense T4ToolKit options for

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

Mvc namespace is not displayed, is it possible to enable the namespace and call

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

from the preprocessor template?

i.e.

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

so I can programmatically access my template, reuse the display logic and build, say, an email on the fly (I know that email is absurd, just a short hand for simplicity)

 var template = MyTemplate(){ Model = MyViewModel }; Email.Send(emailAddress, title, template.TransformText(), null) etc.. 

TIA

+4
source share
1 answer

This can be done for sure, but you need to use different extension methods than RenderPartial , because they are directly written to the response. I tried Partial extension methods that return an MvcHtmlString , which works fine in the template. This is my T4 test run-time pattern, RuntimeTextTemplate1.tt:

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

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

I created an incomplete class to add an Html property to the template and instantiate the HtmlHelper and provide the constructor:

 public partial class RuntimeTextTemplate1 { public HtmlHelper Html { get; private set; } public RuntimeTextTemplate1(ViewContext viewContext, IViewDataContainer viewDataContainer) { Html = new HtmlHelper(viewContext, viewDataContainer); } } 

A HtmlHelper is required to create a ViewContext and IViewDataContainer , and those that in turn have other dependencies. I presented 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 a way out of it.

Thus, although this can be done, it depends on the specific situation, how exactly you need to use it, how your view is parameterized, and how you can put the necessary classes together to get to the HtmlHelper instance.

In the end, you may find that creating a template is the main source of the required output, and using it in your views and out of them is easier than vice versa.

0
source

Source: https://habr.com/ru/post/1447914/


All Articles