Czy ktoś wie, jak uzyskać wygenerowany kod HTML widoku w akcji?
Czy to jest coś takiego:
public ActionResult Do()
{
var html = RenderView("hello", model);
...
}
Czy ktoś wie, jak uzyskać wygenerowany kod HTML widoku w akcji?
Czy to jest coś takiego:
public ActionResult Do()
{
var html = RenderView("hello", model);
...
}
Używam metody statycznej w klasie, którą wywołałem. Utilities.Common
Przekazuję widoki z powrotem do klienta jako właściwości obiektów JSON w sposób ciągły, więc musiałem renderować je w postaci ciągu. Proszę bardzo:
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();
}
}
Będzie to działać zarówno w przypadku widoków pełnych, jak i częściowych, wystarczy zmienić ViewEngines.Engines.FindPartialView
na ViewEngines.Engines.FindView
.
masterName
), który należy określić jako null. Polecam również zapisanie i przywrócenie (po wyrenderowaniu) kontrolera.ViewData.Model w przypadku wywołania metody na bieżącej instancji kontrolera, a model został przypisany przed tym wywołaniem.this
jako argument kontrolera.RenderPartialViewToString(this, "index", viewModel)
. Myślę, że to głupie, że nie ma prostszego sposobu, aby po prostu wywołać silnik widoku i odzyskać ciąg, ale w ASP.NET silnik widoku potrzebuje odniesienia do instancji kontrolera, aby skompilować widok. Jestem teraz programistą nodeJS i przeglądanie silników w węźle to całe oddzielne moduły, które można wywołać ręcznie lub za pomocą struktury MVC, takiej jak express .Przyjęta odpowiedź przez @Chev powyżej jest dobra, ale chciałem wyrenderować wynik określonego działania , a nie tylko określonego widoku .
Musiałem też móc przekazywać parametry do tej akcji, zamiast polegać na wstrzykiwaniu modelu.
Wymyśliłem więc własną metodę, którą umieściłem w klasie bazowej moich kontrolerów (udostępniając ją wszystkim):
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); } }
Załóżmy, że mam akcję o nazwie,
Foo
która pobiera obiekt modelu i kilka innych parametrów, które razem wpływają na to, jaki widok zostanie użyty:public ViewResult Foo(MyModel model, int bar) { if (bar == 1) return this.View("Bar1"); else return this.View("Bar2", model); }
Teraz, jeśli chcę uzyskać wynik wywołania akcji
Foo
, mogę po prostu uzyskaćViewResult
, wywołującFoo
metodę, a następnie wywołać,RenderViewResultAsString
aby uzyskać tekst HTML:var viewResult = this.Foo(model, bar); var html = this.RenderViewResultAsString(viewResult);
źródło