ASP.NET MVC Razor: как отобразить HTML частичного представления Razor внутри действия контроллера
Как создать HTML данного частичного представления на ASP.NET вид двигателя известен.
но если эта функция используется в частичном представлении razor, она не работает, так как исключение говорит, что частичное представление не является производным от "UserControl".
Как исправить рендеринг для поддержки частичного просмотра razor?
мне это нужно, потому что я генерирую электронные письма из этого частичного представления ...
обновление:
код, который не удается (@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();
}
6 ответов:
@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 file IO для получения содержимого файла razor и вызова
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 обратно в исходное состояние, которое будет использоваться объектом ответа.
отличный код; маленькая подсказка: если вам иногда приходится обходить больше данных, а не только viewmodel ..
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)
Comments