1. How to collect from value in Class in ASP.NET MVC 5 Project?
2. What are the different ways to Retrieve Form Values?
3. What is
FormCollection
Object, ModelBinder
Class and UpdateModel
Class?In this article, I am going to explain 4 different ways to Collect Form Data in Controller class in ASP.NET MVC 5. It is a very basic job for any application is to collect form data and process them with programming logic and save to the database. There are various ways to gather form value in class and I have added 4 most popular and suitable ways to do it.
Content of this Aricle
2. Retrieve Form Data using FormCollection Object.
3. Retrieve Form Data using Model Binder
3. Retrieve Form Data Directly from the Model Class
4. Retrieve Form Data using UpdateModel class
1. Create New MVC Project
SaveFormData
in Visual Studio 2013,2015 or 2017. Go to File New Project. Select Web in left pane and then select ASP.NET Web Application (.Net Framework) in middle panel. A Template window will be opened. Select Empty Template and Check MVC CheckBox and click OK.
Help - Guide to Create New Project with Pictorial Guide
2. Create Model: Create a Model class
StudentModel.cs
. Right click on Models Folder Add Class.
Paste following code in
StudentModel.cs
namespace SaveFormData.Models { public class StudentModel { public int Id { get; set; } public string Name { get; set; } public string City { get; set; } public string Address { get; set; } } }
3. Create Controller: Create a Controller
HomeController.cs
. Right click on Controllers Folder > Add > Controller. Select MVC 5 Controller with read/write actions.
4. Delete Unnecessary code and your
HomeController.cs
should look like this. However, it is not mandatory and you can use your own way to implement code.
using System.Web.Mvc; namespace SaveFormData.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } // GET: Home/Create public ActionResult Create() { return View(); } // POST: Home/Create [HttpPost] public ActionResult Create(FormCollection collection) { try { return View("Index"); } catch { return View(); } } } }
5. Create Views: Right click on
Create()
Action Method in HomeController class and select Add View. Give View Name Create and then choose Create Template from dropdown list. Select StudentModel from Model Class dropdown list. Check Use a layout page and click Add.Create.cshtml View Page
@model SaveFormData.Models.StudentModel @{ ViewBag.Title = "Create"; } <h2>Create</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>StudentModel</h4> <hr /> @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.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.Address, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Address, "", 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>
6. Using same process create Index view Page. Right click on Index Action Method in HomeController class and click Add View. Give View Name: Index, Choose Template: Empty (Without Model), tick on Use a Layout Page and click on Add button.
Index.cshtml View Page
@{ ViewBag.Title = "Index Page"; } <h2>View Details</h2> <strong>Name</strong> : @ViewData["Name"]<br /> <strong>City</strong> : @ViewData["City"]<br /> <strong>Address</strong> : @ViewData["Address"]<br />
Now, your project is ready with a form Create. You can navigate it like this
In this article, I will fill some data in Create Form and when click Create Button, it will display Index View Page with Filled data.
FormCollection
object is used for accessing Form Data in controller class. The FormCollection Object automatically receives the posted form data. In the following example I am going to explain how to use FormCollection Object to retrieve form data into controller class.
using System.Web.Mvc; namespace SaveFormData.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } // GET: Home/Create public ActionResult Create() { return View(); } // POST: Home/Create [HttpPost] public ActionResult Create(FormCollection collection) { try { //Method 1: Using Component Name /*ViewData["Name"] = collection["Name"]; ViewData["City"] = collection["City"]; ViewData["Address"] = collection["Address"];*/ //Method 2: Using Component Index Position ViewData["Name"] = collection[1]; ViewData["City"] = collection[2]; ViewData["Address"] = collection[3]; return View("Index"); } catch { return View(); } } } }
Output
using System.Web.Mvc; namespace SaveFormData.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } // GET: Home/Create public ActionResult Create() { return View(); } // POST: Home/Create [HttpPost] public ActionResult Create(string name, string city, string address) { try { ViewData["Name"] = name; ViewData["City"] = city; ViewData["Address"] = address; return View("Index"); } catch { return View(); } } } }
Explanation:
I know what is going on your mind. You are thinking that how MVC map parameter exactly with correct components. It is very simple. MVC has a Model Binder that does the following task to match parameter with control.
b. Look for control name that match with parameter name.
c. Map that control to parameter with same name.
But here is a catch. You have to use the same name as your component name. If you look for Create.cshtml source page you will notice that the controls name are same as the parameter name. It doesn't matter ordering of parameter but naming should be same.
In previous method, Model Binder works great if you have a form with 3 or 5 controls but what if you have a form with 30+ controls. It is not practical to use a 30+ parameter to retrieve form data. Your Model class fixes these issues and makes this job very easier. How see the example.
You must import SaveFormData.Models to use StudentModel Object
using System.Web.Mvc; using SaveFormData.Models; namespace SaveFormData.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } // GET: Home/Create public ActionResult Create() { return View(); } // POST: Home/Create [HttpPost] public ActionResult Create(StudentModel smodel) { try { if (ModelState.IsValid) { ViewData["Name"] = smodel.Name; ViewData["City"] = smodel.City; ViewData["Address"] = smodel.Address; return View("Index"); } else { return View(); } } catch { return View(); } } } }
Explanation
In this example, you can receive data directly from your model class. ModelState.IsValid
properties ensure that all the data filled in a control was in a correct format and validated.
You must import SaveFormData.Models to use StudentModel Object
using System.Web.Mvc; using SaveFormData.Models; namespace SaveFormData.Controllers { public class HomeController : Controller { // GET: Home public ActionResult Index() { return View(); } // GET: Home/Create [HttpGet] [ActionName("Create")] public ActionResult Create_get() { return View(); } // POST: Home/Create [HttpPost] [ActionName("Create")] public ActionResult Create_post() { try { StudentModel smodel = new StudentModel(); UpdateModel(smodel); ViewData["Name"] = smodel.Name; ViewData["City"] = smodel.City; ViewData["Address"] = smodel.Address; return View("Index"); } catch { return View(); } } } }
Explanation:
The UpdateModel class binds control data to models property. But there is a catch. When you use UpdateModel class, there is no parameter in [HttpPost] Create()
Method. As you know that there can not be two methods in a class with same name and same parameter types. As there are already a [HttpGet] Create()
method without parameter, so you cannot declare [HttpPost] Create()
method without parameter. So the solution is to change Create Method name as Create_Get()
and Create_Post()
or whatever you want to change. Then decorate both method with correct action name as follows:
// GET: Home/Create [HttpGet] [ActionName("Create")] public ActionResult Create_get() { return View(); } // POST: Home/Create [HttpPost] [ActionName("Create")] public ActionResult Create_post() { …….. return View(); }
Summary
In this article, I have shown you 4 different ways to retrieve form value in controller class. It is very necessary to know how to collect form data in a class for each MVC Programmer or learner. Hope, your doubt would be cleared.