Rendering al volo di una vista
-
03-07-2019 - |
Domanda
Sto sviluppando un'applicazione ASP.NET MVC che invierà all'utente un'email di conferma. Per l'e-mail stessa, vorrei creare una vista, quindi renderla e inviarla utilizzando gli oggetti di posta .NET.
Come posso farlo usando il framework MVC?
Soluzione 2
Come per il mio commento sulla risposta di Richard, questo codice ha funzionato, ma ha sempre provocato l'errore "Impossibile reindirizzare dopo che le intestazioni HTTP sono state inviate".
Dopo un lotto di scavare in giro per Google ed essere frustrato, ho finalmente trovato un codice che sembra fare il trucco, in questo articolo:
http: //mikehadlow.blogspot .com / 2008/06 / MVC-quadro-cattura-uscita-di-view_05.html
Il metodo di questo ragazzo è creare il proprio HttpContext.
Invece di utilizzare MVCContrib BlockRenderer, sostituisco semplicemente l'HttpContext corrente con uno nuovo che ospita una risposta che scrive su StringWriter.
Questo metodo funziona perfettamente (una piccola differenza è che ho dovuto creare un'azione separata per rendere la mia visione parziale, ma non c'è nessun dramma).
Altri suggerimenti
Fondamentalmente devi usare IView.Render
. Puoi ottenere la vista utilizzando ViewEngineCollection.FindView
( ViewEngines.Engines.FindView
per impostazione predefinita). Renderizza l'output in TextWriter
e assicurati di chiamare ViewEngine.ReleaseView
in seguito. Codice di esempio di seguito (non testato):
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();
Lascerò viewData / tempData a te.
Questo ha funzionato per me:
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);
}
}
}
}
}
}