Working With Html.BeginForm() and Ajax.BeginForm() in MVC 3

"BeginForm()" is an extension method that writes an opening "<form>" tag to the response. "BeginForm()" is an extension method for both HtmlHelper and AjaxHelper classes. It returns an MVCForm object from both HtmlHelper and AjaxHelper class instances so there is not much difference but the AjaxHelper method submits the form asynchronously using JavaScript.

There are two types of the BeginForm() extension methods, they are,

  • Html.BeginForm()
  • Ajax.BeginForm()

This article explains the behavior of both "Html.BeginForm()" and "Ajax.BeginForm()" although these are the same and return the same MvcForm object. To explain the post-back behavior of both methods we create an application for product registeration. Let's see that step-by-step.

Step 1

Create an MVC application

Step 2 Create Model

We create a model (actually a class) for Product that has various properties to store a value for the project object. Product Model ("ProductModel.cs") is: 
  1. using System.Collections.Generic;  
  2. using System.Web.Mvc;  
  3. using System.ComponentModel.DataAnnotations;  
  4.    
  5. namespace FormTypesMvcApplication.Models  
  6. {  
  7.     public class ProductModel  
  8.     {  
  9.         public ProductModel()  
  10.         {  
  11.             Category = new List<SelectListItem>();  
  12.             Category.Add(new SelectListItem  
  13.             {  
  14.                 Text = "Books",  
  15.                 Value = "1"  
  16.             });  
  17.             Category.Add(new SelectListItem  
  18.             {  
  19.                 Text = "Mobiles & Tablets",  
  20.                 Value = "2"  
  21.             });  
  22.             Category.Add(new SelectListItem  
  23.             {  
  24.                 Text = "Laptops & Accessories",  
  25.                 Value = "3"  
  26.             });  
  27.         }  
  28.          
  29.         public int ProductId { getset; }  
  30.         [Required]  
  31.         public string Name { getset; }         
  32.         public string Description { getset; }  
  33.         public string Manufacturer { getset; }         
  34.         [RegularExpression(@"^\$?\d+(\.(\d{2}))?$")]  
  35.         public decimal BasePrice { getset; }  
  36.         public IList<SelectListItem> Category { getset; }  
  37.         public int CategoryId { getset; }  
  38.     }  
  39. }  
Now we have a product model that will be bound with view.

Step 4 Create Controller

Create a product controller where we define action methods that return a view and form submitting data. Here we create a controller ("ProductController.cs").

Working With Html.BeginForm()

Step 1

Create an Action in a controller to load the view in the UI Create an ActionResult return type action method that returns a view with an empty model. This action method loads our view whenever we make a request from the browser. The action method is:
  1. public ActionResult ProductHtml()  
  2. {  
  3.     ProductModel model = new ProductModel();            
  4.     return View(model);  
  5. }  
Step 2 Create View

We create a strongly typed view with help of Product model that uses the Html.BeginForm() method to create a form. The BeginForm() method is an extension method of the HtmlHelper class that writes an opening "<form>" tag and it also calls the "Dispose()" method that writes a closing "</form>" tag. Because the MvcForm class implements the IDisposable interface, we can call the Dispose() method of the IDisposable interface to dispose of the MvcForm class object. We create an MvcFrom as in the following:
  1. @{         
  2.     MvcForm mvcForm = Html.BeginForm();      
  3.     <div>My Html Form</div>       
  4.     mvcForm.Dispose();  
  5. }  
And that code renders in the opening "<form>" and closing "</form>" tags on the browser when it's loaded. We get the source code in the browser as in the following:
  1. <form action="/Product/ProductHtml" method="post">  
  2.     <div>My Html Form</div>       
  3. </form>  
Here the action and method type properties have their values. The method type is "post" so the Product controller's "ProductHtml()" action method will be called on the form submit that handles the post request.

We can write the same code to create both opening <form> and closing </form> tags as in the following:
  1. @using(Html.BeginForm())  
  2. {      
  3.     <div>My Html Form</div>  
  4. }  
