Enviar el resultado de la acción asp.net mvc dentro del correo electrónico

Me gustaría usar mi Acción en asp.net mvc, como motor de plantillas, que da como resultado una cadena, que podría enviar por correo electrónico.

Pseudo-código:

public ActionResult Register() { SendEmail(View().ToString()); return new EmptyResult(); } 

En primer lugar, probablemente aún quiera devolver una vista de su acción, por lo que devolver un EmptyResult no es el mejor; pero lo sabrá cuando esté lidiando con el flujo de páginas en su proceso de registro.

Supongo que desea crear un correo electrónico HTML utilizando una Vista que ya ha creado. Eso significa que desea tomar el resultado de algo que se parece a lo siguiente:

 public ActionResult CreateEmailView(RegistrationInformation info) { var userInformation = Membership.CreateNewUserLol(info); return View(userInformation) } 

y enviar eso como el cuerpo del correo electrónico. Puedes volver a utilizar tus puntos de vista y todas esas cosas divertidas.

Puede aprovechar el marco creando un resultado de acción personalizado y usándolo para generar su texto.

Aquí hay un pseudocódigo tipo c # que podría comstackrse y funcionar. Primero, el ActionResult personalizado:

 public class StringResult : ViewResult { public string Html { get; set; } public override void ExecuteResult(ControllerContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (string.IsNullOrEmpty(this.ViewName)) { this.ViewName = context.RouteData.GetRequiredString("action"); } ViewEngineResult result = null; if (this.View == null) { result = this.FindView(context); this.View = result.View; } ViewContext viewContext = new ViewContext( context, this.View, this.ViewData, this.TempData); using (var stream = new MemoryStream()) using (var writer = new StreamWriter(stream)) { // used to write to context.HttpContext.Response.Output this.View.Render(viewContext, writer); writer.Flush(); Html = Encoding.UTF8.GetString(stream.ToArray()); } if (result != null) { result.ViewEngine.ReleaseView(context, this.View); } } } 

Esto anula el ExecuteResult del método base (este es el código del método base que anulo, puede haber cambiado en RC1) para representar en una secuencia que controlo en lugar de la secuencia de salida de la respuesta. Por lo tanto, extrae el texto exactamente cómo se representaría en la máquina del cliente.

A continuación, cómo usaría esto en una acción de controlador:

 public ActionResult CreateEmailView(RegistrationInformation info) { var userInformation = Membership.CreateNewUserLol(info); // grab our normal view so we can get some info out of it var resultView = View(userInformation); // create our string result and configure it StringResult sr = new StringResult(); sr.ViewName = resultView.ViewName; sr.MasterName = resultView.MasterName; sr.ViewData = userInformation; sr.TempData = resultView.TempData; // let them eat cake sr.ExecuteResult(this.ControllerContext); string emailHtml = sr.Html; // awesome utils package, dude Utils.SendEmailKThx(userInformation, emailHtml); return resultView; } 

Estoy renderizando la misma vista dos veces; la primera vez que la renderizo en una secuencia y la segunda vez la renderizo normalmente. Es posible colarse en la cadena de llamadas de ViewResult en otro lugar y cambiar la forma en que Render opera, pero una mirada rápida al código no revela nada. Si bien el marco es bastante bueno, la stack de llamadas para partes del proceso no es lo suficientemente fina como para que sea fácil cambiar un solo paso en el proceso. Si rompieron ExecuteResult en unos pocos métodos reemplazables diferentes, podríamos haberlo cambiado de renderizado a flujo de salida para renderizar a nuestra stream sin anular todo el método ExecuteResult. Oh bien….

A continuación, se indica cómo obtener la vista como una cadena.

No tengo suficiente representante para comentar, pero pensé que podría ahorrarle algo de tiempo a la gente señalando que parece que la respuesta aceptada funcionaría y sería genial si lo hiciera. Sin embargo, parece que el motor de vista de WebForm simplemente come el parámetro TextWriter. Hay más información aquí: http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx

http://www.brightmix.com/blog/renderpartial-to-string-in-asp-net-mvc/ tiene una buena solución para representar una vista en una cadena para que pueda enviarla por correo electrónico. Señala que “al hacer una vista parcial de la cuerda, afortunadamente, se ha vuelto mucho, mucho más fácil”.

 /// Static Method to render string - put somewhere of your choosing public static string RenderPartialToString(string controlName, object viewData) { ViewDataDictionary vd = new ViewDataDictionary(viewData); ViewPage vp = new ViewPage { ViewData = vd }; Control control = vp.LoadControl(controlName); vp.Controls.Add(control); StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { using (HtmlTextWriter tw = new HtmlTextWriter(sw)) { vp.RenderControl(tw); } } return sb.ToString(); } 

MvcMailer obtuvo justo lo que estás buscando. Vea el paquete NuGet aquí y la documentación del proyecto

¡Espero eso ayude!

No puede ver la vista en sí dentro del controlador. La forma de hacer lo que pide es escribir una subclase ActionResult personalizada y un ViewEngine personalizado para manejarla. Anule ExecuteResult para enviar realmente el correo electrónico. Mire el código abierto Spark, NHAML, etc., vea los motores para MVC para ver ejemplos.

Este artículo me proporcionó la mejor respuesta:

Render cualquier ASP.NET MVC ActionResult a una cadena

Hay un buen artículo sobre cómo usar RazorEngine para ese propósito: Cómo crear un motor de plantillas de texto localizable usando RazorEngine

Oye Will, por lo que estoy leyendo (y mi propio bash de implementar tu solución), el método View.Render ignora por completo el parámetro del escritor. El contenido de mi escritor siempre está vacío y, en cambio, la vista representada se deja escapar en la secuencia de respuesta. Por lo tanto, parece imposible (o al menos intrincado al menos) para obtener su uso que ve de esa manera. Creo que en su caso de prueba verá la vista renderizada dos veces y su correo electrónico estará en blanco.

Encontré algo de discusión sobre esto aquí: http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx