2012-02-04 3 views
5

Я обрабатываю PartialViews/Models следующим способом, чтобы отправить шаблонные письма.ControllerContext и ViewData Внешняя область действия контроллера - MVC3 C#

Я использую приведенный ниже код для преобразования частичной и модели в строку html, которую я могу передать на мой код отправки электронной почты.

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

В настоящее время, это живет в BaseController, я хотел бы, чтобы переместить его в вспомогательном метод, так что я могу переместить мою электронная модель пристраивания/отправку из контроллера тоже.

Проблема в том, у меня нет доступа к ViewData/TempData/ControllerContext

я могу новый вверх ControllerContext, но я не знаю, что делать ViewData/TempData.

Это, как я хотел бы использовать то, что у меня есть в контроллере в настоящее время:

//Do Stuff in Controller 

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

//Send the Email 
+0

Вы используете tempdata/viewdata в рендеринге представления ? Если нет, то почему бы не пройти пустые? – Aliostad

+0

Я использую ViewData для установки модели. – Jason

+1

Так почему же это не строго типизированный вид? Вам нужно было использовать свободный просмотр? – Aliostad

ответ

2

Я думаю, что вы на правильном пути, но проблема в том, ваше стремление к полному разделению, это скорее слишком нетерпелив.

Вы используете механизм просмотра Razor для рендеринга вашего HTML-текста с богатым текстом. Очень благородный подход. Однако это означает, что вы будете очень близки к вашему уровню презентации и запускаете это извне контроллера - на мой взгляд, это не имеет большого смысла.

Я считаю, что вам нужно сделать (если это уже не сделано):

  • Ваш электронный вид Razor, как сильно типизированных
  • Пусть рендеринга, называемый в контроллере, как обычно
  • Rendering бы быть простым как прохождение модели к методу визуализации
  • Выньте здание своей модели электронной почты своему помощнику. Это не потребует логики уровня представления и, как таковая, не обращает на это внимания.

Таким образом, при вызове рендеринга не требуется выходить из контроллера, создание модели электронной почты должно быть выполнено.

Теперь, если вы все это делаете, это означает, что я не понял ваш вопрос и требует больше объяснений.

+0

Так, например, я бы сделал MailController, который возвращает строки? И просто оставьте метод RenderToHTML в BaseController или даже переместите его на MailController? Затем, например, в действии Account/Register, когда мне нужно отправить успешное электронное письмо: выполните ли мои записи, создайте почтовую модель, вызовите Mail/RenderRegisterEmail Action и передайте строку, которую он генерирует отправителю электронной почты? – Jason

0

Вы можете создать экземпляр или статическое свойство BaseController в классе хелперов, как показано ниже,

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

С уважением. Надеюсь это поможет.

0

Я использовал 2 метода для рендеринга Razor, которые нужно отправить стороне контроллера ... сначала я передал ControllerContext на свой сервисный уровень, который работал как ожидалось, но не идеально ... Часто мои услуги используются приложениями командной строки или скомпилированы в службу Windows, где нет доступного ControllerContext ... При моей второй попытке я использовал этот механизм рендеринга Razor: http://razorengine.codeplex.com/ или

Смежные вопросы