Custom MVC Models and Controllers in Umbraco 7 and 8

Image of Stephen Garside Stephen Garside | Sun 03 Nov 19 > 3 min read

One of the great things about Umbraco 7 is the ability to create your own custom MVC controllers and models. In this article I am going to show you how to create a basic Contact form using MVC, C# and Umbraco 7.

First off you will need an MVC Controller to handle the incoming gets and posts.  In my example I have created a base controller to handle the calls to Umbraco so I can re-use the code for other controllers I may wish to create.  This base controller inherits PluginController - a base class provided by Umbraco.

using Examine;
using System;
using System.Linq;
using Umbraco.Core.Models;
using Umbraco.Web;
using Umbraco.Web.Mvc;
 
namespace Website.Controllers
{
    /// <summary>
    /// Base Controller
    /// </summary>
    public class BaseController : PluginController
    {
        /// <summary>
        /// Base Controller Constructor
        /// </summary>
        public BaseController()
            : this(UmbracoContext.Current)
        {
        }
 
        /// <summary>
        /// Base Controller Constructor
        /// </summary>
        /// <param name="umbracoContext">Umbraco Context</param>
        public BaseController(UmbracoContext umbracoContext)
            : base(umbracoContext)
        {
        }
 
        /// <summary>
        /// Get Published Content
        /// </summary>
        /// <param name="nodeName">Node Name</param>
        /// <returns>Published Content</returns>
        public IPublishedContent GetPublishedContent(string nodeName)
        {
            if (nodeName == null)
            {
                throw new ArgumentNullException("Node Name");
            }
 
            return Umbraco.TypedSearch(nodeName).First();
        }
    }
}
 

The next step is to create your Contact controller to handle the gets and posts. This new controller will inherit from your Base controller so you can utilise the GetPublishedContent method to search for Umbraco content. 

using System;
using System.Web.Mvc;
using Website.Models;
using Website.Models.Email;
 
namespace Website.Controllers
{
    /// <summary>
    /// Contact Controller
    /// </summary>
    public class ContactController : BaseController
    {
        /// <summary>
        /// Get Contact View
        /// </summary>
        /// <returns>Contact View</returns>
        [HttpGet]
        [Route("contact", Name = "Contact")]
        public ActionResult Contact()
        {
            return View("~/Views/Contact.cshtml",
                new ContactModel(GetPublishedContent("Contact")));
        }
 
        /// <summary>
        /// Post Contact View
        /// </summary>
        /// <param name="model">Contact Post Model</param>
        /// <returns>Redirect to Thankyou or Error</returns>
        [HttpPost]
        [Route("contact", Name = "ContactPost")]
        public ActionResult Contact(ContactPostModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    var emailModel = new ContactUsEmailModel()
                    {
                        EmailAddress = model.Email,
                        Name = model.Name,
                        Message = model.Message,
                        ContactDateTime = DateTime.Now
                    };
 
                    new EmailController().ContactUsEmail(emailModel).Send();
 
                    return RedirectToRoute("ContactThanks");
                }
                catch (Exception ex)
                {
                    // Somethings gone wrong
                    ModelState.AddModelError(
                        string.Empty, "Sorry, an error occurred, please retry");
                }               
            }
 
            return View("~/Views/Contact.cshtml",
                new ContactModel(GetPublishedContent("Contact")));
        }
 
        /// <summary>
        /// Get Contact Thanks View
        /// </summary>
        /// <returns>Contact View</returns>
        [HttpGet]
        [Route("contact/thankyou", Name = "ContactThanks")]
        public ActionResult ContactThanks()
        {
            return View("~/Views/ContactThanks.cshtml",
                new GeneralModel(GetPublishedContent("ContactThanks")));
        }
    }
}

So, lets have a look in a little more detail at our Get method first of all:-

/// <summary>
/// Get Contact View
/// </summary>
/// <returns>Contact View</returns>
[HttpGet]
[Route("contact", Name = "Contact")]
public ActionResult Contact()
{
     return View("~/Views/Contact.cshtml",
     new ContactModel(GetPublishedContent("Contact")));
}

The first thing is to define your route - this is done by implementing MVC5 Attribute Routing for Umbraco 7.

We then initialise a new custom mvc model (called Contact model) that will be used to build and validate the view. The constructor for the Contact model takes the Umbraco published content for the Contact page (which you need to create in your instance of Umbraco) e.g.

Leave Your Comments...