剃刀查看页面作为电子邮件模板

Lar*_*ara 15 .net html c# email razor

我设计了Razor Syntax的电子邮件模板.当我使用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>
Run Code Online (Sandbox Code Playgroud)

更新..

 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);

  }
Run Code Online (Sandbox Code Playgroud)

稍后我在将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
   );
Run Code Online (Sandbox Code Playgroud)

Bas*_*sem 22

您不需要任何特殊库来将 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在控制器中

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

ConfigureServices()Startup.cs 中

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)

这是您在 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();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,从控制器

ViewToStringRenderer.RenderViewToString(this.ControllerContext, "~/Views/Emails/MyEmailTemplate.cshtml", model);
Run Code Online (Sandbox Code Playgroud)

获得电子邮件内容后,可以轻松使用MailMessage和发送电子邮件SmtpClient

  • 如果要在没有控制器的情况下渲染视图,您知道如何获取 ControllerContext 吗? (4认同)
  • 这是正确的答案,我花了一整天的时间来研究这个问题。这工作起来很快并且没有一堆依赖。 (2认同)
  • 这。绝对是这个。我尝试过使用其他库,这些库很难工作,但在部署到服务器时却失败了。我已经在我的 .Net 5 项目中结合 Microsoft.Net.Mail.SmtpClient 实现了 .Net Core 解决方案,它的工作方式非常出色。Bassem - 只是一个建议:在代码中包含您的 using 语句,以便我们可以看到您正在使用哪些命名空间。干杯! (2认同)

SWe*_*eko 19

电子邮件只能理解两种格式:纯文本和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);
Run Code Online (Sandbox Code Playgroud)

  • 是否有一个asp.net核心2替代品? (4认同)

Dar*_*ght 5

你看过了吗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

本质上它会将你的 razor 视图解析为 html。