Wie man einen HTML-Code einer bestimmten Teilansicht auf der ASP.NET-Ansichts-Engine generiert ist bekannt .
Wenn diese Funktion jedoch für die Rasierer-Teilansicht verwendet wird, funktioniert sie nicht, da die Teilansicht ausnahmsweise nicht von "UserControl" stammt.
Wie kann ich das Rendering so korrigieren, dass es die Teilansicht von Rasierern unterstützt?
Ich brauche das, weil ich E-Mails aus diesen Teilansichten generiere ...
UPDATE:
Code, der fehlschlägt (@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)
Update
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();
}
}
Obwohl bereits ausreichende Antworten gegeben wurden, möchte ich eine weniger ausführliche Lösung vorschlagen, die ohne die in einer MVC-Controller-Klasse verfügbaren Hilfsmethoden verwendet werden kann. Mit einer Fremdanbieter-Bibliothek namens "RazorEngine" können Sie die .Net-Datei IO verwenden, um den Inhalt der Rasiererdatei abzurufen und abzurufen
string html = Razor.Parse(razorViewContentString, modelObject);
Besorgen Sie sich die Drittanbieter-Bibliothek hier .
Ich habe gesehen, dass sich jemand gefragt hat, wie man es für einen anderen Controller macht.
In meinem Fall hatte ich alle meine E-Mail-Vorlagen im Ordner Ansichten/E-Mail, aber Sie können dies ändern, um den Controller zu übergeben, in dem Sie Ansichten haben.
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;
}
}
Im Wesentlichen müssen Sie dazu einen Controller wie AccountController verwenden und ihn so anpassen, dass er ein EmailController ist, damit der Code im Ordner Views/Email
angezeigt wird. Dies ist notwendig, da die FindView
-Methode keinen direkten Pfad als Parameter hat, sondern eine ControllerContext
.
Nach dem Rendern der Zeichenfolge wird der AccountController wieder in den Ausgangszustand versetzt, der vom Response-Objekt verwendet werden soll.
großer Code; kleiner tipp: wenn man manchmal mehr daten umgehen muss und nicht nur das viewmodel ..
if (model is ViewDataDictionary)
{
controller.ViewData = model as ViewDataDictionary;
} else {
controller.ViewData.Model = model;
}
Ausleihe von @jgauffin als HtmlHelper-Erweiterung:
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);
}
}
Verwendung in einer Rasiermesseransicht:
Html.RenderPartialViewToString(ViewContext, ViewData, TempData, "Search", Model)