FormCollection in ASP.NET MVC

FormCollection in ASP.NET MVC

In this article, I am going to discuss FormCollection in ASP.NET MVC application. Please read our previous article where we discussed business objects as Model in MVC application. We are also going to work with the same example that we worked in our previous article.

Here, in this article, we will create a view to inserting a new employee into the database table Employee using the FormCollection class that is available in ASP.NET MVC

Creating a view to inserting data using FormCollection in MVC

We want to present the end-user with a form as shown in the image below 

Creating a view to inserting data using FormCollection in MVC

Copy and paste the following “Create” action method in the EmployeeController class. 

[HttpGet]
public ActionResult Create()
{
    return View();
}

Please note that the method is decorated with “HttpGet” attribute. This makes this action method to respond only to the “GET” request. Now let’s add a “Create” view. To do this right-click on the “Create” action method and select “Add View” from the context menu. Set

View name = “Create”
Template = “Create”
Model class = Employee (BusinessLayer)

Click on the “Add” button as shown below.

FormCollection in MVC

At this point “Create.cshtml” view will be added to the “Employee” folder. Run the application and navigate to the  URL http://localhost:54094/Employee/Index“. Click on “Create New” link. It will navigate to the URL http://localhost:54094/Employee/Create

FormCollection Class in MVC

A form with text boxes to add a new employee is rendered. For employee “Gender” it is ideal to have a dropdown list instead of a text box. To achieve this replace the following line of code

@Html.EditorFor(model => model.Gender, new { htmlAttributes = new { @class = "form-control" } })
WITH
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender", new { htmlAttributes = new { @class = "form-control" } })
After the changes, the complete code for the create view as shown below
@model BusinessLayer.Employee
@{
ViewBag.Title = "Create";
}
<h2>Create Employee</h2>
@using (Html.BeginForm()) 
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Gender, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.DropDownList("Gender", new List<SelectListItem>
{
new SelectListItem { Text = "Male", Value="Male" },
new SelectListItem { Text = "Female", Value="Female" }
}, "Select Gender", new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Gender, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.City, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.City, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.Salary, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Salary, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.Salary, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.DateOfBirth, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.DateOfBirth, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.DateOfBirth, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

Now, run the application and notice that a dropdown list is rendered for “Gender”. If we click on the “Create” button we will get an error message stating – The resource cannot be found. This is because we don’t have the “Create” action method that can handle HTTPPost request.

What is the FormCollection Class in ASP.NET MVC?

The FormCollection class will automatically receive the posted form values in the controller action method in key/value pairs. Keys & values can be accessed using key names or index.

We can use the FormCollection to loop thru each key and its value that is posted to the server. Let’s add the following Create Post method to the employee Controller class.

[HttpPost]
public ActionResult Create(FormCollection formCollection)
{
if (ModelState.IsValid)
{
foreach (string key in formCollection.AllKeys)
{
Response.Write("Key = " + key + "  ");
Response.Write("Value = " + formCollection[key]);
Response.Write("<br/>");
}
}
return View();
}

The output is as shown below

FormCollection Class in ASP.NET MVC

Let’s create a stored procedure to insert the employee object in the Employee table
Create procedure spAddEmployee  
@Name nvarchar(50),
@Gender nvarchar (10),
@City nvarchar (50),
@Salary decimal(18,2),
@DateOfBirth DateTime
As
Begin
Insert into Employee(Name, Gender, City, Salary, DateOfBirth)
Values (@Name, @Gender, @City,@Salary, @DateOfBirth)
End
Add the following method to EmployeeBusinessLayer.cs file.
   // Add employee into the database. This method takes an argument of Employee type which contains the 
//employeethat is going to stored in the database
public void AddEmmployee(Employee employee)
{
//Creating the connection string
string connectionString = ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString;
//Establishing the connection to the database
using (SqlConnection con = new SqlConnection(connectionString))
{
//Creating the command object by passing the stored procedure and connection object as argument
//This stored procedure is used to store the employee in to the database
SqlCommand cmd = new SqlCommand("spAddEmployee", con);
//Specifying the command as stored procedure
cmd.CommandType = CommandType.StoredProcedure;
//Creating SQL parameters because that stored procedure accept some input values
SqlParameter paramName = new SqlParameter();
//Storing the parameter name of the stored procedure into the SQL parameter
//By using ParameterName property 
paramName.ParameterName = "@Name";
//storing the parameter value into sql parameter by using Value ptoperty
paramName.Value = employee.Name;
//Adding that parameter into Command objects Parameter collection by using Add method
//which will take the SQL parameter name as argument
cmd.Parameters.Add(paramName);
//Same for all other parameters (Gender, City, DateOfBirth )
SqlParameter paramGender = new SqlParameter();
paramGender.ParameterName = "@Gender";
paramGender.Value = employee.Gender;
cmd.Parameters.Add(paramGender);
SqlParameter paramCity = new SqlParameter();
paramCity.ParameterName = "@City";
paramCity.Value = employee.City;
cmd.Parameters.Add(paramCity);
SqlParameter paramSalary = new SqlParameter();
paramSalary.ParameterName = "@Salary";
paramSalary.Value = employee.Salary;
cmd.Parameters.Add(paramSalary);
SqlParameter paramDateOfBirth = new SqlParameter();
paramDateOfBirth.ParameterName = "@DateOfBirth";
paramDateOfBirth.Value = employee.DateOfBirth;
cmd.Parameters.Add(paramDateOfBirth);
//Open the connection and execute the command on ExecuteNonQuery method
con.Open();
cmd.ExecuteNonQuery();
}
}

To save form data to a database table modify the create method EmployeeController.cs file whose type is HttpPost.

//FormCollection will store the submitted form data automatically when the form is submitted
[HttpPost]
public ActionResult Create(FormCollection formCollection)
{
Employee employee = new Employee();
// Retrieve form data using form collection
employee.Name = formCollection["Name"];
employee.Gender = formCollection["Gender"];
employee.City = formCollection["City"];
employee.Salary =Convert.ToDecimal(formCollection["Salary"]);
employee.DateOfBirth = Convert.ToDateTime(formCollection["DateOfBirth"]);
EmployeeBusinessLayer employeeBusinessLayer = new EmployeeBusinessLayer();
employeeBusinessLayer.AddEmmployee(employee);
return RedirectToAction("Index");
}

Now Run the application and see everything is working as expected.

But the question is do we really have to write all the dirty code of retrieving data from FormCollection class and assign it to the properties of “employee” object. The answer is no. This is the job of the model binder in MVC.

In the next article, I am going to discuss the Model Binders in ASP.NET MVC application with an example. Here, in this article, I try to explain how to use FormCollection in ASP.NET MVC application step by step with a simple example. I hope you enjoy this article.

Leave a Reply

Your email address will not be published. Required fields are marked *