2012-02-04 12 views
5

Sto visualizzando PartialViews/Modelli con il metodo seguente al fine di inviare e-mail modello che vengono inviate.ControllerContext e ViewData Ambito di applicazione esterno del controller - MVC3 C#

Sto usando il codice qui sotto per convertire il partial e il modello in una stringa html che posso passare al mio codice di invio email.

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(); 
     } 
    } 
} 

Attualmente, questo vive nella BaseController, vorrei spostarlo fuori in un metodo di supporto in modo che possa passare il mio modello e-mail la costruzione di fuori/invio del controller troppo.

Il problema è che non ho accesso al Viewdata/TempData/ControllerContext

posso nuovo un ControllerContext ma non so cosa fare Viewdata/TempData.

Questo è come vorrei usare quello che ho in controller attualmente:

//Do Stuff in Controller 

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

//Send the Email 
+0

Si sta utilizzando tempdata/viewdata nel rendering della vista ? Se no, perché non passare quelli vuoti? – Aliostad

+0

Sto utilizzando ViewData per impostare il modello. – Jason

+1

Quindi, perché non è una visualizzazione fortemente tipizzata? Hai dovuto usare la vista allentata? – Aliostad

risposta

2

Penso che tu sia sulla strada giusta, ma il problema è il tuo desiderio di completare la separazione, è un po 'troppo ansioso.

Si sta utilizzando il motore di visualizzazione Razor per eseguire il rendering dell'email HTML RTF. Un approccio molto nobile. Tuttavia, questo significa che sarai molto vicino al tuo livello di presentazione e che eseguirlo da un controller esterno, a mio avviso, non ha molto senso.

Credo che hai bisogno di fare (se non già fatto):

  • tua email vista del rasoio come fortemente tipizzato
  • Diamo il rendering chiamato nel controller come al solito
  • rendering sarebbe così semplice come passare il modello al metodo Render
  • Estrarre l'edificio del modello di posta elettronica per l'helper che desideri. Ciò non richiederebbe alcuna logica di livello di presentazione e come tale ignaro di esso.

Quindi il punto è che la chiamata del rendering non ha bisogno di uscire dal controller, dovrebbe costruirsi il modello di email.

Ora, se stai facendo tutto questo significa che non ho capito la tua domanda e richiede più spiegazioni.

+0

Quindi, ad esempio, farei un MailController che restituisce le stringhe? E lascia il metodo RenderToHTML in BaseController o spostalo su MailController? Quindi, nell'azione Account/Registra, ad esempio, quando ho bisogno di inviare una e-mail di successo: fai il mio registro roba, costruisci il modello di posta, chiama l'azione Mail/RenderRegisterEmail e passa la stringa che genera al mittente dell'e-mail? – Jason

0

È possibile creare un'istanza o una proprietà statica della BaseController nella classe di supporto come mostrato di seguito,

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(.......); 
}} 

saluti. Spero che questo ti aiuti.

0

Ho usato 2 metodi per le email di rendering Razor che devono essere inviate all'esterno del controller ... prima ho passato il ControllerContext al mio livello di servizio che funzionava come previsto, ma non ideale .... Spesso i miei servizi sono utilizzati da applicazioni da riga di comando o compilati in un servizio di Windows in cui non è disponibile ControllerContext ... Al mio secondo tentativo ho usato questo motore di rendering Razor: http://razorengine.codeplex.com/ o https://github.com/Antaris/RazorEngine

Problemi correlati