I have the following cshtml code in a View called ViewDepartment.cshtml
@model DepartmentViewModel
<head>
<meta charset="iso-8859-1">
</head>
<body>
<div class="d-flex flex-row">
<a class="navbar-text">@Html.DisplayNameFor(o => o.HeadOfTheDepartment): </a>
<a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@Model.HeadOfTheDepartment.FacultyId">@Html.DisplayFor(o => o.HeadOfTheDepartment.FacultyName)</a>
</div>
@*Professors*@
<div class="d-flex flex-column">
<a class="navbar-text align-content-center">@Html.DisplayNameFor(o => o.Professors): </a>
<table class="table table-bordered">
<thead>
<tr class="d-table-row">
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyName)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyDepartment)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyDesignation)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyAddress)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyEmail)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyPhoneNumber)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyStatus)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (Faculty faculty in Model.Professors)
{
<tr class="d-table-row">
<td>@Html.DisplayFor(o => faculty.FacultyName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDepartment.DepartmentName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDesignation)</td>
<td>@Html.DisplayFor(o => faculty.FacultyAddress)</td>
<td>@Html.DisplayFor(o => faculty.FacultyEmail)</td>
<td>@Html.DisplayFor(o => faculty.FacultyPhoneNumber)</td>
<td>@Html.DisplayFor(o => faculty.FacultyStatus)</td>
<td><a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@faculty.FacultyId">View Profile</a></td>
</tr>
}
</tbody>
</table>
</div>
@*Associate Professors*@
<div class="d-flex flex-column">
<a class="navbar-text align-content-center">@Html.DisplayNameFor(o => o.AssociateProfessors): </a>
<table class="table table-bordered">
<thead>
<tr class="d-table-row">
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyName)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyDepartment)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyDesignation)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyAddress)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyEmail)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyPhoneNumber)</th>
<th>@Html.DisplayNameFor(o => o.AssociateProfessors.First().FacultyStatus)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var faculty in Model.AssociateProfessors)
{
<tr class="d-table-row">
<td>@Html.DisplayFor(o => faculty.FacultyName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDepartment.DepartmentName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDesignation)</td>
<td>@Html.DisplayFor(o => faculty.FacultyAddress)</td>
<td>@Html.DisplayFor(o => faculty.FacultyEmail)</td>
<td>@Html.DisplayFor(o => faculty.FacultyPhoneNumber)</td>
<td>@Html.DisplayFor(o => faculty.FacultyStatus)</td>
<td><a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@faculty.FacultyId">View Profile</a></td>
</tr>
}
</tbody>
</table>
</div>
@*Assistant Professors*@
<div class="d-flex flex-column">
<a class="navbar-text align-content-center">@Html.DisplayNameFor(o => o.AssistantProfessors): </a>
<table class="table table-bordered">
<thead>
<tr class="d-table-row">
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyName)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyDepartment)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyDesignation)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyAddress)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyEmail)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyPhoneNumber)</th>
<th>@Html.DisplayNameFor(o => o.AssistantProfessors.First().FacultyStatus)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var faculty in Model.AssistantProfessors)
{
<tr class="d-table-row">
<td>@Html.DisplayFor(o => faculty.FacultyName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDepartment.DepartmentName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDesignation)</td>
<td>@Html.DisplayFor(o => faculty.FacultyAddress)</td>
<td>@Html.DisplayFor(o => faculty.FacultyEmail)</td>
<td>@Html.DisplayFor(o => faculty.FacultyPhoneNumber)</td>
<td>@Html.DisplayFor(o => faculty.FacultyStatus)</td>
<td><a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@faculty.FacultyId">View Profile</a></td>
</tr>
}
</tbody>
</table>
</div>
@*Lecturers*@
<div class="d-flex flex-column">
<a class="navbar-text align-content-center">@Html.DisplayNameFor(o => o.Lecturers): </a>
<table class="table table-bordered">
<thead>
<tr class="d-table-row">
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyName)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyDepartment)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyDesignation)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyAddress)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyEmail)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyPhoneNumber)</th>
<th>@Html.DisplayNameFor(o => o.Lecturers.First().FacultyStatus)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var faculty in Model.Lecturers)
{
<tr class="d-table-row">
<td>@Html.DisplayFor(o => faculty.FacultyName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDepartment.DepartmentName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDesignation)</td>
<td>@Html.DisplayFor(o => faculty.FacultyAddress)</td>
<td>@Html.DisplayFor(o => faculty.FacultyEmail)</td>
<td>@Html.DisplayFor(o => faculty.FacultyPhoneNumber)</td>
<td>@Html.DisplayFor(o => faculty.FacultyStatus)</td>
<td><a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@faculty.FacultyId">View Profile</a></td>
</tr>
}
</tbody>
</table>
</div>
</body>
It can be seen that for 4 different designations, namely, Professor, AssociateProfessor, AssistantProfessor and Lecturer, all of which are of the type Designation which is an Enum:
public Enum Designation
{
Professor,
AssociateProfessor,
AssistantProfessor,
Lecturer
}
I had to write the same code framework, namely,
@*Professors*@
<div class="d-flex flex-column">
<a class="navbar-text align-content-center">@Html.DisplayNameFor(o => o.Professors): </a>
<table class="table table-bordered">
<thead>
<tr class="d-table-row">
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyName)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyDepartment)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyDesignation)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyAddress)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyEmail)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyPhoneNumber)</th>
<th>@Html.DisplayNameFor(o => o.Professors.First().FacultyStatus)</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (Faculty faculty in Model.Professors)
{
<tr class="d-table-row">
<td>@Html.DisplayFor(o => faculty.FacultyName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDepartment.DepartmentName)</td>
<td>@Html.DisplayFor(o => faculty.FacultyDesignation)</td>
<td>@Html.DisplayFor(o => faculty.FacultyAddress)</td>
<td>@Html.DisplayFor(o => faculty.FacultyEmail)</td>
<td>@Html.DisplayFor(o => faculty.FacultyPhoneNumber)</td>
<td>@Html.DisplayFor(o => faculty.FacultyStatus)</td>
<td><a class="nav-link" asp-action="Profile" asp-controller="Faculty" asp-route-Id="@faculty.FacultyId">View Profile</a></td>
</tr>
}
</tbody>
</table>
</div>
4 times! (changing the Professors to Lecturers and the likes, of course)
This seems redundant, and I wanted to know if there was a way that would allow me to write the framework only once which will run for all 4 types of Designation. That way, even if the any more Designations get added later, it'll automatically be accomodated in the current code.
Professors (and its sister properties) are of the type IList<Faculty>, where Faculty class is as follows:
public class Faculty
{
[Required]
public string FacultyId { get; set; }
[Required]
public string FacultyName { get; set; }
[Required]
public FacultyStatus FacultyStatus { get; set; }
[Required]
public Designation FacultyDesignation { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string FacultyEmail { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
public string FacultyPhoneNumber { get; set; }
[Required]
public string FacultyAddress { get; set; }
[Required]
public int FacultyExperience { get; set; }
[Required]
public string FacultyQualifications { get; set; }
[Required]
public string FacultyDescription { get; set; }
public Department HODDepartment { get; set; }
[ForeignKey("FacultyDepartment")]
public string FacultyDepartmentId { get; set; }
public Department FacultyDepartment{ get; set; }
}
I tried an approach using reflection (available in the previous version of the post) not very succesfully. I am guessing, that some version of ForEach loop will be required, which will loop over an object of Enum.GetNames(typeof(Designation)).Cast<Designation>(). However, I am unable to figure out the Reflection constructs I'll need, for I am pretty new to the concept of Reflection. I need someone to point me in the right direction.
I'm working off of this as a base of what your domain resembles based on your question.
What we need here is reflection. Now, we'll iterate the Enum.GetValues() rather than the GetNames() and find the appropriate Model property based on the custom attribute we assigned. If your Model's properties have the same name as the enum value, you can throw out the DesignationAttribute bits. In the view, we do your same loop basically, but immediately lookup the property we're working with via reflection. (research more on this topic to get a better understanding, no need to regurgitate basic reflection here).
I get your main Model DisplayName from the reflected ProperyInfo that we already have in our enum loop. I do this via a ReflectionHelpers static method but you can move this method anywhere, such as a top-level library.
We then use modelProperty.GetValue(Model) to reflect the value of the property back from the Model instance so we can iterate the list contents of that property.
The rest is just as you had it previously.