In Umbraco5, Surface Controller is very interesting topic that everyone should know about this. Today I was digging with Umbraco 5.2 Beta version and successfully created my first surface controller which handle the contact form.
Surface controller is important because who one is move from Umbraco 4.7 to Umbraco 5.x then surely they looking for User Control macro stuff.
Surface Controller perform majorly 3 task:
1) Work with View-Model OR Data
2) If you want to render a partial view using View-Model
3) If you wan to submit any form
Find below steps, how to create a Contact Form using Surface Controller in Umbraco 5
Step-1 : First Create a Contact View-Model class
————————————————-
using System.ComponentModel.DataAnnotations;
namespace Site.Extensions.ViewModel
{
public class ContactViewModel
{
[Required(ErrorMessage = “Please enter your name”)]
public string Name { get; set; }
[Required(ErrorMessage = “Email address required”)]
[RegularExpression(@”[a-zA-Z0-9!#$%&’*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&’*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?”, ErrorMessage = “Please enter a valid e-mail address”)]
public string Email { get; set; }
[Required(ErrorMessage = “Please enter your phone number”)]
public string PhoneNo { get; set; }
[Required(ErrorMessage = “Please enter a subject”)]
public string Subject { get; set; }
[Required(ErrorMessage = “Please enter a message”)]
[DataType(DataType.MultilineText)]
public string Message { get; set; }
public bool SubmitHandled { get; set; }
}
}
———————————————————
Step-2 Create Surface Controller class which handle contact form and render the contact form
//Note: First take reference of Umbraco.Cms.Web dll which is present under Umbraco Bin folder
—————————————————-
using Umbraco.Cms.Web.Context;
using Umbraco.Cms.Web.Surface;
using System.Web.Mvc;
using Site.Extensions.ViewModel;
using Umbraco.Web.Classes;
namespace Umbraco.Web.Controllers
{
//Note: All surface controller class should be inherited with “SurfaceController” class
// and should be postfix with “SurfaceController” other wise when you will create child action macro then this
// class will not able to populate under drop downlist
public class ContactFormSurfaceController : SurfaceController
{
private readonly IUmbracoApplicationContext context;
private const string FormSentKey = “ContactFormSent”;
public ContactFormSurfaceController(IUmbracoApplicationContext context)
{
//If you want to access current page data then you can use this object
//but in that can case you have to pass Hive id from partial view using “Model.Id”
context = context;
}
//ChildActionOnly annotation is required for rendering the view and return type be PartialViewResult
[ChildActionOnly]
public PartialViewResult RenderContactForm()
{
//Create your model view class as created above
var model = new ContactViewModel();
//This code block is basically used to show the confirmation message on page that email send successfully
etc.
var formSent = TempData[FormSentKey];
if (formSent != null && bool.Parse(formSent.ToString()))
model.SubmitHandled = true;
return PartialView(“contactFormRender”, model);
//PartialView takes two parameters first one is your partial view name and second one is your model class
object
}
//HttpPost annotation is required for handling your contact form submit.
[HttpPost]
public ActionResult SendContactForm(ContactViewModel model)
{
//Check if submitted form is valid
if (!ModelState.IsValid)
return CurrentUmbracoPage(); //If any error occurred then stick with current form
//Send email
EmailManager.Send(model);
//This flag value used in RenderContactForm method to show the confirmation message
TempData[FormSentKey] = true;
return RedirectToCurrentUmbracoPage(); //Redirect to current form. Note: You redirect to other page too
}
}
}
———————————————
Step-3 : Login in Umbraco back office and go to Setting section. Under Partial folder, create a partial page
————————————————
@model Site.Extensions.ViewModel.ContactViewModel
//Note: BeginUmbracoForm first two parameter is very important:
// First one: give the Surface Controller httppost handler name. In our case is "SendContactForm"
// Second one: Surface Controller name
// see controller class
:@
@using (Html.BeginUmbracoForm(“SendContactForm”, “ContactFormSurface”, null, new Dictionary { { “class”, “validate-form” } }))
{
@Html.ValidationSummary(true)
Contact Form
@Html.LabelFor(model => model.Name)
@Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name)
@Html.LabelFor(model => model.Email)
@Html.EditorFor(model => model.Email) @Html.ValidationMessageFor(model => model.Email)
@Html.LabelFor(model => model.PhoneNo)
@Html.EditorFor(model => model.PhoneNo) @Html.ValidationMessageFor(model => model.PhoneNo)
@Html.LabelFor(model => model.Subject)
@Html.EditorFor(model => model.Subject) @Html.ValidationMessageFor(model => model.Subject)
@Html.LabelFor(model => model.Message)
@Html.TextAreaFor(model => model.Message) @Html.ValidationMessageFor(model => model.Message)
input type=”submit” value=”Send Email”
}
@if (Model.SubmitHandled)
{
Thanks, we’ll get back to you soon.
}
———————————————–
Note: after above steps, please build the project so you will get Surface Controller class under the macro.
Step-4 : Go to Developer section in umbraco back office then under macro node create a macro as
You done all steps and your form will start working.
Please let me know if found any issue.