I'm following this tutorial, to create a Contact Us form using Umbraco and Mvc - and I am a bit puzzled as to why a certain thing works. Specifically, - how does ContactForm (a partial view) both displays the content of the Contact Us page (by the calling of @Html.Action("ShowForm", "ContactSurface")), and also handles the submit button (how does it knows to only call HandleFormPost when the submit button is pressed?)
Here's the view / template for holding the Contact Us webpage.
@inherits Umbraco.Web.Mvc.UmbracoTemplatePage<ContentModels.ContactHolder>
@using ContentModels = Umbraco.Web.PublishedContentModels;
@{
Layout = "Master.cshtml";
}
@Html.Action("ShowForm", "ContactSurface")
Here's the Controller:
public class ContactSurfaceController : Umbraco.Web.Mvc.SurfaceController
{
public ActionResult ShowForm()
{
ContactModel myModel = new ContactModel();
return PartialView("ContactForm", myModel);
}
public ActionResult HandleFormPost(ContactModel model)
{
var newComment = Services.ContentService.CreateContent(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + model.Name, CurrentPage.Id, "ContactFormula");
newComment.SetValue("emailFrom", model.Email);
newComment.SetValue("contactName", model.Name);
newComment.SetValue("contactMessage", model.Message);
Services.ContentService.SaveAndPublishWithStatus(newComment);
return RedirectToCurrentUmbracoPage();
}
}
And here's a partial view for actually displaying the form, and apparently also create the new ContactFormula (a document type for saving contact us submissions - it has emailFrom, contactName and contactMessage in it).
@inherits Umbraco.Web.Mvc.UmbracoViewPage<ProjectDemo.Models.ContactModel>
@using CohensCigarsDemo.Controllers;
@using (Html.BeginUmbracoForm<ContactSurfaceController>("HandleFormPost"))
{
<label for="emailFrom">E-mail</label> @Html.TextBoxFor(x => x.Email, new { @class = "emailFrom", placeholder = "E-mail" })
<br />
<label for="nameFrom">Name</label> @Html.TextBoxFor(x => x.Name, new { @class = "nameFrom", placeholder = "Name" })
<br />
<label for="messageFrom">Message</label>
<br />
@Html.TextAreaFor(x => x.Message, new { @class = "messageFrom", placeholder = "Message" })
<br />
<input type="submit" value="Submit" />
}
Your controller has 2 methods, 1 for showing the form ShowForm
and 1 for the business logic that is executed after the submit button is pressed HandleFormPost
All the routing information is in the following statement
Html.BeginUmbracoForm<ContactSurfaceController>("HandleFormPost")
Html.BeginUmbracoForm is only a wrapper around Razors own Html.BeginForm
with some additional functionality for routing.
The above statement creates something like
<form method="post" action="umbraco/surface/contact/handleformpost">
The forms now routes to the HandleFormPost method in the ContactSurfaceController (this is standard MVC routing). And because of the submit button the browser know what to do after it's clicked
ContactModel
is just a strongly typed object for the fields in your form and with some MVC magic the fields are automatically maped to a ContactModel
object when the form is submitted and based on this model the new umbraco documenttype is created using Services.ContentService.CreateContent
For more explanation on creating a form using MVC, check out this article