Отправить asp.net mvc результат действия внутри электронной почты

Я хотел бы использовать свое действие в asp.net mvc, в качестве механизма шаблона, которое приводит к форме строки, которую я мог бы отправить по электронной почте.

Псевдо-код:

public ActionResult Register()
{
    SendEmail(View().ToString());

    return new EmptyResult();
}

Ответ 1

Сначала вы, вероятно, захотите вернуть представление из своего действия, поэтому возврат EmptyResult не самый лучший; но вы поймете это, когда будете иметь дело с потоком страницы в процессе регистрации.

Я предполагаю, что вы хотите создать HTML-адрес электронной почты, используя View, который вы уже создали. Это означает, что вы хотите взять результат чего-то, что выглядит следующим образом:

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

и отправьте это как тело письма. Вы можете повторно использовать свои взгляды и все эти забавные вещи.

Вы можете воспользоваться каркасом, создав пользовательский ActionResult и используя его для генерации вашего текста.

Вот некоторый псевдокод С#, который может действительно скомпилироваться и работать. Во-первых, пользовательский ActionResult:

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

Это переопределяет базовый метод ExecuteResult (это код из базового метода, который я переопределяю, возможно, изменился в RC1), чтобы рендерить в поток, который я управляю вместо выходного потока Response. Таким образом, он вытаскивает текст точно, как он будет отображаться на клиентской машине.

Далее, как вы могли бы использовать это в действии контроллера:

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

Я делаю одно и то же представление дважды; в первый раз я передаю его потоку, а во второй раз я его делаю нормально. Возможно, можно прокрасться в цепочку вызовов ViewResult где-то еще и изменить, как работает Render, но беглый взгляд на код ничего не обнаруживает. Несмотря на то, что структура довольно хороша, стек вызовов для частей процесса просто недостаточно хорош, чтобы упростить изменение одного шага в этом процессе. Если они нарушили ExecuteResult в несколько различных переопределяемых методов, мы могли бы изменить его от рендеринга к выходному потоку до рендеринга в наш поток без переопределения всего метода ExecuteResult. О, хорошо...

Ответ 2

Здесь, как получить представление в виде строки.

Ответ 3

У меня недостаточно комментариев для комментариев, но я думал, что когда-нибудь буду экономить людей, указав, что похоже, что принятый ответ будет работать, и было бы здорово, если бы это произошло. Однако кажется, что WebForm View Engine просто ест параметр TextWriter. Здесь больше информации: http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx

Ответ 4

http://www.brightmix.com/blog/renderpartial-to-string-in-asp-net-mvc/ имеет хорошее решение для рендеринга представления в строку, чтобы вы могли отправить ее по электронной почте. Он отмечает, что "частичный просмотр строки, к счастью, стал намного проще".

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

Ответ 6

Вы не можете видеть представление внутри контроллера. Способ делать то, что вы просите, - это написать собственный подкласс ActionResult и настраиваемый ViewEngine для его обработки. Переопределите ExecuteResult, чтобы отправить сообщение по электронной почте. Посмотрите на open-source Spark, NHAML и т.д., Посмотрите примеры для MVC для примеров.

Ответ 9

Привет, из того, что я читаю (и моя собственная попытка реализовать ваше решение), метод View.Render полностью игнорирует параметр записи. Содержимое моего автора всегда пустое, и вместо этого визуализированное представление вырывается в поток ответов. Таким образом, это кажется невозможным (или, скорее, изогнутым, по крайней мере), чтобы вы использовали свое мнение так. Я думаю, что в вашем тестовом примере вы увидите визуализированный вид дважды, и ваше письмо будет пустым.

Я нашел здесь несколько обсуждений: http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx