簡體   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