Back to: ASP.NET MVC Tutorial For Beginners and Professionals
Customizing Auto-Generated Edit View in ASP.NET MVC Application
In this article, I am going to discuss customizing the auto-generated edit view in ASP.NET MVC application. This is a continuation part of our previous article, so please read our previous article before proceeding to this article. In our previous article, we discussed customizing the auto-generated Index and Create views.
Customizing Auto-Generated Edit View
Run the application and navigate to the Index view. Click on the Edit button which will take you to edit view to edit an employee which should display as shown below.
In the edit view if you want “Select Department” as the first item in the “Department” dropdown list then replace the following line.
@Html.DropDownList(“DepartmentId”,null , htmlAttributes: new { @class = “form-control” })
with
@Html.DropDownList(“DepartmentId”,null , “Select Department”, htmlAttributes: new { @class = “form-control” })
Notice that a textbox is used for gender. It is ideal to have a dropdown list for gender rather than a textbox. To achieve this, make the following changes to the “Edit.cshtml” view. Replace the following 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 { @class = “form-control” })
Creating a Field as Non Editable:
Let’s make employee name as non-editable. To achieve this, change the following code in Edit.cshtml view
@Html.EditorFor(model =>model.Name)
TO
@Html.DisplayFor(model =>model.Name)
@Html.HiddenFor(model =>model.Name)
After all the modifications below is our code for Edit.cshtml view
@model CRUD_Using_EF.Models.Employee @{ ViewBag.Title = "Edit"; } <h2>Edit</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Employee</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) @Html.HiddenFor(model => model.EmployeeId) <div class="form-group"> @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DisplayFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.HiddenFor(model => model.Name) @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.DepartmentId, "DepartmentId", htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.DropDownList("DepartmentId", null, "Select Department", htmlAttributes: new { @class = "form-control" }) @Html.ValidationMessageFor(model => model.DepartmentId, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Save" 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>
At this point, we will still be able to change the “Name” property of the employee using tools like Fiddler. There are several ways to prevent “Name” property from being updated.
- Use UpdateModel() function and pass include and exclude list as a parameter
- Use Bind attribute
- Use Interfaces
Prevent Updating using Bind Attribute:
Now let’s discuss using the BIND attribute to prevent updating the “Name” property using tools like Fiddler. Along the way, I will demonstrate adding model validation errors dynamically. Change the implementation of the “Edit” action method of Employee Controller that responds to [HttpPost] request as shown below
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "EmployeeId,Gender,City,Salary,DepartmentId")] Employee employee) { Employee employeeFromDB = db.Employees.Single(emp => emp.EmployeeId == employee.EmployeeId); employeeFromDB.Gender = employee.Gender; employeeFromDB.City = employee.City; employeeFromDB.Salary = employee.Salary; employeeFromDB.DepartmentId = employee.DepartmentId; if (ModelState.IsValid) { db.Entry(employeeFromDB).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId); return View(employee); }
Here, we have not included the “Name” property from model binding using the “Bind” attribute. Even without the BIND attribute users will not be able to change the “Name” of the employee as we are copying only the required properties (Excluding name property) from the “employee” object to “employeeFromDB” which in turn is persisted to the database. Since I want to demonstrate adding model validation errors dynamically let the attribute be there.
At this point if we run the application and click on the “Save” button on the “Edit” view we get a validation error stating – The Name field is required. This is because the “Name” property is decorated with the [Required] attribute in “PEmployee.cs” file. To prevent the validation error, remove the [Required] attribute.
Now the PEmployee.cs file looks as follows
using System.ComponentModel.DataAnnotations; namespace CRUD_Using_EF.Models { [MetadataType(typeof(EmployeeMetaData))] public partial class Employee { } public class EmployeeMetaData { public string Name { get; set; } [Required] public string Gender { get; set; } [Required] public string City { get; set; } [Required] public string Salary { get; set; } [Required] public int DepartmentId { get; set; } } }
Now run the application and see Edit view is working as expected.
Adding Model Error Dynamically:
The problem with this change is that the “Name” field on the “Create” view is no longer mandatory. This means we will now be able to create a new employee without the Name value. To fix this error on the “Create” view let’s add model validation errors dynamically. Change the implementation of the “Create” action method that responds to [HttpPost] request as shown below.
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "EmployeeId,Name,Gender,City,Salary,DepartmentId")] Employee employee) { if (string.IsNullOrEmpty(employee.Name)) { ModelState.AddModelError("Name", "The Name field is required."); } if (ModelState.IsValid) { db.Employees.Add(employee); db.SaveChanges(); return RedirectToAction("Index"); } ViewBag.DepartmentId = new SelectList(db.Departments, "Id", "Name", employee.DepartmentId); return View(employee); }
That’s it. Run the application and see Create View is also working as expected.
In the next article, I am going to discuss HTML helpers in the ASP.NET MVC applications. Here, in this article, I try to explain Customizing Auto Generated Edit View in ASP.NET MVC application as well as how to add dynamic model validation error. I hope this article will help you with your needs. I would like to have your feedback. Please post your feedback, question, or comments about this article.
You have made life easy. I have brought books and read through lots of articles but always felt left out. I am very senior so had less time to do practical. Long time ago i used to read books from Stephen Walther who made learning asp.net easy. You have done the same thing.God bless you.
This is for overall content. Please post more about the core of MVC ,how to extent controller view, bundles, depenency injection under advance section.