And*_*rew 13 c# email asp.net-mvc templates spark-view-engine
他们是使用ASP.NET MVC View生成电子邮件模板的解决方案,而不必跳过篮球.
让我详细说明跳过篮球.
var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var oldContext = HttpContext.Current;
HttpContext.Current = fakeContext;
var html = new HtmlHelper(new ViewContext(fakeControllerContext,
new FakeView(), viewDataDictionary, new TempDataDictionary()),
new ViewPage());
html.RenderPartial(viewName, viewData, viewDataDictionary);
HttpContext.Current = oldContext;
Run Code Online (Sandbox Code Playgroud)
上面的代码使用当前的HttpContext伪造一个新的Context并使用RenderPartial渲染页面,我们不应该这样做.
使用ControllerContext和.Render的另一个非常详细的解决方案:(IEmailTemplateService,Headers/Postback WorkAround),但是使用更多代码几乎做同样的事情.
另一方面,我正在寻找能够呈现View而不必POST/GET的东西,并生成一个简单的字符串,我可以通过我的电子邮件代码发送.不会发生错误的事情,例如发布标题两次或伪造一些数据.
EX:
//code which does not fire Render, RenderPartial... etc
var email = emailFramework.Create(viewData, view);
Run Code Online (Sandbox Code Playgroud)
请参阅我的解决方案或点击此链接:
我的解决方案使用spark:(12/30/2009)ASP.NET MVC电子邮件模板解决方案
And*_*rew 11
这就是我想要的ASP.NET MVC ViewEngine,但它在Spark中,只需按照右边的最新链接,
更新(12/30/2009)清洁版: ASP.NET MVC电子邮件模板解决方案
(11/16/2009)或者,Louis DeJardin控制台应用程序版本:
using System;
using Spark;
using Spark.FileSystem;
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public abstract class EmailView : AbstractSparkView
{
public User user { get; set; }
}
class Program
{
static void Main(string[] args)
{
// following are one-time steps
// create engine
var settings = new SparkSettings()
.SetPageBaseType(typeof(EmailView));
var templates = new InMemoryViewFolder();
var engine = new SparkViewEngine(settings)
{
ViewFolder = templates
};
// add templates
templates.Add("sample.spark", @"Dear ${user.Name}, This is an email.Sincerely, Spark View Engine http://constanto.org/unsubscribe/${user.Id}");
// following are per-render steps
// render template
var descriptor = new SparkViewDescriptor()
.AddTemplate("sample.spark");
var view = (EmailView)engine.CreateInstance(descriptor);
view.user = new User { Id = 655321, Name = "Alex" };
view.RenderView(Console.Out);
Console.ReadLine();
}
}
Run Code Online (Sandbox Code Playgroud)
我决定使用这种方法,因为它似乎是一切正确,它:
请务必阅读这些帖子.所有归功于Louis DeJardin看到他的教程:): 使用Spark作为通用模板引擎!,重新访问 电子邮件模板
为什么需要从视图中创建电子邮件?为什么不使用普通的旧模板文件?我一直这样做 - 我制作一个模板并使用城堡项目中的NVelocity引擎(不要与nvelocity VIEW引擎混淆)来渲染模板.
例:
var nvEngine = new NVelocityEngine();
nvEngine.Context.Add("FullName", fullName);
nvEngine.Context.Add("MallName", voucher.Mall.Name);
nvEngine.Context.Add("ConfirmationCode", voucher.ConfirmationCode);
nvEngine.Context.Add("BasePath", basePath);
nvEngine.Context.Add("TermsLink", termsLink);
nvEngine.Context.Add("LogoFilename", voucher.Mall.LogoFilename);
var htmlTemplate = System.IO.File.ReadAllText(
Request.MapPath("~/App_Data/Templates/Voucher.html"));
var email = nvEngine.Render(htmlTemplate);
Run Code Online (Sandbox Code Playgroud)
NVelocityEngine类是我在Castle项目提供的NVelocity端口周围编写的包装器,如下所示:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using NVelocity;
using NVelocity.App;
namespace MyProgram
{
/// <summary>
/// A wrapper for the NVelocity template processor
/// </summary>
public class NVelocityEngine : VelocityEngine
{
Hashtable context = new Hashtable();
/// <summary>
/// A list of values to be merged with the template
/// </summary>
public Hashtable Context
{
get { return context; }
}
/// <summary>
/// Default constructor
/// </summary>
public NVelocityEngine()
{
base.Init();
}
/// <summary>
/// Renders a template by merging it with the context items
/// </summary>
public string Render(string template)
{
VelocityContext nvContext;
nvContext = new VelocityContext(context);
using (StringWriter writer = new StringWriter())
{
this.Evaluate(nvContext, writer, "template", template);
return writer.ToString();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您根本不必干涉视图引擎,理论上如果需要,您可以使用ASP.NET视图引擎链接它,就像我在以下控制器方法中所做的那样:
public ActionResult ViewVoucher(string e)
{
e = e.Replace(' ', '+');
var decryptedEmail = CryptoHelper.Decrypt(e);
var voucher = Voucher.FindByEmail(decryptedEmail);
if (voucher == null) return View("Error", new Exception("Voucher not found."));
var basePath = new Uri(Request.Url, Url.Content("~/")).ToString();
var termsLink = new Uri(Request.Url, Url.Action("TermsGC", "Legal")).ToString();
basePath = basePath.Substring(0, basePath.Length - 1);
var fullName = voucher.FirstName;
if (!string.IsNullOrEmpty(voucher.LastName))
fullName += " " + voucher.LastName;
var nvEngine = new NVelocityEngine();
nvEngine.Context.Add("FullName", fullName);
nvEngine.Context.Add("MallName", voucher.Mall.Name);
nvEngine.Context.Add("ConfirmationCode", voucher.ConfirmationCode);
nvEngine.Context.Add("BasePath", basePath);
nvEngine.Context.Add("TermsLink", termsLink);
nvEngine.Context.Add("LogoFilename", voucher.Mall.LogoFilename);
var htmlTemplate = System.IO.File.ReadAllText(
Request.MapPath("~/App_Data/Templates/Voucher.html"));
return Content(nvEngine.Render(htmlTemplate));
}
Run Code Online (Sandbox Code Playgroud)
尝试使用spark view engine(http://www.sparkviewengine.com/).它易于使用,比标准引擎更好,并且不需要伪造上下文.
您还可以使用此答案中的函数将视图渲染为字符串,但它需要伪造上下文.这是标准视图引擎的工作方式,您无能为力.
这是我的扩展类,用于生成字符串视图.首先是标准视图引擎,第二个是Spark:
public static class ControllerHelper
{
/// <summary>Renders a view to string.</summary>
public static string RenderViewToString(this Controller controller,
string viewName, object viewData)
{
//Getting current response
var response = HttpContext.Current.Response;
//Flushing
response.Flush();
//Finding rendered view
var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
//Creating view context
var viewContext = new ViewContext(controller.ControllerContext, view,
controller.ViewData, controller.TempData);
//Since RenderView goes straight to HttpContext.Current, we have to filter and cut out our view
var oldFilter = response.Filter;
Stream filter = new MemoryStream(); ;
try
{
response.Filter = filter;
viewContext.View.Render(viewContext, null);
response.Flush();
filter.Position = 0;
var reader = new StreamReader(filter, response.ContentEncoding);
return reader.ReadToEnd();
}
finally
{
filter.Dispose();
response.Filter = oldFilter;
}
}
/// <summary>Renders a view to string.</summary>
public static string RenderSparkToString(this Controller controller,
string viewName, object viewData)
{
var view = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName).View;
//Creating view context
var viewContext = new ViewContext(controller.ControllerContext, view,
controller.ViewData, controller.TempData);
var sb = new StringBuilder();
var writer = new StringWriter(sb);
viewContext.View.Render(viewContext, writer);
writer.Flush();
return sb.ToString();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5337 次 |
| 最近记录: |