1

I am working on a .NET MVC3 C# Application. This application is hosted on our own Server. Now I want to Send Scheduled Email in my application like daily(at a specific time),Weekly, monthly and so on...

Currently I am using MVCMailer to send Emails in my application.

I tried Fluent Scheduler to send scheduled Emails, but it doesn't works with MVCMailer. It Works fine if I send mails without MVCMailer and for other scheduling jobs.

It gives me a ERROR NULLReferenceException and says HTTPContext cannot be null. What can I do to solve this problem.

Also suggest me which will be the best way to send E-mails in my applicaton.

  1. Windows Service (Having own server)
  2. Scheduler (Fluent Scheduler)
  3. SQL Scheduled jobs

I am attaching ERROR snapshot: enter image description here enter image description here

blue
  • 568
  • 3
  • 10
  • 30

2 Answers2

1

It could be that MVCMailer depends on an HttpContext, which will not exist on your scheduled threadlocal's.

You could consider scrapping MvcMailer and implementing your own templating solution. Something like RazorEngine (https://github.com/Antaris/RazorEngine), which gives you the full power of Razor without having to run ontop on an Http stack. You could still source your templates from disk so that your designers could modify it.

Then you could mail the results using the standard classes available from .net.

For e.g.:

string template = File.ReadAllText(fileLocation);//"Hello @Model.Name, welcome to RazorEngine!";
string emailBody = Razor.Parse(template, new { Name = "World" });

SmtpClient client = new SmtpClient();
client.Host = "mail.yourserver.com";
MailMessage mm = new MailMessage();
mm.Sender = new MailAddress("foo@bar.com", "Foo Bar");
mm.From = new MailAddress("foo@bar.com", "Foo Bar");
mm.To.Add = new MailAddress("foo@bar.com", "Foo Bar");
mm.Subject = "Test";
mm.Body = emailBody;
mm.IsBodyHtml = true;
client.Send(mm);

Obviously you could clean this all up. But it wouldn't take to much effort to use the above code and create some reusable classes. :)

Since you already have the FluentScheduler code set up, you may as well stick with that I guess. A windows service does also sound appealing, however I think that it's your call to make. If it's a simple mail service you are after I can't think of any reason not to do it via FluentScheduler.


I have created a full example of this available here: https://bitbucket.org/acleancoder/razorengine-email-example/src/dfee804d526ef3cd17fb448970fbbe33f4e4bb79?at=default

You can download the website to run locally here: https://bitbucket.org/acleancoder/razorengine-email-example/downloads

Just make sure to change the Default.aspx.cs file to have your correct mail server details.

Hope this helps.

ctrlplusb
  • 12,847
  • 6
  • 55
  • 57
  • I am having trouble with email template... Can u please give a example of template... – blue Dec 20 '13 at 07:47
  • I have created a full example for you. You can download this and run this yourself. Please check the links at the bottom of my answer (Updated above). – ctrlplusb Dec 20 '13 at 13:04
  • Thanks... Its Working... I will try this in an MVC application with Fluent Scheduler... – blue Dec 20 '13 at 13:32
  • @Sean - word of warning, the Razor engine relies on a HttpContext for a good chunk of the Html Helpers and thus, was not helpful in a autogenerated situation when needing to display modal information. We found it best to have a static HTML file with fields such as ##UserName## that we simply do a find/replace on when sending emails. `email = email.Replace("##UserName##", userName); ` You know, taking it old school like the old mail merge templates in Word :) – Tommy Dec 22 '13 at 22:45
  • @Sean What will be equivalent to this in HTMLTemplate as this code is not working `@foreach (var item in Model) { @Html.DisplayFor(modelItem => item.Territory) }` Please Reply – blue Dec 23 '13 at 07:10
0

Since MVC Mailer works best in the HTTP stack (i.e. from controllers), I've found that a very reliable way to accomplish this is by using Windows Task Schedule from a server somewhere. You could even spin up a micro instance on Amazon Web Server.

Use "curl" to call the URL of your controller that does the work and sends the emails.

Just setup a Scheduled Task (or Cron if you want to use *IX) to call "c:\path_to_curl\curl.exe http://yourserver.com/your_controller/your_action".

You could even spin up a *IX server on AWS to make it even cheaper.

coach_rob
  • 877
  • 13
  • 28
  • 4
    This could be bad if Google indexed this page or someone with bad intentions ever came across this URL. Instant DDoS attach by asking to generate tons of emails. There should be additional precautions on this URL if this route is chosen. – Tommy Dec 22 '13 at 22:48