2

I have contact form that logs a serialized version of a contact model to a database and sends an email with the form data. Between the two actions, it takes up to 2 seconds to complete. Although not a lot of time, it is enough to annoy impatient users.

Contact Controller:

public class ContactController : Controller
    {
        // GET: Contact
        public ActionResult Index()
        {
            return View();
        }

        // Post: /Contact/
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Index(Models.ContactModel contact)
        {
            if (ModelState.IsValid)
            {

                XmlSerializer xmlSerializer = new XmlSerializer(contact.GetType());
                using (StringWriter textWriter = new StringWriter())
                {
                    xmlSerializer.Serialize(textWriter, contact);
                    Log.Create("email", textWriter.ToString());
                }

                Smtp.sendMail(sendTo, contact.Email, contact.Name, subject, contact.Comment,
                              ipAddress, senderEmail, contact.Phone, sendBcc);

                // using RedirectToRoute instead of RedirectToAction so that /contact is used.
                return RedirectToRoute("Default", new { action = "contactsucess", controller = "contact" });
            }

            // Return Form if not valid
            return View(contact);
        }

        // GET: /Contact/ContactSucess
        public ActionResult ContactSucess()
        {
            ViewBag.IsContactPage = true;

            return View();
        }
    }

What is the best approach to make serializing, logging and STMP logic asynchronous to the controller returning the success/thank you page. Basically my goal is to prevent those calls from blocking the overall progress so that the form completes faster.

5
  • make email sending code async Commented Jul 27, 2014 at 16:02
  • Which part of this is slow? Look to making that more efficient. I'm guessing the Smtp.SendMail is where the time is spent, if so, @EhsanSajjad is right. Commented Jul 27, 2014 at 16:16
  • Email is the slowest part. I was hoping to implement a wrapper around the logic that makes the calls. Commented Jul 27, 2014 at 16:19
  • 1
    stackoverflow.com/questions/3408397/… Commented Jul 27, 2014 at 16:26
  • Using the smtpClient.SendMailAsync method doesn't improve the time. Commented Jul 27, 2014 at 21:39

1 Answer 1

4

The common solution in my working experience is to move the emailer to another process.

The web server communicates to the emailer via messaging bus such as MSMQ, NServiceBus or RabbitMQ. When the web server wants to send an email, it sends a message to the emailer which does the actual email sending.

Sign up to request clarification or add additional context in comments.

4 Comments

Yes - And if you can run on Azure, look at Azure Web Jobs as a way to implement these out of process batch operations. Adding a link to Hanselman's blog hanselman.com/blog/IntroducingWindowsAzureWebJobs.aspx
I was thinking of a queue, but it seemed like overkill for sending an email.
It is not an overkill, it is the way it should be done. You can probably use MSMQ and a Windows service in the same machine than your web server.
I'm using an Azure Web Site, so I'm going to try to implement using a Queue and an Azure WebJob.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.