Let's say i have this
#using MvcApplication6.Models;
#model List<Employee>
I
I have 5 rows/records of Employee and i passed it to my view. They have id, firstname,lastname,gender,department.
I know that i can use foreach to loop through all of them but what if i want to access a specific record from the list?
I get indexing error if i do something like this :
#Html.LabelFor(model => model[0].firstname)
I just want to display a specific record from my page. What should i do to achieve that result?
full code
#using MvcApplication6.Models;
#model IEnumerable<Employee>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New record", "Create")
</p>
#Html.LabelFor(model => model.Model[0].firstname)
<p>#Html.ActionLink("Check departments", "Index", "Department")</p>
<table border="1">
<tr>
<th>
#Html.DisplayNameFor(model => model.id)
</th>
<th>
#Html.DisplayNameFor(model => model.firstname)
</th>
<th>
#Html.DisplayNameFor(model => model.lastname)
</th>
<th>
#Html.DisplayNameFor(model => model.gender)
</th>
<th>
#Html.DisplayNameFor(model => model.department)
</th>
<th>Action</th>
</tr>
#foreach (Employee item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.id)
</td>
<td>
#Html.DisplayFor(modelItem => item.firstname)
</td>
<td>
#Html.DisplayFor(modelItem => item.lastname)
</td>
<td>
#Html.DisplayFor(modelItem => item.gender)
</td>
<td>
#Html.DisplayFor(modelItem => item.department)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.id }) |
#Html.ActionLink("Details","Details", "Employee", new { id=item.id },null) |
#Html.ActionLink("Delete", "Delete", new { id=item.id }) |
#Html.DisplayFor(modelItem => item.Players[0])
</td>
</tr>
}
</table>
You are trying to access the property model on an instance of your collection. Instead, simply reference the model by index to access the firstname property:
#Html.LabelFor(m => m[0].firstname)
The lambda expression exposes the Model, which in your case is a collection. In addition, you should resolve your #model to List<> instead of IEnumerable<> to prevent lazy evaluation.
Related
I was trying to make a list of all the users and I tried this code and this one is giving me an exception of NullReferenceException I tried to type it manually and then when it was making trouble I tried to scaffold it using List T4 Template but it still didnt work out
#model IEnumerable<Aroma.Models.user>
#{
ViewBag.Title = "ManageUsers";
}
<h2>ManageUsers</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.username)
</th>
<th>
#Html.DisplayNameFor(model => model.pass)
</th>
<th>
#Html.DisplayNameFor(model => model.email)
</th>
<th>
#Html.DisplayNameFor(model => model.usertype.name)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.username)
</td>
<td>
#Html.DisplayFor(modelItem => item.pass)
</td>
<td>
#Html.DisplayFor(modelItem => item.email)
</td>
<td>
#Html.DisplayFor(modelItem => item.usertype.name)
</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>
}
</table>
You are trying to display the name of the property on the foreach iteration. That's probably it, since I dont think it has the necessary Attribute to do so.
You should just do:
#foreach (var item in Model) {
<tr>
<td>
#item.username
</td>
<td>
#item.pass
</td>
<td>
#item.email
</td>
<td>
#item.usertype.name
</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>
}
I have a view which has a table that displays values. I would like to add a drop down that filters the results of the status column. So for example if I select "Reviewing", only records with the "Reviewing" status will appear. Below I have my view.
#model IEnumerable<DRT.Models.Master>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.RequestType.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Reviewer.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Status.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.ProjectName)
</th>
<th>
#Html.DisplayNameFor(model => model.ProjectLocation)
</th>
<th>
#Html.DisplayNameFor(model => model.Requestor)
</th>
<th>
#Html.DisplayNameFor(model => model.DateReceived)
</th>
<th>
#Html.DisplayNameFor(model => model.ReviewCompDate)
</th>
<th>
#Html.DisplayNameFor(model => model.ProjectFolerLink)
</th>
<th>
#Html.DisplayNameFor(model => model.ModellingReferralDate)
</th>
<th>
#Html.DisplayNameFor(model => model.ModellingReviewCompletionDate)
</th>
<th>
#Html.DisplayNameFor(model => model.SewerMaintenanceReferralDate)
</th>
<th>
#Html.DisplayNameFor(model => model.SewerMaintenanceReviewCompletionDate)
</th>
<th>
#Html.DisplayNameFor(model => model.FlowControlReferralDate)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.RequestType.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reviewer.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProjectName)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProjectLocation)
</td>
<td>
#Html.DisplayFor(modelItem => item.Requestor)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateReceived)
</td>
<td>
#Html.DisplayFor(modelItem => item.ReviewCompDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProjectFolerLink)
</td>
<td>
#Html.DisplayFor(modelItem => item.ProjectComments)
</td>
<td>
#Html.DisplayFor(modelItem => item.DischargeLocationID)
</td>
<td>
#Html.DisplayFor(modelItem => item.DischargeDistrict)
</td>
<td>
#Html.DisplayFor(modelItem => item.SystemType)
</td>
<td>
#Html.DisplayFor(modelItem => item.AffectedRequlator)
</td>
<td>
#Html.DisplayFor(modelItem => item.StartDateOfDischarge)
</td>
<td>
#Html.DisplayFor(modelItem => item.DurationOfDischarge)
</td>
<td>
#Html.DisplayFor(modelItem => item.RequestFlowRate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ApprovedDischargeRate)
</td>
<td>
#Html.DisplayFor(modelItem => item.DischargeLocationComments)
</td>
<td>
#Html.DisplayFor(modelItem => item.ModellingReferralDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.ModellingReviewCompletionDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.SewerMaintenanceReferralDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.SewerMaintenanceReviewCompletionDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.FlowControlReferralDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.MasterId }) |
#Html.ActionLink("Details", "Details", new { id=item.MasterId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.MasterId })
</td>
</tr>
}
</table>
You basically need a SELECT element in your view and when use selects something, you may post the selected value to the action method where you will use this value when getting data from your db.
You may create a new view model
public class ListAndSearchVm
{
public IEnumerable<DRT.Models.Master> Data { set;get;}
public IEnumerable<SelectListItem> Statuses { set;get;}
public string SelectedStatus { set;get;}
}
Now in your GET action, you need to load the Statuses property of the view model and the Data property. Have a parameter to accept the selected option value from your status filter dropdown. Based on the value of this parameter get the filtered data.
public ActionResult Index(string selectedStatus="")
{
var vm= new ListAndSearchVm();
//Hard coding 2 items for demo. You can read this from your db table
vm.Statuses = new List<SelectListItem> {
new SelectListITem { Value="Open", Text="Open"},
new SelectListITem { Value="Closed", Text="Closed"},
};
var data= dbContext.Masters;
if(!String.IsNullOrEmpty(selectedStatus))
{
data = data.Where(f=>f.Status.Name==selectedSatatus);
}
vm.Data = data.ToList();
return View(vm);
}
Now in your view
#model ListAndSerchVm
#using(Html.BeginForm("Index","YourControllerName",FormMethod.Get))
{
<label> Select a status</label>
#Html.DropDownListFor(f=>f.SelectedStatus,Model.Statuses,"Select")
<input type="submit" value="Filter" />
}
<table>
<tr>
<th>Request type</th>
<th>Reviewer</th>
<th>Status</th>
</tr>
#foreach(var item in Model.Data)
{
<tr>
<td>#item.RequestType.Name)</td>
<td>#item.Reviewer.Name</td>
<td>#item.Status.Name</td>
</tr>
}
</table>
Just a quick question.
#using MvcApplication6.Models;
#model IEnumerable<Employee>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New record", "Create")
</p>
<p>#Html.ActionLink("Check departments", "Index", "Department")</p>
<table border="1">
<tr>
<th>
#Html.DisplayNameFor(model => model.id)
</th>
<th>
#Html.DisplayNameFor(model => model.firstname)
</th>
<th>
#Html.DisplayNameFor(model => model.lastname)
</th>
<th>
#Html.DisplayNameFor(model => model.gender)
</th>
<th>
#Html.DisplayNameFor(model => model.department)
</th>
<th>Action</th>
</tr>
#foreach (Employee item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.id)
</td>
<td>
#Html.DisplayFor(modelItem => item.firstname)
</td>
<td>
#Html.DisplayFor(modelItem => item.lastname)
</td>
<td>
#Html.DisplayFor(modelItem => item.gender)
</td>
<td>
#Html.DisplayFor(modelItem => item.department)
</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 }) |
#Html.DisplayFor(modelItem => item.Players[0])
</td>
</tr>
}
</table>
And this is how i passed my list:
public ActionResult Index()
{
EmployeeContext emp = new EmployeeContext();
List<Employee> adep = emp.Employees.ToList();
return View(adep);
}
Why do i have to declare it as IEnumerable on my view even though the one that i am passing is just a List ? Like if i will change IEnumerable to List, i will get errors specifically on this line of code:
#Html.DisplayNameFor(model => model.id)
I was testing it on my other views and it's declared as a list :
#model List<MvcApplication6.Models.Employee>
It works as intended although no DisplayNameFor and DisplayFor are involved.
IEnumerable
You can use IEnumerable<T> when you only need iteration (See here for a full list: https://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx), It means that If all you want to do with the list is foreach, you should return an IEnumerable<T>.
List
You can use List<T> for a list of objects that needs to be iterated through, modified, sorted, etc (See here for a full list: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).
So, I am new to MVC, and I have a partial view with IEnumerable model, in which I have few fields I would like to be editable.
#model IEnumerable<Allocations>
<p>
#Html.ActionLink("Create New", "AddAllocation", "Admin")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Percentage)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.EditorFor(modelItem => item.Percentage)
</td>
<td>#Html.HiddenFor(modelItem => item.ID)</td>
<td>
#Html.ActionLink("Save", "EditAllocation", "Admin", null, new { id= item.ID })
</td>
</tr>
}
</table>
I want to be able to pass the entered/changed textbox values to the controller action. I understand, I can do that using JQuery if it wasn't a IEnumerable model view. I might be missing something here, and would appreciate if someone could direct me in the right direction.
In my MVC5 Application, I am currently dealing with 2 tables:
[MemberDues] -- [Id], [Year], [Display], [Amount]
[MemberDuesReceived] -- [Id], [MemberDuesId], [MemberOrgId], [PaidByUserId], [TransactionId], [Paid], [DatePaid], [PaymentMethod], [PayPalPaymentId], [PayPalPayerId], [PayPalPaymentState]
I have a View (below) where I display the records for Different [MemberDues]:
#model IEnumerable<PROJECTdev.Models.MemberDues>
<script type="text/javascript" src="~/Areas/Admin/Scripts/Dues/Index.min.js"></script>
<div id="alert" style="display: none;"></div>
<table class="table table-striped">
<thead>
<tr>
<th class="col-md-2">
</th>
<th>
#Html.DisplayNameFor(model => model.Year)
</th>
<th>
#Html.DisplayNameFor(model => model.Display)
</th>
<th>
#Html.DisplayNameFor(model => model.Amount)
</th>
<th>View</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
<span class="glyphicon glyphicon-pencil"></span> Edit
<span class="glyphicon glyphicon-floppy-remove"></span> Delete
</td>
<td>
#Html.DisplayFor(modelItem => item.Year)
</td>
<td>
#Html.EditorFor(modelItem => item.Display, new { htmlAttributes = new { #class = "form-control pull-left", style = "height: 20px; width: 20px;", onclick = "disableEnableDues(" + item.Id + ", this)" } })
</td>
<td>
#Html.DisplayFor(modelItem => item.Amount)
</td>
<td>
<span class="glyphicon glyphicon-list-alt"></span> Paid
</td>
</tr>
}
</tbody>
</table>
What I am attempting to do is have, when the [Paid] button (link) is clicked, a View is brought up which lists all the Member Organizations which have paid their dues. To do this, I have to query [MemberDuesReceived] for the appropriate [MemberDuesId] and return all records which have the matching [MemberDuesId] & [Paid] == true. This I have attempted to below:
public async Task<ActionResult> DuesPaidMembers(int id)
{
MemberDues memberDues = await db.MemberDues.FindAsync(id);
return View(db.MemberDuesReceived.Where(mdr => mdr.MemberDuesId == memberDues.Id && mdr.Paid).ToListAsync());
}
I then created a view called DuesPaidMembers.cshtml which is below:
#model IEnumerable<PROJECTdev.Models.MemberDuesReceived>
#{
ViewBag.Title = "DuesPaidMembers";
Layout = "~/Areas/Admin/Views/Shared/_LayoutAdmin.cshtml";
}
<h2>DuesPaidMembers</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.MemberDues.Id)
</th>
<th>
#Html.DisplayNameFor(model => model.MemberOrganization.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.PaidByUser.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.TransactionId)
</th>
<th>
#Html.DisplayNameFor(model => model.Paid)
</th>
<th>
#Html.DisplayNameFor(model => model.DatePaid)
</th>
<th>
#Html.DisplayNameFor(model => model.PaymentMethod)
</th>
<th>
#Html.DisplayNameFor(model => model.PayPalPaymentId)
</th>
<th>
#Html.DisplayNameFor(model => model.PayPalPayerId)
</th>
<th>
#Html.DisplayNameFor(model => model.PayPalPaymentState)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.MemberDues.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.MemberOrganization.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaidByUser.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.TransactionId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Paid)
</td>
<td>
#Html.DisplayFor(modelItem => item.DatePaid)
</td>
<td>
#Html.DisplayFor(modelItem => item.PaymentMethod)
</td>
<td>
#Html.DisplayFor(modelItem => item.PayPalPaymentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.PayPalPayerId)
</td>
<td>
#Html.DisplayFor(modelItem => item.PayPalPaymentState)
</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>
}
</table>
Currently however, when I click the button, my appropriate Controller Action (DuesPaidMember()) is called, but when the line return View(db.MemberDuesReceived.Where(mdr => mdr.MemberDuesId == memberDues.Id && mdr.Paid).ToListAsync()); is hit, I receive the following error:
The model item passed into the dictionary is of type 'System.Threading.Tasks.Task1[System.Collections.Generic.List1[PRISMdev.Models.MemberDuesReceived]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[PRISMdev.Models.MemberDuesReceived]'.`
Does anyone have any thoughts on what I'm apparently doing wrong?
The following line is to blame.
return View(db.MemberDuesReceived
.Where(mdr => mdr.MemberDuesId == memberDues.Id && mdr.Paid)
.ToListAsync());
You are passing the result of ToListAsync as your model, which is a Task<List<PRISMdev.Models.MemberDuesReceived>>.
Instead, insert await so that the task is run and the resulting value of type List<PRISMdev.Models.MemberDuesReceived> is returned as your model:
return View(await db.MemberDuesReceived
.Where(mdr => mdr.MemberDuesId == memberDues.Id && mdr.Paid)
.ToListAsync());