邮件的内容其实是就HTML,传统的做法都是通过在程序中拼接字符串来生成邮件的内容,生成困难,维护也困难。Razor是MVC里面使用的视图引擎,用来生成HTML非常方便,ZKEACMS中就是使用了Razor视图引擎,用cshtml作为邮件模板来生成邮件内容。这样很方便维护和修改。
定义接口 IViewRenderService
接口中定义了两个方法,第一个是视图中没有使用ViewModel,直接传入视图路径就可以了。第二个是视图中有作用ViewModel,传入视图路径和ViewModel对象就可以。
namespace Easy.Mvc.RazorPages
{
public interface IViewRenderService
{
string Render(string viewPath);
string Render(string viewPath, Model model);
}
}
接口实现 ViewRenderService
实现的方式也比较简单,主要还是直接使用了RazorViewEngine:
namespace Easy.Mvc.RazorPages
{
public class ViewRenderService : IViewRenderService
{
private readonly IRazorViewEngine _viewEngine;
private readonly ITempDataProvider _tempDataProvider;
private readonly IServiceProvider _serviceProvider;
public ViewRenderService(IRazorViewEngine viewEngine, ITempDataProvider tempDataProvider,
IServiceProvider serviceProvider)
{
_viewEngine = viewEngine;
_tempDataProvider = tempDataProvider;
_serviceProvider = serviceProvider;
}
public string Render(string viewPath)
{
return Render(viewPath, string.Empty);
}
public string Render(string viewPath, TModel model)
{
var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider };
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var viewResult = _viewEngine.GetView(null, viewPath, false);
if (!viewResult.Success)
{
throw new InvalidOperationException($"找不到视图模板 {viewPath}");
}
var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
{
Model = model
};
using (var writer = new StringWriter())
{
var viewContext = new ViewContext(
actionContext,
viewResult.View,
viewDictionary,
new TempDataDictionary(actionContext.HttpContext, _tempDataProvider),
writer,
new HtmlHelperOptions()
);
var render = viewResult.View.RenderAsync(viewContext);
render.Wait();
return writer.ToString();
}
}
}
}
使用
使用的方法也很简单,首先要先建一个邮件模板,例如 ResetPassword.cshtml
代码如下:
@model ZKEACMS.Notification.ViewModels.ResetPasswordViewModel
重置密码您正在重置密码,
您可以使用以下链接来重置您的密码,为了安全,该链接仅会在一段时间内有效,请尽快重置密码
@Model.Link
ZKEASOFT
http://www.zkea.net
@DateTime.Now.ToString("yyyy-MM-dd")
接下来就是调用ViewRenderService
var htmlContent = _viewRenderService.Render("~/EmailTemplates/ResetPassword.cshtml", new ResetPasswordViewModel{Link=...});
有了内容以后,就可以直接调用发送了。