app*_*orm 22 asp.net-mvc template-engine
我想在asp.net mvc中使用我的Action作为模板引擎,它会产生字符串形式,我可以通过电子邮件发送.
伪代码:
public ActionResult Register()
{
SendEmail(View().ToString());
return new EmptyResult();
}
Run Code Online (Sandbox Code Playgroud)
小智 13
首先,你仍然可能想要从你的动作返回一个视图,所以返回一个EmptyResult不是最好的; 但是当你在注册过程中处理页面流时,你会发现这一点.
我假设您希望使用您已创建的视图创建HTML电子邮件.这意味着您希望获得类似于以下内容的结果:
public ActionResult CreateEmailView(RegistrationInformation info)
{
var userInformation = Membership.CreateNewUserLol(info);
return View(userInformation)
}
Run Code Online (Sandbox Code Playgroud)
并将其作为电子邮件的正文发送.您可以重用您的视图和所有有趣的东西.
您可以通过创建自定义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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这将覆盖基本方法的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;
}
Run Code Online (Sandbox Code Playgroud)
我两次渲染相同的视图; 我第一次将它渲染到流中,第二次我正常渲染它.有可能潜入其他地方的ViewResult调用链并改变Render的操作方式,但粗略地看一眼代码并没有透露任何东西.虽然框架非常好,但部分流程的调用堆栈不够精细,无法轻松更改流程中的单个步骤.如果他们将ExecuteResult分解为几个不同的可覆盖方法,我们可以将它从渲染更改为输出流,以渲染到我们的流,而不会覆盖整个ExecuteResult方法.那好吧....
我没有足够的评论来评论,但我想我会节省一些时间,指出似乎接受的答案会起作用,如果它确实会很好.但是,似乎WebForm视图引擎只是吃了TextWriter参数.这里有更多信息:http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx
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();
}
Run Code Online (Sandbox Code Playgroud)
您无法在控制器内部看到视图本身。执行您要求的操作的方法是编写一个自定义 ActionResult 子类,以及一个自定义 ViewEngine 来处理它。重写 ExecuteResult 以实际发送电子邮件。看看开源的Spark、NHAML等,MVC的视图引擎为例。
| 归档时间: |
|
| 查看次数: |
12701 次 |
| 最近记录: |