Now we create our view (ProductHtml.cshtml) to show data in the UI and the code for that is:
  1. @model FormTypesMvcApplication.Models.ProductModel  
  2. @using System.Web.Mvc.Html;  
  3.    
  4. @{  
  5.     ViewBag.Title = "Product Master HTML";  
  6. }  
  7.    
  8. <h2>Product Master</h2>  
  9.    
  10. <fieldset>  
  11.     <legend>Product</legend>          
  12.      
  13. @using (Html.BeginForm())  
  14. {  
  15.      <div class="formRowContainer">  
  16.         <div class="labelContainer">Name</div>  
  17.         <div class="valueContainer">  
  18.             @Html.TextBoxFor(model => model.Name)  
  19.             @Html.ValidationMessage("Name")  
  20.         </div>  
  21.      </div>  
  22.     <div class="clearStyle"></div>  
  23.     <div class="formRowContainer">  
  24.         <div class="labelContainer">Description</div>  
  25.         <div class="valueContainer">@Html.TextBoxFor(model => model.Description)</div>  
  26.     </div>  
  27.     <div class="clearStyle"></div>  
  28.     <div class="formRowContainer">  
  29.         <div class="labelContainer">Manufacturer</div>  
  30.         <div class="valueContainer">@Html.TextBoxFor(model => model.Manufacturer)</div>  
  31.     </div>  
  32.     <div class="clearStyle"></div>  
  33.     <div class="formRowContainer">  
  34.         <div class="labelContainer">Price</div>  
  35.         <div class="valueContainer">  
  36.             @Html.TextBoxFor(model => model.BasePrice)  
  37.             @Html.ValidationMessage("BasePrice")  
  38.         </div>  
  39.     </div>  
  40.     <div class="clearStyle"></div>  
  41.      <div class="formRowContainer">  
  42.         <div class="labelContainer">Category</div>  
  43.         <div class="valueContainer">  
  44.             @Html.DropDownListFor(model => model.CategoryId, Model.Category, "--Select--")  
  45.         </div>  
  46.     </div>  
  47.     <div class="clearStyle"></div>  
  48.     <div class="buttonContainer">  
  49.         <button>Add Product</button>     
  50.     </div>  
  51. }  
  52. </fieldset>  
Step 3 Create Action to handle form submitting

We know that when the form is submited, the Post method executes. In the "BeginForm()" method we did not pass any action and controller name so the default action method means that as the view name action method is called to handle the post of the data request. So it creates an action that returns form data into the content to be shown on the UI on form submission.
  1. [HttpPost]  
  2. public ActionResult ProductHtml(ProductModel model)  
  3. {  
  4.     if (ModelState.IsValid)  
  5.     {  
  6.       System.Text.StringBuilder sb = new System.Text.StringBuilder();  
  7.   
  8.        sb.Append("Product Name :" + model.Name + "</br/>");  
  9.        sb.Append("Description :" + model.Description + "</br/>");  
  10.        sb.Append("Manufacturer :" + model.Manufacturer + "</br/>");  
  11.        sb.Append("Price :" + model.BasePrice + "</br/>");  
  12.        sb.Append("Category :" + model.Category[model.CategoryId-1].Text);  
  13.         return Content(sb.ToString());  
  14.     }  
  15.     else  
  16.     {  
  17.         return View(model);  
  18.     }  
  19. }  
Now the process is ready and runs the application. 

MVC1.jpg

Click on the submit button "Add Product" so that submits all the form data and we get the result in another screen with the same URL due to post-back.

MVC2.jpg

Working With Ajax.BeginForm()

Step 1 Create Action in the controller to load a view in the UI

Create an ActionResult return type method that returns a view with empty model. This action method loads our view whenever we make a request from a browser. The action method is as in the following:
  1. public ActionResult ProductAjax()  
  2. {  
  3.     ProductModel model = new ProductModel();  
  4.     return View(model);  
  5. }  
Step 2 Create View

When we use "Ajax.BeginForm()" then the form will be submited using JavaScript. We are using "_Layout.cshtml" as a shared layout so add the JavaScript file "jquery.unobtrusive-ajax.min.js" reference on it to handle the ajax form submission request on post-back.
  1. <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>  
