If you want to create a custom form within your Umbraco V8 website then you can make use of the surface controller. The surface controller comes with the core-framework and it will allow you to create forms that post back to a controller without the need of having to mess around with the routing-table.

When working with a surface controller it is best to use it as a component that is contained within a page, rather than apply the surface controller on the page document-type itself. In this example, I will assume you have created a standard page and we will build the form within that page

Contact Us View Model

When we want to move data between the business layer and the presentation layer, we will need a view model to pass this data. For a contact form this view model may look like this:

This controller is split into two actions. The first action will be used to render the custom form. The second action will be used by our form to post data back to the server. Another thing to note in SubmitForm is the ValidateAntiForgeryToken and HttpPost attributes decorated on the action, as well as the use of the IsValid property within the action.

When you define the form it is important that you use the correct get/set attribute. Failing to specify the correct one may result in a 404 when someone tries to submit a form.

ValidateAntiForgeryToken should be used with any .NET form for security. I have omitted the code to process the form, you may want to send an email, or submit the data to Umbraco. After we do the form logic, we can use the TEMPDATA feature to pass information back to the view.

When this pattern we will need to bind the view to a mode. The model will be used to define the properties that will be rendered on the page. The model will also be used to post data back to the server. This model will follow the more standard ASP.NET practice of using annotations. For this tutorial we will use this view model:

You can see it makes use of the Required and MaxLength annotations. There are several more attributes you can use. If you want to learn more you can check out the MSDN page here

The View

The HTML required for the view can be seen below:

The code above is using BeginUmbracoForm set using a POST request. It is using TEMPDATA to pass custom information from the controller into the view. Usually, I would always recommend using a view model to pass this data back. As we are working with Umbraco routing and we are building a component that sits on a page then using normal view models can be more tricker.

Finally, or the containing document-type will need to render the form, this can be done using this snippet:

With this action method, the form should not render on a page!