Antworten:
Ich verwende eine statische Methode in einer Klasse, die ich aufgerufen habe. Utilities.Common
Ich übergebe Ansichten als Eigenschaften von JSON-Objekten ständig an den Client zurück, sodass ich sie in eine Zeichenfolge rendern musste. Hier gehts:
public static string RenderPartialViewToString(Controller controller, string viewName, object model)
{
controller.ViewData.Model = model;
using (StringWriter sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.ToString();
}
}
Dies funktioniert sowohl für Vollansichten als auch für Teilansichten. Wechseln Sie einfach ViewEngines.Engines.FindPartialView
zu ViewEngines.Engines.FindView
.
this
als Controller-Argument. RenderPartialViewToString(this, "index", viewModel)
. Ich finde es albern, dass es keinen einfacheren Weg gibt, die View Engine einfach aufzurufen und eine Zeichenfolge zurückzugewinnen, aber in ASP.NET benötigt die View Engine einen Verweis auf die Controller-Instanz, um die View zu kompilieren. Ich bin jetzt ein NodeJS-Entwickler und View Engines in Node sind ganze separate Module, die Sie manuell oder mit einem MVC-Framework wie Express aufrufen können .
Die akzeptierte Antwort von @Chev oben ist gut, aber ich wollte das Ergebnis einer bestimmten Aktion wiedergeben , nicht nur einer bestimmten Ansicht .
Außerdem musste ich in der Lage sein, Parameter an diese Aktion zu übergeben, anstatt mich auf das Injizieren eines Modells zu verlassen.
Also habe ich mir eine eigene Methode ausgedacht, die ich in die Basisklasse meiner Controller eingefügt habe (um sie allen zur Verfügung zu stellen):
protected string RenderViewResultAsString(ViewResult viewResult)
{
using (var stringWriter = new StringWriter())
{
this.RenderViewResult(viewResult, stringWriter);
return stringWriter.ToString();
}
}
protected void RenderViewResult(ViewResult viewResult, TextWriter textWriter)
{
var viewEngineResult = this.ViewEngineCollection.FindView(
this.ControllerContext,
viewResult.ViewName,
viewResult.MasterName);
var view = viewEngineResult.View;
try
{
var viewContext = new ViewContext(
this.ControllerContext,
view,
this.ViewData,
this.TempData,
textWriter);
view.Render(viewContext, textWriter);
}
finally
{
viewEngineResult.ViewEngine.ReleaseView(this.ControllerContext, view);
}
}
Angenommen, ich habe eine Aktion namens Foo
, die ein Modellobjekt und einige andere Parameter verwendet, die zusammen beeinflussen, welche Ansicht verwendet wird:
public ViewResult Foo(MyModel model, int bar)
{
if (bar == 1)
return this.View("Bar1");
else
return this.View("Bar2", model);
}
Wenn ich nun das Ergebnis des Aufrufs von action erhalten möchte Foo
, kann ich das einfach ViewResult
durch Aufrufen der Foo
Methode abrufen und dann aufrufen RenderViewResultAsString
, um den HTML-Text abzurufen:
var viewResult = this.Foo(model, bar);
var html = this.RenderViewResultAsString(viewResult);
masterName
), den Sie null angeben würden. Außerdem empfehle ich, controller.ViewData.Model (nach dem Rendern) zu speichern und wiederherzustellen, falls die Methode für die aktuelle Controller-Instanz aufgerufen wird und das Modell vor diesem Aufruf zugewiesen wurde.