Taylor_Oshyn
Mar 4, 2016
  12553
(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

Comments

valdis
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

Hi,

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
Introducing Optimizely Graph Source .NET SDK

Overview Of Optimizely Graph Optimizely Graph is a cutting-edge, headless content management solution designed to integrate seamlessly with any...

Jake Minard | Oct 10, 2024

Content Search with Optimizely Graph

Optimizely Graph lets you fetch content and sync data from other Optimizely products. For content search, this lets you create custom search tools...

Dileep D | Oct 9, 2024 | Syndicated blog

Omnichannel Analytics Simplified – Optimizely Acquires Netspring

Recently, the news broke that Optimizely acquired Netspring, a warehouse-native analytics platform. I’ll admit, I hadn’t heard of Netspring before,...

Alex Harris - Perficient | Oct 9, 2024 | Syndicated blog

Problem with language file localization after upgrading to Optimizely CMS 12

Avoid common problems with xml file localization when upgrading from Optimizely CMS 11 to CMS 12.

Tomas Hensrud Gulla | Oct 9, 2024 | Syndicated blog