8

I am working on a web application that will be going live soon, and I am now trying to figure out the best way for handling sending email from the application. I understand completely HOW to send email from the application using the MailMessage and SmtpClient classes, however my question is from a different angle. My main purpose at my job before this project was support of old applications that had been developed before my time. In these applications, when they needed to send email, they hard coded any of the messages into the actual message with all of the HTML tags embeded directly into the C# code.

The application that I am working on will have a template for the emails to be sent in, as a sort of styling container, and the different messages will be embeded into the main content div's of the template. I would like to avoid hardcoding these templates in this application, so I have been trying to figure out the best way to layout my project. I have thought of using a t4 template, and reading the different t4's into the application and applying a String.Format with the specified parameters to add names/emails to the messages to be sent. However, I am not sure this is the best way to do it.

My other idea was to define a class for each type of message, however this would end up hardcoding messages again, which as I said I don't want to do.

My question is, how have you approached this in the past? What worked, and what didn't and for what reasons? I have looked all over online, but either the only content out there is on HOW to send the message, or I have not used the right Google power words.

tostringtheory
  • 877
  • 8
  • 19
  • Do you have access to a database? You could store each type of message, the recipients, subject, body, etc in a database and build a simple maintenance routine on top of it. You can also enter various tags inside the email body to act as placeholders for other text (like a user's name). I've done this before and it works reasonably well. – hawkke Dec 19 '11 at 00:59
  • The application does have a database, and this is one of the things that I had actually considered doing. I was kind of wary about doing this at first, as I wasn't sure that the messages should be stored in the database, but it is definetly a pro that the message can be updated at any time. The recipients are also currently stored in the database as well. Thanks for the input, and I will definetly consider it more now that I know someone else has done it well. I still wonder though whether or not there is a better way. – tostringtheory Dec 19 '11 at 01:06
  • What have you tried on your own thus far in regards to chat code do you have so that someone on line here can see and possibly help you..? Depends on what you are really looking for sending email is not a difficult task since .NET provides you with a lot of options using System.Net.Mail or via Web Application using System.Web.Mail there a a lot of previous examples as well that you can search and research on this site or checkout codeproject.com lots of great examples – MethodMan Dec 19 '11 at 00:49
  • 1
    Mainly all of the code has just been in my head. I want to get an idea on the best way to do this before I devote alot of time coding it. I have already been trying to research this for several hours now. I don't need hand holding on how to do it, just on what should be done. The ideas I had come up with so far are in my question, but as I said, I am not sure that is the best way to approach the problem. – tostringtheory Dec 19 '11 at 00:51

2 Answers2

2

I do it this way:

  • Code it the usual way with ViewModel and Razor Template
  • By creating the e-mail, use http://razorengine.codeplex.com/ to load and parse the template
  • Be aware to not use Html and Url helper if you want to send e-mails in a thread, because they rely on HttpContext which you don't have in that case. Build your own helpers if needed.

For example, if you have a ViewModel Car in your application which is displayed somewhere, you could also use this ViewModel as @model in a Razor Template for e-mail.

Marc
  • 6,749
  • 9
  • 47
  • 78
  • Thanks for the link. This is definetly closer to what I was looking for in a way. Am I correct in assuming that you have the template as an actual separate file, or are you hard coding it in as they show on their home page? – tostringtheory Dec 19 '11 at 01:17
  • Of course no hard coding, for each e-mail I have one cshtml file. So you would be able to use this as an e-mail preview in your application too. – Marc Dec 19 '11 at 01:28
  • Hmmm.. This is a definite plus to be able to preview a message. I seriously like the idea of this functionality. – tostringtheory Dec 19 '11 at 01:30
  • And you could have a look at [MvcMailer](https://github.com/smsohan/MvcMailer/) where this has been built already. But I think you are maybe not able to send the mails in a thread with that. – Marc Dec 19 '11 at 01:34
  • I had considered this, but was wary about using this, as I will be sending the emails from the service side of the application, not the web application side itself. This site will end up running on Windows Azure, so I want to minimize the passing back and forth of the emails\users informations between the service and the web site to do the sending. This is one of the reasons that storing the email in the database sounds nice - updating the application can be a long process. – tostringtheory Dec 19 '11 at 01:40
  • I would never do any application logic in the database because that's just a place to store the data. You should be able to drop the database and start again without loosing application code, otherwise you are chained. But that's a point where programmers start to discuss :) Where do you do the break? Why not loading the whole application code in the DB and execute it so you can update it more easily... know what I mean? :) – Marc Dec 19 '11 at 02:36
  • Btw if you just update the Razor templates, you don't have to restart your application. – Marc Dec 19 '11 at 02:38
  • Doesn't redeploying the application effect everything, or does Azure do a comparizon to determine that only the cshtml pages changed? Thanks for the input too, I am still new to programming in a junior level job, but what I learn, I want to learn it well, and hopefully the right way. Then again, in many cases the 'right' way can be subjective, as you mentioned. – tostringtheory Dec 19 '11 at 02:46
0

I've had to do this on a couple of occasions. I originally used the ASP.Net template engine based on I think a Rick Strahl blog post. It worked but there was always some issue I was banging my head against.

I switched to using the NVelocity template engine and found it a really simple way to create and maintain email templates. There are a number of other template engines and I suspect next time I might have a serious look at the Razor engine.

The code for merging values into the template:

private string Merge(ManualTypeEnum manualType, Object mergeValues)
{
    var body = "";
    var templateFile = string.Format("{0}MailTemplate.vm", manualType);
    var velocity = new VelocityEngine();
    var props = new ExtendedProperties();
    props.AddProperty("file.resource.loader.path", Config.EmailTemplatePath);
    velocity.Init(props);
    var template = velocity.GetTemplate(templateFile);
    var context = new VelocityContext();
    context.Put("Change", mergeValues);
    using (var writer = new StringWriter())
    {
        template.Merge(context, writer);
        body = writer.ToString();
    }
    return body;
}

The values to merge are passed as an anonymous object, and can include various types including lists etc e.g.

var emailBody = Merge(newDocument.ManualType, new
{
    ManualType = newDocument.ManualType.ToString(),
    Message = change.Message,
    NewTitle = newDocument.Title ?? "",
    NewVersion = newDocument.Version ?? "",
    Contact = From,
    Changes = change.ToList(),
});
Community
  • 1
  • 1
David Clarke
  • 12,888
  • 9
  • 86
  • 116
  • Hmm.. Looks like I can do this with a file, but I may look at combining the Razor engine with the database, to get the information from a datarow, then transform it. What about separation of concerns? Do you think this would be mixing them too much? – tostringtheory Dec 19 '11 at 01:24
  • It's all about context. The app that uses the above code was old and crufty by the time I got to it and using a database to store templates would have been overkill for the volume/complexity of the emails being sent. Consider a template is just a string then you can store that string in a file or a database, whichever makes sense for your app. One of the benefits of using Razor templates is the Visual Studio support so you will get syntax colouring etc. If you store them in a database you are adding a couple of extra steps whenever you want to modify them, i.e. extract, change, update. – David Clarke Dec 19 '11 at 01:46
  • Very true. However storing it in the database would probably end up being easier in my situation. I can of course have the file on my pc, and update db through code when needed. It takes forever to deploy a change to azure, and I would be hesitant to redeploy for only a small change such as that. – tostringtheory Dec 19 '11 at 02:05