繁体   English   中英

Razor 视图页面作为电子邮件模板

[英]Razor View Page as Email Template

我从 Razor 语法设计了一个电子邮件模板。 当我使用 C# 代码和 SMTP 协议将此模板作为电子邮件发送时,我得到裸露的 Razor 和 HTML 标记作为电子邮件正文。 这种方法我错了吗? Razor 页面是否允许作为电子邮件模板?

这是我的页面

@inherits ViewPage
@{
Layout = "_Layout";
ViewBag.Title = "";
}
<div class="container w-420 p-15 bg-white mt-40">
<div style="border-top:3px solid #22BCE5">&nbsp;</div>
<span style="font-family:Arial;font-size:10pt">
    Hello <b>{UserName}</b>,<br /><br />
    Thanks for Registering to XYZ Portal<br /><br />
    <a style="color:#22BCE5" href="{Url}">Click to Confirm Email</a><br />

    <br /><br />
    Thanks<br />
    Admin (XYZ)
</span>

更新..

 using (StreamReader reader = new StreamReader(HttpContext.Current.Server.MapPath("~/ContentPages/EmailConfTemplate.cshtml")))
  {
     body = reader.ReadToEnd();
     //Replace UserName and Other variables available in body Stream
     body = body.Replace("{UserName}", FirstName);

  }

后来我将 SMTP 代码替换为 ..

  MailMessage message = new MailMessage(
    ApplicationWideData.fromEmailId, // From field
    ToEmailId, // Recipient field
    "Click On HyperLink To Verify Email Id", // Subject of the email message
    body
   );

电子邮件只能理解两种格式:纯文本和 HTML。 由于 Razor 两者都不是,因此需要由某些引擎处理它,以便将生成的 HTML 返回给您。

这正是您在 ASP.NET MVC 中使用 Razor 时在幕后发生的情况。 Razor 文件被编译成一个内部 C# 类,它被执行,执行的结果是 HTML 的字符串内容,它被发送到客户端。

您的问题是您想要并且需要运行该处理,只是为了将 HTML 作为字符串返回,而不是发送到浏览器。 之后,您可以对 HTML 字符串执行任何您想要的操作,包括将其作为电子邮件发送。

有几个包包含这种功能,我已经成功地使用了Westwind.RazorHosting ,但您也可以使用RazorEngine获得类似的结果。 我更喜欢 RazorHosting 用于独立的非 Web 应用程序,而 RazorEngine 用于 Web 应用程序

这是我的一些代码的(净化)版本 - 我正在使用 Westwind.RazorHosting 使用强类型视图从 Windows 服务发送剃刀格式的电子邮件。

RazorFolderHostContainer host = = new RazorFolderHostContainer();
host.ReferencedAssemblies.Add("NotificationsManagement.dll");
host.TemplatePath = templatePath;
host.Start();
string output = host.RenderTemplate(template.Filename, model);

MailMessage mm = new MailMessage { Subject = subject, IsBodyHtml = true };
mm.Body = output;
mm.To.Add(email);

var smtpClient = new SmtpClient();
await smtpClient.SendMailAsync(mm);

您不需要任何特殊库来将 Razor 视图呈现为 ASP.NET MVC 应用程序中的字符串。

以下是您在 MVC Core 3 中的操作方法

public static class ViewToStringRenderer
{
    public static async Task<string> RenderViewToStringAsync<TModel>(IServiceProvider requestServices, string viewName, TModel model)
    {
        var viewEngine = requestServices.GetRequiredService(typeof(IRazorViewEngine)) as IRazorViewEngine;
        ViewEngineResult viewEngineResult = viewEngine.GetView(null, viewName, false);
        if (viewEngineResult.View == null)
        {
            throw new Exception("Could not find the View file. Searched locations:\r\n" + string.Join("\r\n", viewEngineResult.SearchedLocations));
        }
        else
        {
            IView view = viewEngineResult.View;
            var httpContextAccessor = (IHttpContextAccessor)requestServices.GetRequiredService(typeof(IHttpContextAccessor));
            var actionContext = new ActionContext(httpContextAccessor.HttpContext, new RouteData(), new ActionDescriptor());
            var tempDataProvider = requestServices.GetRequiredService(typeof(ITempDataProvider)) as ITempDataProvider;

            using var outputStringWriter = new StringWriter();
            var viewContext = new ViewContext(
                actionContext,
                view,
                new ViewDataDictionary<TModel>(new EmptyModelMetadataProvider(), new ModelStateDictionary()) { Model = model },
                new TempDataDictionary(actionContext.HttpContext, tempDataProvider),
                outputStringWriter,
                new HtmlHelperOptions());

            await view.RenderAsync(viewContext);

            return outputStringWriter.ToString();
        }
    }
}

在控制器中

string str = await ViewToStringRenderer.RenderViewToStringAsync(HttpContext.RequestServices, $"~/Views/Emails/MyEmailTemplate.cshtml", new MyEmailModel { Prop1 = "Hello", Prop2 = 23 });

在 Startup.cs 的ConfigureServices()

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

这是您在 MVC 5 中的操作方法

public static class ViewToStringRenderer
{
    public static string RenderViewToString<TModel>(ControllerContext controllerContext, string viewName, TModel model)
    {
        ViewEngineResult viewEngineResult = ViewEngines.Engines.FindView(controllerContext, viewName, null);
        if (viewEngineResult.View == null)
        {
            throw new Exception("Could not find the View file. Searched locations:\r\n" + viewEngineResult.SearchedLocations);
        }
        else
        {
            IView view = viewEngineResult.View;

            using (var stringWriter = new StringWriter())
            {
                var viewContext = new ViewContext(controllerContext, view, new ViewDataDictionary<TModel>(model), new TempDataDictionary(), stringWriter);
                view.Render(viewContext, stringWriter);

                return stringWriter.ToString();
            }
        }
    }
}

然后,从控制器

ViewToStringRenderer.RenderViewToString(this.ControllerContext, "~/Views/Emails/MyEmailTemplate.cshtml", model);

获得电子邮件内容后,可以使用MailMessageSmtpClient轻松发送电子邮件。

你看过MVC Mailer吗?

这是一个可从 GitHub ( https://github.com/smsohan/MvcMailer ) 获得的免费软件包

也有一个分步指南https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide

它也在 Nuget 上。 https://www.nuget.org/packages/MvcMailer

本质上,它会将您的剃刀视图解析为 html。

查看 NuGet 上提供的 RazorEngine ( https://razorengine.codeplex.com/ ) 等剃须刀处理器。 它处理 razor 以创建输出,然后将其用作电子邮件正文。

Mailzory项目是发送带有 Razor 模板的电子邮件的一个有价值且方便的选择。

// template path
var viewPath = Path.Combine("Views/Emails", "hello.cshtml");
// read the content of template and pass it to the Email constructor
var template = File.ReadAllText(viewPath);

var email = new Email(template);

// set ViewBag properties
email.ViewBag.Name = "Johnny";
email.ViewBag.Content = "Mailzory Is Funny";

// send email
var task = email.SendAsync("mailzory@outlook.com", "subject");
task.Wait()

该项目托管在 Github。 还有一个可用于 Mailzory 的nuget 包

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM