ASP.NET MVC Email

后端 未结 7 1206
日久生厌
日久生厌 2021-01-30 11:50

Is their a solution to generate an email template using an ASP.NET MVC View without having to jump through hoops.

Let me elaborate jumping through hoops.



        
7条回答
  •  死守一世寂寞
    2021-01-30 12:41

    Why do you need to create the email from a view? Why not use a plain old template file? I do this all the time - I make a template and use the NVelocity engine from the castle project (not to be confused with an nvelocity VIEW engine) to render the template.

    Example:

    var nvEngine = new NVelocityEngine();
    nvEngine.Context.Add("FullName", fullName);
    nvEngine.Context.Add("MallName", voucher.Mall.Name);
    nvEngine.Context.Add("ConfirmationCode", voucher.ConfirmationCode);
    nvEngine.Context.Add("BasePath", basePath);
    nvEngine.Context.Add("TermsLink", termsLink);
    nvEngine.Context.Add("LogoFilename", voucher.Mall.LogoFilename);
    
    var htmlTemplate = System.IO.File.ReadAllText(
        Request.MapPath("~/App_Data/Templates/Voucher.html"));
    
    var email = nvEngine.Render(htmlTemplate);
    

    The NVelocityEngine class is a wrapper I wrote around the NVelocity port provided by the Castle project as shown below:

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using NVelocity;
    using NVelocity.App;
    
    namespace MyProgram
    {
        /// 
        /// A wrapper for the NVelocity template processor
        /// 
        public class NVelocityEngine : VelocityEngine
        {
            Hashtable context = new Hashtable();
    
            /// 
            /// A list of values to be merged with the template
            /// 
            public Hashtable Context
            {
                get { return context; }
            }
    
            /// 
            /// Default constructor
            /// 
            public NVelocityEngine()
            {
                base.Init();
            }
    
            /// 
            /// Renders a template by merging it with the context items
            /// 
            public string Render(string template)
            {
                VelocityContext nvContext;
    
                nvContext = new VelocityContext(context);
                using (StringWriter writer = new StringWriter())
                {
                    this.Evaluate(nvContext, writer, "template", template);
                    return writer.ToString();
                }
            }
        }
    }
    

    In this way, you don't have to meddle with the view engine at all, and you can theoretically chain this with the ASP.NET view engine if you wanted, like I have done in the following controller method:

    public ActionResult ViewVoucher(string e)
    {
        e = e.Replace(' ', '+');
        var decryptedEmail = CryptoHelper.Decrypt(e);
        var voucher = Voucher.FindByEmail(decryptedEmail);
        if (voucher == null) return View("Error", new Exception("Voucher not found."));
    
        var basePath = new Uri(Request.Url, Url.Content("~/")).ToString();
        var termsLink = new Uri(Request.Url, Url.Action("TermsGC", "Legal")).ToString();
        basePath = basePath.Substring(0, basePath.Length - 1);
    
        var fullName = voucher.FirstName;
        if (!string.IsNullOrEmpty(voucher.LastName))
            fullName += " " + voucher.LastName;
    
        var nvEngine = new NVelocityEngine();
        nvEngine.Context.Add("FullName", fullName);
        nvEngine.Context.Add("MallName", voucher.Mall.Name);
        nvEngine.Context.Add("ConfirmationCode", voucher.ConfirmationCode);
        nvEngine.Context.Add("BasePath", basePath);
        nvEngine.Context.Add("TermsLink", termsLink);
        nvEngine.Context.Add("LogoFilename", voucher.Mall.LogoFilename);
    
        var htmlTemplate = System.IO.File.ReadAllText(
            Request.MapPath("~/App_Data/Templates/Voucher.html"));
    
        return Content(nvEngine.Render(htmlTemplate));
    }
    

提交回复
热议问题