How to create a Contact Form in Umbraco using MVC and C#

Posted written by Paul Seal on October 21, 2016 Umbraco

YouTube Video Tutorial

This post is to accompany the YouTube video tutorial I created. I will share the code I wrote for each section in the video.

1. Create the Contact template

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage
@{
    Layout = "Master.cshtml";
}

2. Create the Contact document type

3. Associate the Contact template with the Contact document type

4. Create a Model to receive the data

using System.ComponentModel.DataAnnotations;

namespace InstallUmbraco.Models
{
    public class ContactModel
    {
        [Required]
        [Display(Name ="First Name:")]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = "Last Name:")]
        public string LastName { get; set; }

        [Required]
        [EmailAddress]
        [Display(Name = "Email Address:")]
        public string EmailAddress { get; set; }

        [Required]
        [Display(Name = "Message:")]
        public string Message { get; set; }
    }
}

5. Create a Controller with a method to Render the form

using Umbraco.Web.Mvc;
using System.Web.Mvc;
using InstallUmbraco.Models;
using System.Net.Mail;

namespace InstallUmbraco.Controllers
{
    public class ContactSurfaceController : SurfaceController
    {
        public const string PARTIAL_VIEW_FOLDER = "~/Views/Partials/Contact/";

        public ActionResult RenderForm()
        {
            return PartialView(PARTIAL_VIEW_FOLDER + "_Contact.cshtml");
        }
    }
}

6. Add a method to the controller to Submit the form and send an email

using Umbraco.Web.Mvc;
using System.Web.Mvc;
using InstallUmbraco.Models;
using System.Net.Mail;

namespace InstallUmbraco.Controllers
{
    public class ContactSurfaceController : SurfaceController
    {
        public const string PARTIAL_VIEW_FOLDER = "~/Views/Partials/Contact/";
        public ActionResult RenderForm()
        {
            return PartialView(PARTIAL_VIEW_FOLDER + "_Contact.cshtml");
        }

        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult SubmitForm(ContactModel model)
        {
            if(ModelState.IsValid)
            {
                SendEmail(model);
                TempData["ContactSuccess"] = true;
                return RedirectToCurrentUmbracoPage();
            }
            return CurrentUmbracoPage();
        }

        private void SendEmail(ContactModel model)
        {
            MailMessage message = new MailMessage(model.EmailAddress, "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7c0b191e0f1508193c15120f081d101009111e0e1d1f13520b191e5210131f1d10">[email&#160;protected]</a>");
            message.Subject = string.Format("Enquiry from {0} {1} - {2}", model.FirstName, model.LastName, model.EmailAddress);
            message.Body = model.Message;
            SmtpClient client = new SmtpClient("127.0.0.1", 25);
            client.Send(message);
        }
    }
}

7. Create a partial view for the Contact form

@inherits UmbracoViewPage<InstallUmbraco.Models.ContactModel>

@using (Html.BeginUmbracoForm("SubmitForm", "ContactSurface", FormMethod.Post))
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.ValidationSummary()
    </div>

    <div class="form-group">
        <div class="col-xs-3">
            @Html.LabelFor(m => m.FirstName)
        </div>
        <div class="col-xs-9">
            @Html.TextBoxFor(m => m.FirstName)
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-3">
            @Html.LabelFor(m => m.LastName)
        </div>
        <div class="col-xs-9">
            @Html.TextBoxFor(m => m.LastName)
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-3">
            @Html.LabelFor(m => m.EmailAddress)
        </div>
        <div class="col-xs-9">
            @Html.TextBoxFor(m => m.EmailAddress)
        </div>
    </div>

    <div class="form-group">
        <div class="col-xs-3">
            @Html.LabelFor(m => m.Message)
        </div>
        <div class="col-xs-9">
            @Html.TextAreaFor(m => m.Message)
        </div>
    </div>
    <button>Submit</button>
}

8. Add the form to the Contact template

@inherits Umbraco.Web.Mvc.UmbracoTemplatePage

@{
    Layout = "Master.cshtml";
}

<div class="container">
    @if (TempData["ContactSuccess"] != null &amp;&amp; (bool)TempData["ContactSuccess"])
    {
        <p>Your message was sent successfully</p>
    }
    else
    {
        Html.RenderAction("RenderForm", "ContactSurface");
    }
</div>

9. Create a Contact page using the Contact document type

10. Demonstrate PaperCut for testing emails

https://papercut.codeplex.com/

Papercut allows you to you test emails without the need for a physical SMTP server.

11. Test it works