当前位置:  开发笔记 > 编程语言 > 正文

在电子邮件中发送asp.net mvc动作结果

如何解决《在电子邮件中发送asp.netmvc动作结果》经验,为你挑选了3个好方法。

我想在asp.net mvc中使用我的Action作为模板引擎,它会产生字符串形式,我可以通过电子邮件发送.

伪代码:

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

    return new EmptyResult();
}

小智.. 13

首先,你仍然可能想要从你的动作返回一个视图,所以返回一个EmptyResult不是最好的; 但是当你在注册过程中处理页面流时,你会发现这一点.

我假设您希望使用您已创建的视图创建HTML电子邮件.这意味着您希望获得类似于以下内容的结果:

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

并将其作为电子邮件的正文发送.您可以重用您的视图和所有有趣的东西.

您可以通过创建自定义ActionResult并使用它来生成文本来利用该框架.

这是一些可能实际编译和工作的类似c#的伪代码.首先,自定义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方法.那好吧....



1> 小智..:

首先,你仍然可能想要从你的动作返回一个视图,所以返回一个EmptyResult不是最好的; 但是当你在注册过程中处理页面流时,你会发现这一点.

我假设您希望使用您已创建的视图创建HTML电子邮件.这意味着您希望获得类似于以下内容的结果:

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

并将其作为电子邮件的正文发送.您可以重用您的视图和所有有趣的东西.

您可以通过创建自定义ActionResult并使用它来生成文本来利用该框架.

这是一些可能实际编译和工作的类似c#的伪代码.首先,自定义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方法.那好吧....


神圣的废话.... MVC 1完全忽略了流,只是写入响应.http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx我想知道他们是否已修复此问题2 ?

2> Jonathan..:

我没有足够的评论来评论,但我想我会节省一些时间,指出似乎接受的答案会起作用,如果它确实会很好.但是,似乎WebForm视图引擎只是吃了TextWriter参数.这里有更多信息:http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx



3> Ian Mercer..:

http://www.brightmix.com/blog/renderpartial-to-string-in-asp-net-mvc/有一个很好的解决方案,可以将View渲染为字符串,以便您可以通过电子邮件发送它.他指出"幸运的是,渲染部分视图到字符串变得更容易了."

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

推荐阅读
罗文彬2502852027
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有