ASP.NET Core MVC Employee Management – Index View with Modal Form and AJAX Create
✅ 1) Why did asp-for
show an error like:
“IEnumerable<Employee> does not contain a definition for 'Name'…”
Explanation:
At the top of your Razor view you have:
which means:
“This view expects a model that is a collection (list) of Employee objects.”
But later in your modal form you wrote:
The
asp-for
tag helper looks for a property namedName
on the model.But your model is
IEnumerable<Employee>
(i.e., a collection of employees).A collection doesn’t have properties like
Name
,Gender
etc. Those belong to a singleEmployee
.
That’s why you get:
“IEnumerable<Employee> does not contain a definition for 'Name'…”
Why is dummy
used?
In the table header, we often use:
Why?
DisplayNameFor
needs to know which property it is working on, so it can find:Display name from
[Display(Name="...")]
attributes in your model,or use the property name itself.
DisplayNameFor
doesn’t actually render data; it just looks at the property metadata.
Since our model is IEnumerable<Employee>
, we can’t say:
So we create:
and then write:
This way, DisplayNameFor
can still get the metadata of the Name
property from an Employee object.
✅ 3) Why not use asp-for
inside the modal?
Inside the modal form, if you wrote:
It would try to bind to the model: IEnumerable<Employee>
— which is wrong.
Correct approach:
Since your modal is for creating one new employee, you should ideally:
Use a partial view whose
@model
is a singleEmployee
orManually write
<input>
elements withoutasp-for
.
For quick projects:
We often manually write:
and handle validation & posting with JavaScript (as shown).
✔ ASP.NET Core MVC view (index.cshtml
partial with modal),
✔ CSS,
✔ full jQuery validation (red border + inline error),
all together, so you can copy-paste.
✅ Full updated index.cshtml
(view)
@model IEnumerable<DemoEmsCoreMVCMarch2025.Models.Employee>
@{
ViewData["Title"] = "Index";
var dummy = new DemoEmsCoreMVCMarch2025.Models.Employee();
}
<h1>Index</h1>
<style>
.input-error {
border-color: red !important;
}
</style>
<div class="container mt-3">
<div class="d-flex align-items-center">
<!--Add Employee-->
<button type="button" class="btn btn-secondary me-2"
data-bs-toggle="modal"
data-bs-target="#createEmployeeModal">
Create New
</button>
<!--Search Employee-->
<input type="text" id="searchInput" class="form-control me-2"
placeholder="Enter contact number"
style="width: auto; flex-grow: 1;">
<button id="searchButton" class="btn btn-primary">Search</button>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>@Html.DisplayNameFor(m => dummy.Id)</th>
<th>@Html.DisplayNameFor(m => dummy.Name)</th>
<th>@Html.DisplayNameFor(m => dummy.Gender)</th>
<th>@Html.DisplayNameFor(m => dummy.Designation)</th>
<th>@Html.DisplayNameFor(m => dummy.Salary)</th>
<th>@Html.DisplayNameFor(m => dummy.DOB)</th>
<th>@Html.DisplayNameFor(m => dummy.Department.DepartmentName)</th>
<th>@Html.DisplayNameFor(m => dummy.IsActive)</th>
<th>@Html.DisplayNameFor(m => dummy.Contact)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(m => item.Id)</td>
<td>@Html.DisplayFor(m => item.Name)</td>
<td>@Html.DisplayFor(m => item.Gender)</td>
<td>@Html.DisplayFor(m => item.Designation)</td>
<td>@Html.DisplayFor(m => item.Salary)</td>
<td>@Html.DisplayFor(m => item.DOB)</td>
<td>@Html.DisplayFor(m => item.Department.DepartmentName)</td>
<td>@Html.DisplayFor(m => item.IsActive)</td>
<td>@Html.DisplayFor(m => item.Contact)</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id = item.Id }) |
@Html.ActionLink("Details", "Details", new { id = item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id = item.Id })
</td>
</tr>
}
</tbody>
</table>
<!-- Modal -->
<div class="modal fade" id="createEmployeeModal" tabindex="-1"
aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Create Employee</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
<form id="createEmployeeForm">
<!-- Name -->
<div class="form-group">
<label>Name <span class="text-danger">*</span></label>
<input class="form-control" id="name" autocomplete="off" />
<span id="nameError" class="text-danger"></span>
</div>
<!-- Gender -->
<div class="form-group">
<label>Gender <span class="text-danger">*</span></label>
<div>
<input type="radio" name="Gender" value="Male" id="genderMale" /> <label for="genderMale">Male</label>
</div>
<div>
<input type="radio" name="Gender" value="Female" id="genderFemale" /> <label for="genderFemale">Female</label>
</div>
<div>
<input type="radio" name="Gender" value="Other" id="genderOther" /> <label for="genderOther">Other</label>
</div>
<span id="genderError" class="text-danger"></span>
</div>
<!-- Designation -->
<div class="form-group">
<label>Designation <span class="text-danger">*</span></label>
<input class="form-control" id="designation" autocomplete="off" />
<span id="designationError" class="text-danger"></span>
</div>
<!-- Contact -->
<div class="form-group">
<label>Contact <span class="text-danger">*</span></label>
<input class="form-control" id="contact" autocomplete="off" />
<span id="contactError" class="text-danger"></span>
</div>
<!-- Salary -->
<div class="form-group">
<label>Salary <span class="text-danger">*</span></label>
<input class="form-control" id="salary" type="number" autocomplete="off" />
<span id="salaryError" class="text-danger"></span>
</div>
<!-- DOB -->
<div class="form-group">
<label>Date of Birth <span class="text-danger">*</span></label>
<input class="form-control" id="dob" type="date" />
<span id="dobError" class="text-danger"></span>
</div>
<!-- Department -->
<div class="form-group">
<label>Department <span class="text-danger">*</span></label>
<select id="departmentList" class="form-control">
<option value="">---Select Department---</option>
@foreach (var department in ViewBag.Departments)
{
<option value="@department.DepartmentId">@department.DepartmentName</option>
}
</select>
<span id="departmentError" class="text-danger"></span>
</div>
<!-- IsActive -->
<div class="form-group form-check">
<input type="checkbox" id="IsActive" class="form-check-input" checked />
<label class="form-check-label">Is Active</label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary"
data-bs-dismiss="modal">
Close
</button>
<button type="button" id="btnSave" class="btn btn-primary">Save</button>
</div>
</div>
</div>
</div>
@section Scripts {
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function () {
$("#btnSave").click(function (e) {
e.preventDefault();
// Clear previous errors
$(".form-control").removeClass("input-error");
$(".text-danger").text("");
var hasError = false;
var name = $("#name").val().trim();
var gender = $("input[name='Gender']:checked").val();
var designation = $("#designation").val().trim();
var contact = $("#contact").val().trim();
var salary = $("#salary").val().trim();
var dob = $("#dob").val().trim();
var departmentId = $("#departmentList").val();
if (!name) {
$("#name").addClass("input-error");
$("#nameError").text("Name is required.");
hasError = true;
}
if (!gender) {
$("#genderError").text("Gender is required.");
hasError = true;
}
if (!designation) {
$("#designation").addClass("input-error");
$("#designationError").text("Designation is required.");
hasError = true;
}
if (!contact) {
$("#contact").addClass("input-error");
$("#contactError").text("Contact is required.");
hasError = true;
}
if (!salary || parseFloat(salary) <= 0) {
$("#salary").addClass("input-error");
$("#salaryError").text("Enter valid salary.");
hasError = true;
}
if (!dob) {
$("#dob").addClass("input-error");
$("#dobError").text("DOB is required.");
hasError = true;
}
if (!departmentId) {
$("#departmentList").addClass("input-error");
$("#departmentError").text("Select department.");
hasError = true;
}
if (hasError) return;
var formData = {
Name: name,
Gender: gender,
Designation: designation,
Contact: contact,
Salary: salary,
DOB: dob,
DepartmentId: departmentId,
IsActive: $("#IsActive").is(":checked")
};
$.ajax({
type: "POST",
url: "@Url.Action("Create", "Employees")",
data: formData,
success: function () {
$('#createEmployeeModal').modal('hide');
location.reload();
},
error: function () {
alert("Error adding employee.");
}
});
});
});
</script>
}
Comments
Post a Comment