Mar 4, 2016
(4 votes)

Posting Forms with Episerver MVC

In my previous post, I briefly discussed Episerver MVC support and included a few examples on how to implement it in a project. In this post, I’m going to talk about a functionality usually required by almost all web sites: forms. Episerver provides tools to editors to build forms (Episerver form add-on). But most of the time, specific forms that shouldn’t be modified by editors are desired. This post focuses on how to build these kinds of forms.

For the following example, we are going to implement a form as an Episerver block. This will allow you to drop the form in any page with a suitable container.

First of all, we need to create a base class for any Form models. This base class will contain basic data such as the current page link, current block link, current language and the form’s parent block. We’ll see later the use of these fields.

Image codeB1.png

Before we create our form model, let’s first create the Block Type. For this example, it will only have one content field that will contain the form’s title.

Image codeB2.png

Now we can create the form model. This will follow the same standard MVC patterns for forms, except that the model class will inherit from the Base Form Model class.

 Image codeB3.png

We are using a simple Form Model for this example, with required fields for Name and Email, and a Regular Expression validator for the Email field.

Next, we have to create the Form Controller. We’ll create a Base Form Controller with the methods we’ll reuse in any Form Controller. When we do a Post in a form, we’ll be losing the Episerver Context information. These methods will help keep the Episerver Context temporarily in the TempData store, and merge it back to the ViewData when returning to the Episerver page after the submission.

Image codeB4.png

Now we can create our Form Controller. It will have a standard Index action that will display the form. Additionally, it will have a Submit action to handle the data submission from the form.

Image CodeB5.png

Let’s analyze the code of this controller. In the index action method, we get the current block content link in Episerver. The ID of the block will be used as part of the key in the TempData store. If the action was called after a form submission, the submit action would have stored the Episerver Context by using the SaveModelState() method. So the LoadModelState() method call would, at this point, merge the previous model state into the current one in order to maintain consistency and be able to show validation messages when something is not entered correctly by the user. When creating the form model, we store the current page link, the current block link, the language and the current block reference. In case this is a redirect from a posted form, if everything is valid, the partial view to display will be the one named “Success”. Otherwise, the default “index” view will be displayed.

For the submit action, it will first get the return URL for the page (it will come from the hidden fields in the view that will contain the page data). If the data entered by the user is valid (Model.IsValid), then it will process your data, and add to the Return URL the “form posted” flag with the Block ID. It will save the Model State into the TempData store (using the SaveModelState() call) and redirect the call to the return URL. When redirected to the return URL, it will process the block through the normal Index action and follow the steps described before.

We need 2 Views for this block. One contains the form presentation, and the other the “Thank you” message. Both will reside under \Views\TestForm. This is the main form view (Index.cshtml):

Image CodeB6.png

As you can see, the ParentBlock is referenced to get the title field from the block. Field properties are accessed directly from the model. You can also see that the BeginForm method references to the “Submit” action. Our Success page will be a very simple “Thank you” static page (Success.cshtml):

Image thankyoucodeB.png

Before we deploy this to Episerver, make sure to include the following in your Global.asax code behind:

Image CodeB7.png

 This will register the submit route for your forms. In the Page Type, make sure you have a property to contain the Form block (FormArea in this example):

Image CodeB8.png

Also, in your Views, make sure to register in your layout the section for the block:

Image CodeB9.png

And in the view that will contain the form:

Image CodeB10.png

Build and deploy your project. Register your new block, and use it in your page.

To get updated about on more of my posts, follow us on Twitter @Oshyn_Inc, or register for our email list at http://oshyn.com/resources/blog.html  and check out our website as well!

Mar 04, 2016


valdis Mar 8, 2016 01:24 PM

Is BeginForm("Submit", null) really generating you *the* correct form action (to actual page address and not underlying controller address generated by Mvc)?

Jonathan Roberts
Jonathan Roberts Jun 22, 2017 10:51 AM


Thanks for the post but when I post the form I get a 404 error 

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that it is spelled correctly. 

Requested URL: /testform/submit/

Any ideas?

Chris Mulvey
Chris Mulvey Nov 17, 2017 04:11 PM

Hunted, and hunted...then even hunted some more for good documentation and sample source on creating your own FormContainerBlock, and FormContainerBlockControllers, etc. and NOTHING! (Well, very, very little and everone complaining abut how difficult it is) Then I found this post and it filled in the final gaps and lead me in the right directoin re: adding TempData t oDataSubmitController and extracting it into the ViewBag in EPIServer built in ascx form container view. At Last!...Many Thanks.

Seems lots of people are trying to get this together - maybe EPiServer could beef up their documentation with some working models?

Please login to comment.
Latest blogs
Optimizely finally releases new and improved list properties!

For years, the Generic PropertyList has been widely used, despite it being unsupported. Today a better option is released!

Tomas Hensrud Gulla | Mar 28, 2023 | Syndicated blog

Official List property support

Introduction Until now users were able to store list properties in three ways: Store simple types (int, string, DateTime, double) as native...

Bartosz Sekula | Mar 28, 2023

New dashboard implemented in CMS UI 12.18.0

As part of the CMS UI 12.18.0 release , a new dashboard has been added as a ‘one stop shop’ to enable editors to access all of their content items,...

Matthew Slim | Mar 28, 2023

How to Merge Anonymous Carts When a Customer Logs In with Optimizely Commerce 14

In e-commerce, it is common for users to browse a site anonymously, adding items to their cart without creating an account. Later, when the user...

Francisco Quintanilla | Mar 27, 2023

How to Write an xUnit Test to Verify Unique Content Type Guids in Content Management

When developing an Optimizely CMS solution, it is important to ensure that each content type has a unique GUID. If two or more content types share...

Minesh Shah (Netcel) | Mar 27, 2023

Extend TinyMCE in Optimizely CMS 12

Since technologies are upgraded to newer versions the ways to extend or override the out-of-the-box functionality are also changed a little bit so...

Ravindra S. Rathore | Mar 27, 2023 | Syndicated blog