[英]ASP.NET MVC Razor: How to render a Razor Partial View's HTML inside the controller action
如何在ASP.NET視圖引擎上生成給定局部視圖的HTML 是已知的 。
但是如果在razor局部視圖上使用此功能則它不起作用,因為異常說部分視圖不是從“UserControl”派生的。
如何修復渲染以支持剃刀局部視圖?
我需要這個,因為我從這個部分視圖生成電子郵件...
更新:
失敗的代碼(@mcl):
public string RenderPartialToString(string controlName, object viewData)
{
ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
viewPage.Url = this.GetUrlHelper();
string fullControlName = "~/Views/Email/" + controlName + ".ascx";
viewPage.ViewData = new ViewDataDictionary(viewData);
viewPage.Controls.Add(viewPage.LoadControl(fullControlName));
StringBuilder sb = new StringBuilder();
using (StringWriter sw = new StringWriter(sb))
{
using (HtmlTextWriter tw = new HtmlTextWriter(sw))
{
viewPage.RenderControl(tw);
}
}
return sb.ToString();
}
@Html.Partial("nameOfPartial", Model)
更新
protected string RenderPartialViewToString(string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = ControllerContext.RouteData.GetRequiredString("action");
ViewData.Model = model;
using (StringWriter sw = new StringWriter()) {
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
雖然已經給出了足夠的答案,但我想提出一個不那么詳細的解決方案,可以在沒有MVC控制器類中可用的輔助方法的情況下使用。 使用名為“RazorEngine”的第三方庫,您可以使用.Net文件IO來獲取剃刀文件的內容並調用
string html = Razor.Parse(razorViewContentString, modelObject);
在這里獲取第三方庫。
我看到有人想知道如何為另一個控制器做這件事。
在我的情況下,我將所有的電子郵件模板都放在了Views / Email文件夾中,但您可以對其進行修改以傳入您有關聯視圖的控制器。
public static string RenderViewToString(Controller controller, string viewName, object model)
{
var oldController = controller.RouteData.Values["controller"].ToString();
if (controller.GetType() != typeof(EmailController))
controller.RouteData.Values["controller"] = "Email";
var oldModel = controller.ViewData.Model;
controller.ViewData.Model = model;
try
{
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindView(controller.ControllerContext, viewName,
null);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
//Cleanup
controller.ViewData.Model = oldModel;
controller.RouteData.Values["controller"] = oldController;
return sw.GetStringBuilder().ToString();
}
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
throw ex;
}
}
基本上這是做一個控制器,如AccountController並修改它認為它是一個EmailController,以便代碼將在Views/Email
文件夾中查找。 這是必要的,因為FindView
方法不會將直線路徑作為參數,它需要一個ControllerContext
。
完成呈現字符串后,它會將AccountController返回到其初始狀態,以供Response對象使用。
偉大的代碼; 小提示:如果你有時不得不繞過更多的數據,而不僅僅是視圖模型..
if (model is ViewDataDictionary)
{
controller.ViewData = model as ViewDataDictionary;
} else {
controller.ViewData.Model = model;
}
借用@jgauffin作為HtmlHelper擴展的答案:
public static class HtmlHelperExtensions
{
public static MvcHtmlString RenderPartialViewToString(
this HtmlHelper html,
ControllerContext controllerContext,
ViewDataDictionary viewData,
TempDataDictionary tempData,
string viewName,
object model)
{
viewData.Model = model;
string result = String.Empty;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controllerContext, viewName);
ViewContext viewContext = new ViewContext(controllerContext, viewResult.View, viewData, tempData, sw);
viewResult.View.Render(viewContext, sw);
result = sw.GetStringBuilder().ToString();
}
return MvcHtmlString.Create(result);
}
}
剃須刀視圖中的用法:
Html.RenderPartialViewToString(ViewContext, ViewData, TempData, "Search", Model)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.