Alguém sabe como obter o html gerado de uma visão dentro de uma ação?
É algo assim:
public ActionResult Do()
{
var html = RenderView("hello", model);
...
}
Respostas:
Eu uso um método estático em uma classe que chamei. Utilities.Common
Eu passo as visualizações de volta para o cliente como propriedades de objetos JSON constantemente, então eu tive a necessidade de renderizá-los em uma string. Aqui está:
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();
}
}
Isso funcionará tanto para visualizações completas quanto parciais, basta alterar ViewEngines.Engines.FindPartialView
para ViewEngines.Engines.FindView
.
this
como o argumento do controlador. RenderPartialViewToString(this, "index", viewModel)
. Eu acho que é bobo que não haja uma maneira mais fácil de simplesmente invocar o mecanismo de exibição e obter uma string, mas no ASP.NET o mecanismo de exibição precisa fazer referência à instância do controlador para compilar o modo de exibição. Agora sou um desenvolvedor nodeJS e os motores de visualização no node são módulos separados inteiros que você pode invocar manualmente ou com uma estrutura MVC como express .
A resposta aceita por @Chev acima é boa, mas eu queria renderizar o resultado de uma ação específica , não apenas de uma determinada visualização .
Além disso, eu precisava ser capaz de passar parâmetros para essa ação em vez de confiar na injeção de um modelo.
Então eu vim com meu próprio método, que coloquei na classe base dos meus controladores (tornando-o disponível para todos eles):
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);
}
}
Suponha que eu tenha uma ação chamada Foo
que leva um objeto de modelo e alguns outros parâmetros, que juntos influenciam qual visualização será usada:
public ViewResult Foo(MyModel model, int bar)
{
if (bar == 1)
return this.View("Bar1");
else
return this.View("Bar2", model);
}
Agora, se eu quiser obter o resultado da ação de chamada Foo
, posso simplesmente obter o ViewResult
invocando o Foo
método e, em seguida, chamar RenderViewResultAsString
para obter o texto HTML:
var viewResult = this.Foo(model, bar);
var html = this.RenderViewResultAsString(viewResult);
masterName
) que você especificaria nulo. Também recomendo salvar e restaurar (após a renderização) controller.ViewData.Model caso o método seja chamado na instância do controlador atual e o modelo tenha sido atribuído antes desta chamada.