Renderizar uma vista on-the-fly
-
03-07-2019 - |
Pergunta
Estou desenvolvendo uma aplicação ASP.NET MVC que irá enviar ao usuário um e-mail de confirmação. Para o próprio e-mail, eu gostaria de criar uma visão e, em seguida, tornar essa visão e enviá-lo usando os objetos de correio NET.
Como posso fazer isso usando o framework MVC?
Solução 2
De acordo com o meu comentário sobre a resposta de Richard, este código não funcionou, mas sempre resultou em uma 'Não é possível redirecionar depois de cabeçalhos HTTP foram enviados' erro.
Depois de um muito de escavar em torno do Google e ser frustrado, eu finalmente encontrei algum código que parece estar a fazer o truque, neste artigo:
http: //mikehadlow.blogspot .com / 2008/06 / MVC-estrutura de captura e saída-de-view_05.html
método Esse cara é criar seu próprio HttpContext.
Ao invés de usar o MVCContrib BlockRenderer eu simplesmente substituir o atual HttpContext com um novo que anfitriões uma resposta que grava em um StringWriter.
Este método funciona perfeitamente (a pequena diferença é que eu tive que criar uma ação separada para a prestação de meu ponto de vista parcial, mas nenhum drama lá).
Outras dicas
Você precisa basicamente para uso IView.Render
. Você pode obter a vista utilizando ViewEngineCollection.FindView
(ViewEngines.Engines.FindView
para os padrões). Processar a saída para um TextWriter
e certifique-se de chamar ViewEngine.ReleaseView
depois. código de exemplo abaixo (não testado):
StringWriter output = new StringWriter();
string viewName = "Email";
string masterName = "";
ViewEngineResult result = ViewEngines.Engines.FindView(ControllerContext, viewName, masterName);
ViewContext viewContext = new ViewContext(ControllerContext, result.View, viewData, tempData);
result.View.Render(viewContext, output);
result.ViewEngine.ReleaseView(ControllerContext, result.View);
string viewOutput = output.ToString();
Vou deixar viewData / TempData para você.
Isso funcionou para mim:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
namespace Profiteer.WebUI.Controllers
{
public class SampleController : Controller
{
public ActionResult Index()
{
RenderViewAsHtml(RouteData.Values["controller"].ToString(),
RouteData.Values["action"].ToString());
return View();
}
private void RenderViewAsHtml(string controllerName, string viewName)
{
var vEngine = (from ve in ViewEngineCollection
where ve.GetType() == typeof(RazorViewEngine)
select ve).FirstOrDefault();
if (vEngine != null)
{
var view =
vEngine.FindView(
ControllerContext,
viewName, "_Layout", false).View as RazorView;
if (view != null)
{
var outPath =
Server.MapPath(
string.Format("~/Views/{0}/{1}.html",
controllerName, viewName));
using (var sw = new StreamWriter(outPath, false))
{
var viewContext =
new ViewContext(ControllerContext,
view,
new ViewDataDictionary(),
new TempDataDictionary(),
sw);
view.Render(viewContext, sw);
}
}
}
}
}
}