Now to handle the request we add "UnobtrusiveJavaScriptEnabled" as a key in the web.config file under the "<appSettings>" section.
  1. <appSettings>  
  2.     <add key="webpages:Enabled" value="false" />  
  3.     <add key="ClientValidationEnabled" value="true"/>  
  4.     <add key="UnobtrusiveJavaScriptEnabled" value="true"/>  
  5. </appSettings>  
Now we create a view that has an Ajax form. The Ajax.BeginForm() method has three arguments, these are actionName, controllerName and AjaxOptions. We are using the AjaxOptions object UpdateTargetId property that has a value of a control id where the response will be shown after the post request. In the following code we are passing the div id so the result data will be shown in that div.
  1. @model FormTypesMvcApplication.Models.ProductModel  
  2.    
  3. @{  
  4.     ViewBag.Title = "Product Master Ajax";  
  5. }  
  6.    
  7. <h2>Product Master</h2>  
  8.    
  9. <fieldset>  
  10.     <legend>Product</legend>     
  11. @using (Ajax.BeginForm("ProductAjax""Product"new AjaxOptions { UpdateTargetId = "Productresult" }))  
  12. {  
  13.     <div id="Productresult"></div>  
  14.      <div class="formRowContainer">  
  15.         <div class="labelContainer">Name</div>  
  16.         <div class="valueContainer">  
  17.             @Html.TextBoxFor(model => model.Name)  
  18.             @Html.ValidationMessage("Name")  
  19.         </div>  
  20.      </div>  
  21.     <div class="clearStyle"></div>  
  22.     <div class="formRowContainer">  
  23.         <div class="labelContainer">Description</div>  
  24.         <div class="valueContainer">@Html.TextBoxFor(model => model.Description)</div>  
  25.     </div>  
  26.     <div class="clearStyle"></div>  
  27.     <div class="formRowContainer">  
  28.         <div class="labelContainer">Manufacturer</div>  
  29.         <div class="valueContainer">@Html.TextBoxFor(model => model.Manufacturer)</div>  
  30.     </div>  
  31.     <div class="clearStyle"></div>  
  32.     <div class="formRowContainer">  
  33.         <div class="labelContainer">Price</div>  
  34.         <div class="valueContainer">  
  35.             @Html.TextBoxFor(model => model.BasePrice)  
  36.             @Html.ValidationMessage("BasePrice")  
  37.         </div>  
  38.     </div>  
  39.     <div class="clearStyle"></div>  
  40.      <div class="formRowContainer">  
  41.         <div class="labelContainer">Category</div>  
  42.         <div class="valueContainer">  
  43.             @Html.DropDownListFor(model => model.CategoryId, Model.Category, "--Select--")  
  44.         </div>  
  45.     </div>  
  46.     <div class="clearStyle"></div>  
  47.     <div class="buttonContainer">  
  48.         <button>Add Product</button>     
  49.     </div>  
  50. }  
  51. </fieldset>  
Step 3 Create Action to handle form submission

We know that when a form is submited the Post method executes. In the "BeginForm()" method we passed an action name and controller name so that the action method will be called that handles the post data request. So it creates an action that returns the form data into the content to be shown on the UI on form submission.
  1. [HttpPost]  
  2. public ActionResult ProductAjax(ProductModel model)  
  3. {  
  4.     if (ModelState.IsValid)  
  5.     {  
  6.         System.Text.StringBuilder sb = new System.Text.StringBuilder();  
  7.         sb.Append("Product Name :" + model.Name + "</br/>");  
  8.         sb.Append("Description :" + model.Description + "</br/>");  
  9.         sb.Append("Manufacturer :" + model.Manufacturer + "</br/>");  
  10.         sb.Append("Price :" + model.BasePrice + "</br/>");  
  11.         sb.Append("Category :" + model.Category[model.CategoryId-1].Text);  
  12.         return Content(sb.ToString());  
  13.     }  
  14.     else  
  15.     {  
  16.         return View(model);  
  17.     }  
  18. }  
Now the process is ready and runs the application.

MVC3.jpg

Click on the submit button "Add Product" that submits all the form data and we get the results on the same screen in the div. So the result is in the following screen on the form design.

MVC4.jpg

Conclusion

In this article we learned about both Html form and Ajax form and how these forms work on post-back. We can use both forms as per our application requirement.