【问题标题】:Razor View Page as Email TemplateRazor 查看页面作为电子邮件模板
【发布时间】:2016-01-12 11:06:38
【问题描述】:

我从 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。您如何使用代码中的模板来准备电子邮件?
  • @SWeko 我正在使用 Razor 语法创建电子邮件正文。对于发送我在 c# 中使用 SMTP
  • 你能显示代码吗?
  • @SWeko 你想要我的 C# 代码吗?
  • @SWeko 我更新了我的帖子..请看一下。我还尝试用HTML 替换.cshtml 页面,但我再次获得与邮件正文相同的HTML 标记语法。我指的是codeproject.com/Articles/874218/…链接

标签: c# html .net email razor


【解决方案1】:

电子邮件信息只支持两种格式:纯文本和 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);

【讨论】:

  • 保存 .cshtml 非常容易 - Razor 是一个很棒的模板引擎 - 特别是如果你有不同的模型,以及不同语言的模板等等......更不用说你总是可以抓住文件,将其设置为真实视图,然后在浏览器中查看。
  • 是否有 asp.net core 2 替代方案?
【解决方案2】:

您不需要任何特殊的库来将 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 });

ConfigureServices() 中的 Startup.cs

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轻松发送邮件了。

【讨论】:

  • 这是一个正确的答案,我花了一整天的时间来解决这个问题。这可以快速运行并且没有大量依赖项。
  • 完美答案,这一定是公认的答案!
  • 这太棒了!我们现在不需要那个 RazorEngine 库..
  • 如果要在没有控制器的情况下呈现视图,关于如何获取 ControllerContext 的任何想法?
  • 这个。绝对是这个。我尝试过使用其他难以工作的库,然后在部署到服务器时摔倒了。我已经在我的 .Net 5 项目中与 Microsoft.Net.Mail.SmtpClient 一起实现了 .Net Core 解决方案,它就像一个魅力。 Bassem - 只是一个建议:在代码中包含您的 using 语句,以便我们可以看到您正在使用哪些命名空间。干杯!
【解决方案3】:

你看过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。

【讨论】:

    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      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 package

      【讨论】:

        猜你喜欢
        • 2020-05-26
        • 2011-05-21
        • 2012-09-21
        • 2010-10-02
        • 2014-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多