2012-02-04 11 views
5

Estoy representando Parciales/Modelos con el siguiente método para modelar los correos electrónicos que se envían.ControllerContext y ViewData Outside Scope of Controller - MVC3 C#

Estoy usando el siguiente código para convertir el parcial y el modelo en una cadena html que puedo pasar a mi código de envío de correo electrónico.

public class BaseController : Controller 
{ 
    public string RenderPartialViewToString(string viewName, object model) 
    { 
     if (string.IsNullOrEmpty(viewName)) 
      throw new ArgumentException("No View Path Provided."); 

     ViewData.Model = model; 

     using (StringWriter sw = new StringWriter()) 
     { 
      ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); 
      ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); 
      viewResult.View.Render(viewContext, sw); 

      return sw.GetStringBuilder().ToString(); 
     } 
    } 
} 

Actualmente, este vive en el BaseController, me gustaría moverlo hacia un método de ayuda para que pueda mover el modelo de correo electrónico a cabo la construcción/envío de la controladora también.

El problema es que no tengo acceso a ViewData/TempData/ControllerContext

puedo nuevo un ControllerContext pero no sé qué hacer con ViewData/TempData.

Esta es la forma en que yo usaría lo que tengo en el controlador actualmente:

//Do Stuff in Controller 

var html = RenderPartialViewToString("~/Views/Mail/_ForgotPassword.cshtml", new MailModel { Username = "Skrillex", SomethingElse = "foo" }); 

//Send the Email 
+0

¿Está utilizando tempdata/viewdata en la representación de la vista ? Si no, ¿por qué no pasar los vacíos? – Aliostad

+0

Estoy usando ViewData para establecer el modelo. – Jason

+1

Entonces, ¿por qué no es una vista fuertemente tipada? ¿Tuviste que usar vista suelta? – Aliostad

Respuesta

2

Creo que usted está en el camino correcto, pero el problema es que su afán de completar la separación, es más bien demasiado ansioso.

Está utilizando el motor de visualización Razor para procesar su correo HTML enriquecido. Un enfoque muy noble. Sin embargo, esto significa que estará muy cerca de su capa de presentación y ejecutar esto desde fuera de un controlador, en mi opinión, no tiene mucho sentido.

Creo que usted necesita para hacer (si no se ha hecho):

  • Su correo electrónico vista de la maquinilla de afeitar tan inflexible de tipos
  • Vamos a la prestación llamada en el controlador como de costumbre
  • representación sería tan sencillo como pasar el modelo al método Render
  • Saque la construcción de su modelo de correo electrónico a la ayuda que desee. Esto no requeriría ninguna lógica de capa de presentación y, como tal, ajeno a ella.

Así que el punto es, llamado de la prestación no tiene que salir del controlador, la construcción del modelo de correo electrónico debe.

Ahora bien, si está haciendo todo eso, significa que no he entendido su pregunta y que necesita más explicaciones.

+0

Entonces, por ejemplo, ¿haría un MailController que devuelve cadenas? ¿Y dejar el método RenderToHTML en BaseController o incluso moverlo a MailController? Luego, en la acción Cuenta/Registrar, por ejemplo, cuando necesito enviar un correo electrónico exitoso: ¿Mis cosas para registrar, crear modelo de correo, llamar a Mail/RenderRegisterEmail Action y pasar la cadena que genera al remitente del correo electrónico? – Jason

0

Puede crear una instancia o propiedad estática de BaseController en la clase de ayuda que se muestra a continuación,

public sealed class Helper { 
///Gets or sets BaseController 
public BaseController { get; set; } 
#region "Constructors" 
/// <summary> 
/// Initialises a new instance of the <see cref="Helper" /> class. 
/// </summary> 
public Helper() : base() { 

} 
/// <summary> 
/// Initialises a new instance of the <see cref="Helper" /> class. 
/// </summary> 
public Helper(BaseController baseController) : this() { 
    this.BaseController = baseController; 
} 
#endregion 
public void SendEmail(){ 
    // Here you can call your RenderPartialViewToString from the BaseController 
var m_RenderPartialViewToString = this.BaseController.RenderPartialViewToString(.......); 
}} 

Saludos. Espero que esto ayude.

0

He usado 2 métodos para renderizar correos electrónicos Razor que necesitan ser enviados al lado de un controlador ... primero pasé el ControllerContext a mi capa de servicio que funcionó como se esperaba, pero no ideal .... A menudo mis servicios son utilizados por aplicaciones de línea de comandos o compilados en un Servicio de Windows donde no hay ControllerContext disponible ... En mi segundo intento utilicé este motor de renderizado Razor: http://razorengine.codeplex.com/ o https://github.com/Antaris/RazorEngine