.net core mvc利用razor模板引擎开发邮件模板功能
前言:模板引擎渲染HTML的技术有很多,这里仅说明一下利用.net core下的mvc框架里的razor引擎怎么去做模板渲染功能。 在介绍之前,首先感谢磊哥的技术分享,得以让这篇文章成型。
核心参考文章:
Walkthrough: Creating an HTML Email Template with Razor and Razor Class Libraries
https://github.com/scottsauber/RazorHtmlEmails
a-razor引擎渲染HTML核心代码:
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Routing; using System; using System.IO; using System.Linq; using System.Threading.Tasks; namespace MeShop.CRM.Domain.Services.Vip.Helper { // Code from: https://github.com/aspnet/Entropy/blob/master/samples/Mvc.RenderViewToString/RazorViewToStringRenderer.cs public class RazorViewToStringRenderer : IRazorViewToStringRenderer { private IRazorViewEngine _viewEngine; private ITempDataProvider _tempDataProvider; private IServiceProvider _serviceProvider; public RazorViewToStringRenderer( IRazorViewEngine viewEngine, ITempDataProvider tempDataProvider, IServiceProvider serviceProvider) { _viewEngine = viewEngine; _tempDataProvider = tempDataProvider; _serviceProvider = serviceProvider; } public async Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model) { var actionContext = GetActionContext(); var view = FindView(actionContext, viewName); using (var output = new StringWriter()) { var viewContext = new ViewContext( actionContext, view, new ViewDataDictionary<TModel>( metadataProvider: new EmptyModelMetadataProvider(), modelState: new ModelStateDictionary()) { Model = model }, new TempDataDictionary( actionContext.HttpContext, _tempDataProvider), output, new HtmlHelperOptions()); await view.RenderAsync(viewContext); return output.ToString(); } } private IView FindView(ActionContext actionContext, string viewName) { var getViewResult = _viewEngine.GetView(executingFilePath: null, viewPath: viewName, isMainPage: true); if (getViewResult.Success) { return getViewResult.View; } var findViewResult = _viewEngine.FindView(actionContext, viewName, isMainPage: true); if (findViewResult.Success) { return findViewResult.View; } var searchedLocations = getViewResult.SearchedLocations.Concat(findViewResult.SearchedLocations); var errorMessage = string.Join( Environment.NewLine, new[] { $"Unable to find view '{viewName}'. The following locations were searched:" }.Concat(searchedLocations)); ; throw new InvalidOperationException(errorMessage); } private ActionContext GetActionContext() { var httpContext = new DefaultHttpContext(); httpContext.RequestServices = _serviceProvider; return new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); } } public interface IRazorViewToStringRenderer { Task<string> RenderViewToStringAsync<TModel>(string viewName, TModel model); } }
b-邮件模板模块:
需要注意的是:邮件模板模块,必须放在mvc项目的Views目录下,主要是利用Razor寻找页面元素位置的机制(或者可以自定义寻找视图位置)
TemplateShopExpired实体示例:
namespace MeShop.Module.Model.CRM.EmailTemplate { /// <summary> /// 邮件模板类-店铺过期 /// </summary> public class TemplateShopExpired { public string ShopHost { get; set; } public string ShopHostAdmin { get; set; } public string ShopSaveDays { get; set; } public string ShopCloseDate { get; set; } public string CdnHost { get; set; } } }