Qualcuno sa come ottenere l'html generato di una vista all'interno di un'azione?
È qualcosa del genere:
public ActionResult Do()
{
var html = RenderView("hello", model);
...
}
Risposte:
Uso un metodo statico in una classe che ho chiamato Utilities.Common
. Passo le visualizzazioni al client come proprietà degli oggetti JSON costantemente, quindi avevo bisogno di renderle in una stringa. Ecco qua:
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();
}
}
Funzionerà sia per le visualizzazioni complete che per quelle parziali, basta passare ViewEngines.Engines.FindPartialView
a ViewEngines.Engines.FindView
.
this
come argomento del controller. RenderPartialViewToString(this, "index", viewModel)
. Penso che sia sciocco che non ci sia un modo più semplice per invocare semplicemente il motore di visualizzazione e ottenere una stringa, ma in ASP.NET il motore di visualizzazione deve fare riferimento all'istanza del controller per compilare la visualizzazione. Sono uno sviluppatore nodeJS ora e i motori di visualizzazione in node sono interi moduli separati che puoi richiamare manualmente o con un framework MVC come express .
La risposta accettata da @Chev sopra è buona, ma volevo rendere il risultato di un'azione specifica , non solo una vista particolare .
Inoltre, dovevo essere in grado di passare parametri a quell'azione piuttosto che fare affidamento sull'iniezione di un modello.
Quindi ho escogitato il mio metodo, che ho inserito nella classe base dei miei controller (rendendolo disponibile a tutti):
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);
}
}
Supponiamo di avere un'azione chiamata Foo
che accetta un oggetto del modello e alcuni altri parametri, che insieme influenzano la vista che verrà utilizzata:
public ViewResult Foo(MyModel model, int bar)
{
if (bar == 1)
return this.View("Bar1");
else
return this.View("Bar2", model);
}
Ora, se voglio ottenere il risultato della chiamata all'azione Foo
, posso semplicemente ottenere ViewResult
invocando il Foo
metodo e quindi chiamare RenderViewResultAsString
per ottenere il testo HTML:
var viewResult = this.Foo(model, bar);
var html = this.RenderViewResultAsString(viewResult);
masterName
) da specificare null. Inoltre, consiglio di salvare e ripristinare (dopo il rendering) controller.ViewData.Model nel caso in cui il metodo venga chiamato sull'istanza del controller corrente e il modello sia stato assegnato prima di questa chiamata.