"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 registration. 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 a Product that has various properties to store a value for the project object. Product Model ("ProductModel.cs") is.
using System.Collections.Generic;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
namespace FormTypesMvcApplication.Models
{
public class ProductModel
{
public ProductModel()
{
Category = new List<SelectListItem>();
Category.Add(new SelectListItem
{
Text = "Books",
Value = "1"
});
Category.Add(new SelectListItem
{
Text = "Mobiles & Tablets",
Value = "2"
});
Category.Add(new SelectListItem
{
Text = "Laptops & Accessories",
Value = "3"
});
}
public int ProductId { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public string Manufacturer { get; set; }
[RegularExpression(@"^\$?\d+(\.(\d{2}))?$")]
public decimal BasePrice { get; set; }
public IList<SelectListItem> Category { get; set; }
public int CategoryId { get; set; }
}
}
Now we have a product model that will be bound with view.
Step 3. 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.
public ActionResult ProductHtml()
{
ProductModel model = new ProductModel();
return View(model);
}
Step 2. Create View.
We create a strongly typed view with the help of a Product model that uses 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 a MvcFrom as in the following.
@{
using (MvcForm mvcForm = Html.BeginForm())
{
<div>My Html Form</div>
}
}
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.
<form action="/Product/ProductHtml" method="post">
<div>My Html Form</div>
</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 submission that handles the post request.
We can write the same code to create both opening <form> and closing </form> tags as in the following.
@using(Html.BeginForm())
{
<div>My Html Form</div>
}
Now we create our view (ProductHtml.cshtml) to show data in the UI and the code for that is.
@model FormTypesMvcApplication.Models.ProductModel
@using System.Web.Mvc.Html;
@{
ViewBag.Title = "Product Master HTML";
}
<h2>Product Master</h2>
<fieldset>
<legend>Product</legend>
@using (Html.BeginForm())
{
<div class="formRowContainer">
<div class="labelContainer">Name</div>
<div class="valueContainer">
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessage("Name")
</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Description</div>
<div class="valueContainer">@Html.TextBoxFor(model => model.Description)</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Manufacturer</div>
<div class="valueContainer">@Html.TextBoxFor(model => model.Manufacturer)</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Price</div>
<div class="valueContainer">
@Html.TextBoxFor(model => model.BasePrice)
@Html.ValidationMessage("BasePrice")
</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Category</div>
<div class="valueContainer">
@Html.DropDownListFor(model => model.CategoryId, Model.Category, "--Select--")
</div>
</div>
<div class="clearStyle"></div>
<div class="buttonContainer">
<button>Add Product</button>
</div>
}
</fieldset>
Step 3. Create Action to handle the form submission.
We know that when the form is submitted, the Post method executes. In the "BeginForm()" method we did not pass any action and controller name so the default action method means that 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.
[HttpPost]
public ActionResult ProductHtml(ProductModel model)
{
if (ModelState.IsValid)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("Product Name : " + model.Name + "</br>");
sb.Append("Description : " + model.Description + "</br>");
sb.Append("Manufacturer : " + model.Manufacturer + "</br>");
sb.Append("Price : " + model.BasePrice + "</br>");
sb.Append("Category : " + model.Category[model.CategoryId - 1].Text);
return Content(sb.ToString());
}
else
{
return View(model);
}
}
Now the process is ready and runs the application.
Click on the submit button "Add Product" so that it submits all the form data and we get the result in another screen with the same URL due to post-back.
Working With Ajax.BeginForm()
Step 1. Create an Action in the controller to load a view in the UI.
Create an ActionResult return type method that returns a view with an empty model. This action method loads our view whenever we make a request from a browser. The action method is as follows.
public ActionResult ProductAjax()
{
ProductModel model = new ProductModel();
return View(model);
}
Step 2. Create View.
When we use "Ajax.BeginForm()" then the form will be submitted 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.
<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.
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</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.
@model FormTypesMvcApplication.Models.ProductModel
@{
ViewBag.Title = "Product Master Ajax";
}
<h2>Product Master</h2>
<fieldset>
<legend>Product</legend>
@using (Ajax.BeginForm("ProductAjax", "Product", new AjaxOptions { UpdateTargetId = "Productresult" }))
{
<div id="Productresult"></div>
<div class="formRowContainer">
<div class="labelContainer">Name</div>
<div class="valueContainer">
@Html.TextBoxFor(model => model.Name)
@Html.ValidationMessage("Name")
</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Description</div>
<div class="valueContainer">@Html.TextBoxFor(model => model.Description)</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Manufacturer</div>
<div class="valueContainer">@Html.TextBoxFor(model => model.Manufacturer)</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Price</div>
<div class="valueContainer">
@Html.TextBoxFor(model => model.BasePrice)
@Html.ValidationMessage("BasePrice")
</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Category</div>
<div class="valueContainer">
@Html.DropDownListFor(model => model.CategoryId, Model.Category, "--Select--")
</div>
</div>
<div class="clearStyle"></div>
<div class="buttonContainer">
<button>Add Product</button>
</div>
}
</fieldset>
Step 3. Create Action to handle the form submission.
We know that when a form is submitted 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.
[HttpPost]
public ActionResult ProductAjax(ProductModel model)
{
if (ModelState.IsValid)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
sb.Append("Product Name : " + model.Name + "</br>");
sb.Append("Description : " + model.Description + "</br>");
sb.Append("Manufacturer : " + model.Manufacturer + "</br>");
sb.Append("Price : " + model.BasePrice + "</br>");
sb.Append("Category : " + model.Category[model.CategoryId - 1].Text);
return Content(sb.ToString());
}
else
{
return View(model);
}
}
Now the process is ready and runs the application.
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.
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 requirements.