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 31 Dec 2012, 22:57 PM
Tags: Umbraco,MVC