MVC forms in Umbraco

I've had a lot of trouble working out how to create forms in Umbraco because a lot of the documentation around is either for an old version of Umbraco, using a third party library or just not very helpful!

I've finally found out the trick when working with MVC and surface controllers, and it's very simple once you get to know it, it's definately not as hard a lot of tutorials make it seem.

To get your form working you're going to need to know what a controler is and what it does, so if you don't it's basically an area of code that handles every thing for your forms actions, think of it as the .cs file behind a user control.

For the purpose of this tutorial, I'll show you how to create a comment form, so we're going to start off with creating a partial view in the 'Partials' folder within the 'Views' folder, we'll then add the basic code needed to render the form and link it to a custom surface controller that we'll create in the 'App_Code' folder.

Step 1: Create the partial

Create a partial view in the 'Partials' folder located under the 'Views' folder and name it 'ContactForm' this will be where the GUI part of the form is located, it'll also be what's called from our view page to render the form.

Step 2: Adding the form

To create forms in MVC you can use a neat way of adding elements instead of writing the HTML, for example we can use 'LabelFor', 'EditorFor' and 'ValidationMessageFor' pretty neat right? All of these are preceded by '@Html.' because they're located under the 'Html' class.

See my example below and paste it into a partial view called 'CommentForm' to get started.

@inherits Umbraco.Web.Mvc.UmbracoViewPage
@{
    Layout = null;
}

@using (Html.BeginUmbracoForm("SubmitComment", "CommentFormSurface"))
{
  @Html.LabelFor(x => Model.Name)
  @Html.EditorFor(x => Model.Name)
  @Html.ValidationMessageFor(x => Model.Name)

  @Html.LabelFor(x => Model.Email)
  @Html.EditorFor(x => Model.Email)
  @Html.ValidationMessageFor(x => Model.Email)

  @Html.LabelFor(x => Model.Comment)
  @Html.EditorFor(x => Model.Comment)
  @Html.ValidationMessageFor(x => Model.Comment)
}

This is esseintially the form that people will see and use on our website, it is linked to a model and controller which we will create in step three by means of an inherits statement in the first line which calls the 'CommentFormModel'.

 

Step Three: Setting up the model and controller

To create the model and controller, you need to create a new class file in the 'App_Code' folder and call it 'CommentController', within this file, you'll add the model and surface controller for your form, copy and paste the below code into the class file to get started.

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Web;
using System.Web.Mvc;
using Umbraco.Web.Mvc;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;

namespace LukeAlderton
{
    /// 
    /// Comment form controller deals with all comment systems
    /// 
    public class CommentFormSurfaceController : SurfaceController
    {
        [HttpPost]
        public ActionResult SubmitComment(CommentFormModel model)
        {
            //model not valid, do not save, but return current umbraco page
            if (!ModelState.IsValid)
            {        
                return CurrentUmbracoPage();
            }

            // Create the comment and add then data then publish it
            User author = new User(0);
            Document comment = Document.MakeNew(model.Name, DocumentType.GetByAlias("uBlogsyComment"), author, CurrentPage.Children.First().Id);
            comment.getProperty("uBlogsyCommentName").Value = model.Name;
            comment.getProperty("uBlogsyCommentEmail").Value = model.Email;
            comment.getProperty("uBlogsyCommentWebsite").Value = model.Website;
            comment.getProperty("uBlogsyCommentMessage").Value = model.Comment;
            comment.Publish(author);
            umbraco.library.UpdateDocumentCache(comment.Id);

            // Add date to the page
            //TempData.Add("SubmissionMessage", "Your comment was successfully submitted");

            // Redirect to current page to clear the form
            return RedirectToCurrentUmbracoPage();

            // Redirect to specific page
            //return RedirectToUmbracoPage(2525);
        }
    }

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

        [Required]
        [RegularExpression(@"^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6}$", ErrorMessage = "Invalid Email Address")]
        public string Email { get; set; }

        [DataType(DataType.Url)]
        public string Website { get; set; }

        [Required]
        [DataType(DataType.MultilineText)] 
        public string Comment { get; set; }
    }
}

This controller is designed to replace the comment function of the uBlogsy comment system which adds a node under the post, within the comments node.

The top class called 'CommentFormSurfaceController' is the surface controller and it handles everything that happens after the form has been submitted, in our case we call the method 'SubmitComment' to add a comment to the post via it.

The lower class called 'CommentFormModel' is our view model and it handles the variables available to us and what they should be displayed as, this model has four variables which can all be accessed via 'model.variablename'.

Step Four: Using the form

To Use the form you simply add the following line into any view in your website:

@Html.Partial("CommentForm",new LukeAlderton.CommentFormModel())

It's as simple as that!

Also note that you can't have a form surrounding your whole page when using this because the form will just post the data as a querystring.


Published at

Tags: Umbraco,MVC

Luke Alderton

Comments

Connie
Why do you have the TempData line commented out? I am struggling with an issue where I can only get the TempData value to display in the partial that contains the form. It will not display on the parent view, even though that is the next http request.
22/04/2015
Luke
Connie, TempData is commented out because it's an option if you want to display some custom text when the page reloads. Have you read the TempData value? You can call TempData.Keep("somekeyname"); To make sure it is kept next time it's been read.
22/04/2015
Sumit
BeginUmbracoForm this is an error i am facing again and again in view/partial how to resolve it(System.Web.WebPages.Html.HtmlHelper' does contain defination for BeginUmbracoForm and no extention method 'BeginUmbracoForm' accepting a .....etc
26/07/2016
Person
Howdy! Do you know if they make any plugins to protect against hackers? I'm kinda paranoid about losing everything I've worked hard on. Any tips?
27/04/2019
Share with
Tags
Latest Comments
By Mark Gentry on Windows Server 2019 - Change product key does nothing
20 Aug 2021, 03:30 AM
By Cathy on In-Place Upgrade for a Windows Server domain controller
31 Jul 2021, 18:28 PM
By Mr. Greymatter on Raspberry Pi - Running Java app on Raspbian
16 Feb 2021, 07:35 AM
By Mikko Seittenranta on Xamarin Forms multiple instances of same app open
16 Feb 2021, 04:34 AM
By Andrew on Auto/Custom height on Xamarin Forms WebView for Android and iOS
22 Jan 2021, 22:15 PM
By Nick on Raspberry Pi - Running Java app on Raspbian
14 Oct 2020, 19:37 PM
By Ivan on Fixed: Value cannot be null Parameter Name: source
15 Sep 2020, 19:47 PM
By Anand on Raspberry Pi - Bluetooth using Bluecove on Raspbian
7 Sep 2020, 16:53 PM
Categories
App Development
Event
Game Development
Mapping
Modelling
Programming
Review
Robotics
Tutorial
Web Development