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.FindPartialViewa ViewEngines.Engines.FindView.
thiscome 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 Fooche 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 ViewResultinvocando il Foometodo e quindi chiamare RenderViewResultAsStringper 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.