在Controller或其他地方将部分渲染为字符串

Ste*_*eve 6 asp.net-mvc partial-views

所以基本上我有一个局部视图,可以为我建立一个很好的表.我想每周通过电子邮件发送给我的用户.而不必再次基本上复制的模板,我想我的模型转发到控制器并接收相应产生HTMLString.

是否可以在Controller中执行此操作,我觉得它应该是一个非常简单的过程.

Nes*_*tor 18

把它放到Helper文件中:

public static string RenderViewToString(ControllerContext context, string viewName, object model)
        {
            if (string.IsNullOrEmpty(viewName))
                viewName = context.RouteData.GetRequiredString("action");

            ViewDataDictionary viewData = new ViewDataDictionary(model);

            using (StringWriter sw = new StringWriter())
            {
                ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                ViewContext viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                viewResult.View.Render(viewContext, sw);

                return sw.GetStringBuilder().ToString();
            }
        }
Run Code Online (Sandbox Code Playgroud)

然后从控制器你可以这样称呼它:

var order = orderService.GetOrder(id);

var orderPrint = MyHelper.RenderViewToString(this.ControllerContext, "_OrderView", order);
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您搜索将部分视图呈现为字符串,您也会遇到一些好的线索。这就是我为 ControllerBase 类提出以下扩展方法所做的工作:

public static string RenderPartialViewToString( this ControllerBase controller, string partialPath, ViewDataDictionary viewData = null )
{
    if( string.IsNullOrEmpty(partialPath) )
        partialPath = controller.ControllerContext.RouteData.GetRequiredString("action");

    using( StringWriter sw = new StringWriter() )
    {
        ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialPath);

        ViewContext viewContext = new ViewContext(controller.ControllerContext,
            viewResult.View,
            ( viewData == null ) ? controller.ViewData : viewData,
            controller.TempData,
            sw);

        // copy retVal state items to the html helper 
        foreach( var item in viewContext.Controller.ViewData.ModelState )
        {
            if( !viewContext.ViewData.ModelState.Keys.Contains(item.Key) )
                viewContext.ViewData.ModelState.Add(item);
        }

        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

从概念上讲,要遵循的过程涉及使用为您的应用程序定义的 ViewEngines 来按名称查找局部视图。然后从该部分创建一个 ViewContext,并将各种模型状态属性复制到它上面。

该代码分配了一个可选的 ViewDataDictionary,您可以将其提供给 ViewContext。如果您不提供 ViewDataDictionary,它会获取为它被调用的控制器定义的 ViewDataDictionary。

这意味着您可以直接在控制器中定义 ViewData 值(或 ViewBag 属性),然后调用扩展方法——该方法将在渲染部分时将这些 ViewData/ViewBag 属性应用到部分——或者您可以创建一个在您的操作方法中分离 ViewDataDictionary 对象并将其传递给扩展方法。第一个更快/更容易,但它“污染”了您的操作方法的 ViewData,而第二个需要更长的时间来设置,但可以让您将部分视图数据与您的操作方法的 ViewData 分开。


tva*_*son 0

查看MvcMailer项目。再加上呈现表格的部分视图,您应该能够轻松地将电子邮件与表格放在一起。