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
Post a comment
Sit tight...
We're adding your comment.
Thank you.
Your comment has been added.
There's been a problem.
Please try again later.
Share with
Tags
Latest Comments
By PS on Replacing the Xamarin Header/Navigation bar with a custom view/template
16 Apr 2018, 07:53 AM
By Srusti Thakkar on How to add a Xamarin Forms Loading Screen/Overlay
27 Mar 2018, 18:22 PM
By Luke on How to add a Xamarin Forms Loading Screen/Overlay
23 Mar 2018, 15:03 PM
By Srusti Thakkar on How to add a Xamarin Forms Loading Screen/Overlay
23 Mar 2018, 13:16 PM
By Marco Teodoro on Custom section tree nodes and routes - Umbraco
21 Mar 2018, 11:08 AM
By ttt asd on Limit Google Autocomplete results to country and city
20 Mar 2018, 11:53 AM
By hamid on Limit Google Autocomplete results to country and city
19 Mar 2018, 21:13 PM
By matt on Auto/Custom height on Xamarin Forms WebView for Android and iOS
17 Mar 2018, 02:18 AM
Categories
App Development
Event
Game Development
Mapping
Modelling
Programming
Review
Robotics
Tutorial
Web Development