I have a requirement to show 1 column from different model on MVC. Im a first timer in mvc so im not really familiar with lambda convention...
So far I have this classes
article.cs
public class Article
{
[Key]
public int bl_id { get; set; }
[Column("bl_title")]
public string Title { get; set; }
[Column("bl_img")]
public string Image { get; set; }
[Column("bl_summ")]
public string Summary { get; set; }
[AllowHtml]
[Column("bl_content")]
public string Content { get; set; }
[Column("bl_author")]
public string Author { get; set; }
[DisplayFormat(ApplyFormatInEditMode =true, DataFormatString ="{0:MM/dd/yyyy}")]
[Column("bl_dtecrt")]
public DateTime DateCreated { get; set; }
}
the next class is the comments:
comments.cs
public class Comments
{
[Key]
public int ic_id { get; set; }
public int ic_blid { get; set; }
public string ic_comment { get; set; }
public DateTime ic_crtdte { get; set; }
public string ic_pcname { get; set; }
}
What I need is to have relate the Title Column from the Articles.cs models to the set of Comments... if it were on sql i could do a select query in this manner: select article.title, comments.ic_comment from articles, comments where articles.bl_id = comments.ic_blid
So far, the solution i tried is create a join in the controller then throw it to the view...
articlescontroller.cs
public ActionResult Comments()
{
var comm = from c in db.Comments
join a in db.Articles
on c.ic_blid equals a.bl_id
select c;
return View("Comments", comm.ToList());
}
EDIT: View
Comments.cshtml
#model IEnumerable<WebApplication3.Models.Comments>
#{
ViewBag.Title = "Comments";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Html.DisplayNameFor(model => model.ic_comment)
</th>
<th>
#Html.DisplayNameFor(model => model.ic_crtdte)
</th>
<th>
#Html.DisplayNameFor(model => model.ic_pcname)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
#Html.DisplayFor(ModelItem => item.Article.Title)
<tr>
<td>
#Html.DisplayFor(modelItem => item.ic_comment)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_crtdte)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_pcname)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ic_id }) |
#Html.ActionLink("Details", "Details", new { id=item.ic_id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ic_id })
</td>
</tr>
}
</table>
but my view is not catering the columns from the articles.
So my question is, how can I incorporate 1 or more columns from my Articles Model to my Comments Models then show them in the view? The reason behind this module is to maintain the comments done in the articles posted.
I tried putting this in the comments model:
public virtual Article Article { get; set; }
but i dont know how to use.
I hope you can help me...
You will first have to correct your Article class.
Since a Article can have many comments you need a property describing the same
(Please note the code is not tested)
public class Article{
...
public List<Comment> Comments {get; set;}
...
}
Now the place where you are trying to retrieve the data, include comments as well. Something like this:
public ActionResult Comments()
{
var comm = db.Article.Include(x=>x.Comments).ToList();
// This will get All article and include comments if any for each article.
return View("Comments", comm.ToList());
}
In your view you would have to iterate Comment for individual Article
#{
ViewBag.Title = "Comments";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#foreach (var item in Model) {
#Html.DisplayFor(ModelItem => item.Article.Title)
<tr>
<td>
#Html.DisplayFor(modelItem => item.Comments.ic_comment)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments.ic_crtdte)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comments.ic_pcname)
</td>
<td
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ic_id }) |
#Html.ActionLink("Details", "Details", new { id=item.ic_id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ic_id })
</td>
</tr>
}
This can be done in below 2 ways. Create a Class which contains Comments and Title. Construct the object from this select result and pass it to Model.
Or have a Navigation property for comments in Article class. And modify LINQ-SQL as below.
Artice class
public class Article
{
[Key]
public int bl_id { get; set; }
[Column("bl_title")]
public string Title { get; set; }
[Column("bl_img")]
public string Image { get; set; }
[Column("bl_summ")]
public string Summary { get; set; }
[AllowHtml]
[Column("bl_content")]
public string Content { get; set; }
[Column("bl_author")]
public string Author { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
[Column("bl_dtecrt")]
public DateTime DateCreated { get; set; }
public virtual ICollection<Comments> Comments { get; set; }
}
Query
var comments1 = from c in comments
join a in articles
on c.ic_blid equals a.bl_id
select a;
View as below
#model IEnumerable<WebApplication1.Models.Article>
#{
ViewBag.Title = "Comments";
}
<h2>Comments</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>Title</th>
<th>ic_comment</th>
<th>ic_blid</th>
<th>ic_crtdte</th>
<th>ic_pcname</th>
</tr>
#foreach (var item1 in Model)
{
foreach (var item in item1.Comments)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item1.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_comment)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_blid)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_crtdte)
</td>
<td>
#Html.DisplayFor(modelItem => item.ic_pcname)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ic_id }) |
#Html.ActionLink("Details", "Details", new { id=item.ic_id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ic_id })
</td>
</tr>
}
}
</table>
Need to declare the Model for the View as dynamic. Please see
https://www.aspsnippets.com/Articles/Display-data-in-Single-View-from-Multiple-Tables-in-ASPNet-MVC.aspx
if it helps.
Also modify as below
var comm = from c in db.Comments
join a in db.Articles
on c.ic_blid equals a.bl_id
select new {c,a.title};
The answer of #Jja is the accepted answer but since i had a trouble with navigation property...
As per this stackoverflow link: The Name value should be a valid navigation property name.
My problem when using ForeignKey, the virtual table you're connecting to must have the same name on the [ForeignKey("")] tag. Before, my Comments class was defined as this:
[Table("Intranet_Comments")]
public class Intranet_Comments
{
[Key]
public int ic_id { get; set; }
[ForeignKey("Intranet_Article")]
public int ic_blid { get; set; }
public string ic_comment { get; set; }
public DateTime ic_crtdte { get; set; }
public string ic_pcname { get; set; }
public virtual Article Article { get; set; }
}
And it throws navigation error... i re-wrote this class into:
[Table("Intranet_Comments")]
public class Intranet_Comments
{
[Key]
public int ic_id { get; set; }
[ForeignKey("Article")]
public int ic_blid { get; set; }
public string ic_comment { get; set; }
public DateTime ic_crtdte { get; set; }
public string ic_pcname { get; set; }
public virtual Article Article { get; set; }
}
The foreign key property name must be the same name as the virtual property set..
i hope this helps!
Related
I want to build my view and join 2 tables using LINQ but i got this error in view in foreach in Model
#foreach (var item in Model)
This is my classes :
public partial class Lab_orders_Cash
{
[Display(Name = "Order Id")]
public int cash_order_id { get; set; }
[Display(Name = "Order Date")]
public Nullable<System.DateTime> order_date { get; set; }
[Display(Name = "MRN File No.")]
public Nullable<int> patient_no { get; set; }
public string invoice_order_no { get; set; }
public string order_description { get; set; }
public string user_id { get; set; }
[Display(Name = "Order Status")]
public Nullable<int> order_status { get; set; }
public Nullable<int> catid { get; set; }
public Nullable<int> almansoor { get; set; }
public Nullable<int> prio_id { get; set; }
}
public partial class Lab_Sample_status
{
public int status_id { get; set; }
public string status_name { get; set; }
}
this my controller :
public ActionResult ordersCash()
{
var OrdersList = from o in db.Lab_orders_Cash
Join os in db.Lab_Sample_status on o.order_status equals os.status_id into tablestatus
where o.patient_no == (int)Session["UserpatientNo"]
select o;
return View(OrdersList);
}
In view i used Tuples :
#using AljawdahNewSite.Models;
#model Tuple<Lab_orders_Cash,Lab_Sample_status>
#{
#{
ViewBag.Title = "ordersCash";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
}
<h2>Orders List </h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.cash_order_id)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.order_date)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item1.patient_no)
</th>
<th>
#Html.DisplayNameFor(Tuple => Tuple.Item2.status_name)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.cash_order_id)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.order_date)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item1.patient_no)
</td>
<td>
#Html.DisplayFor(Tuple => Tuple.Item2.status_name)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id=item.cash_order_id })
</td>
</tr>
}
</table>
in foreach when select model i got this error , also i tried to use IEnumerable in view like this
#model Tuple<IEnumerable<Lab_orders_Cash>,IEnumerable<Lab_Sample_status>>
but same error when i select Model it shows the error
What i need to change to solve this error.
you can use another way like the following steps :
1- Create new class and put your tables in that class
public class Tables
{
public Lab_orders_Cash LabOrdersCash { get; set; }
public Lab_Sample_status LabOrderStatus { get; set; }
}
2- Write the controller like the following :
public ActionResult ordersCash()
{
List<Lab_orders_Cash> ordercash = db.Lab_orders_Cash.ToList();
List<Lab_Sample_status> samplestatus = db.Lab_Sample_status.ToList();
var OrdersList = from o in ordercash
join st in samplestatus on o.order_status equals st.status_id
where o.patient_no == (int)Session["UserpatientNo"]
select new Tables{ LabOrdersCash = o , LabOrderStatus = st };
return View(OrdersList);
}
3- Create your view use the following code :
#model IEnumerable<AljawdahNewSite.Models.Tables>
#{
ViewBag.Title = "ordersCash";
Layout = "~/Views/Shared/_LayoutPatients.cshtml";
}
<h2>Orders List</h2>
<table class="table">
<tr>
<td> Order No. </td>
<td> order date </td>
<td> Patient No </td>
<td> Status </td>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#item.LabOrdersCash.cash_order_id</td>
<td>#item.LabOrdersCash.order_date</td>
<td>#item.LabOrdersCash.patient_no</td>
<td>#item.LabOrderStatus.status_name</td>
</tr>
}
</table>
This way more effective and easily you can add all your tables in this tables class and call this class any where in your project and easier than Tuples.
I'm trying to get specific data from different tables based on some requirements, The program is supposed to take some columns of choosing from tables: Contatti, Contacts and Companies which are at different locations and bring them together.
Contact is connected to Companies through CompanyID
What i want is to display the company name basing on the CompanyID field in Contact table. The problem is that i iterate through a list to get the data in the view, and because of that i can't seem to get a company name based on the company ID attribute which is the Contact Foreign Key to the Companies table, what i get is all the companies names, because they're in the same list.
I'm sure there is an easy way to do this but this is a new world for me, thank you for any help.
Contact Model:
public class Contact
{
[Key]
public int ContactId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[ForeignKey("Companies")]
public int CompanyId { get; set; }
public virtual ICollection<Companies> Companies { get; set; }
[Required]
//public virtual Contatti Contatti { get; set; }
public virtual ICollection<Contatti> Contatti { get; set; }
}
Companies model:
public class Companies
{
[Key]
public int CompanyId { get; set; }
public string CompanyName { get; set; }
public string CompanyAddress { get; set; }
public string CompanyCity { get; set; }
public string CompanyState { get; set; }
public string CompanyZip { get; set; }
public string CompanyArea { get; set; }
}
Controller:
public ActionResult Index(String Page)
{
ContactsUni2 CU = new ContactsUni2();
CU.Contattis = db2.Contatti.ToList();
CU.Contacts = db.Contacts.ToList();
CU.Companies = db.Companies.ToList();
List<ContactsUni2> contactlist = new List<ContactsUni2>();
contactlist.Add(CU);
return View(contactlist);
}
View:
#foreach (var item in Model)
{
for (int i = 0; i < item.Contacts.Count; i++)
{
<tr>
<td>
#item.Contacts[i].ContactId
</td>
<td>
#item.Contacts[i].Name
</td>
<td>
#item.Contacts[i].Address
</td>
<td>
#item.Contacts[i].CompanyId
</td>
#if (#item.Contacts[i].CompanyId == item.Companies[i].CompanyId)
{
<td>
#item.Companies[i].CompanyName
</td>
<td>
#item.Companies[i].CompanyCity
</td>
<td>
#item.Companies[i].CompanyArea
</td>
}
}
</tr>
<tr>
<td>
#item.Contattis[i].ContattoID
</td>
<td>
#item.Contattis[i].Nome
</td>
<td>
#item.Contattis[i].Citta
</td>
<td>
#item.Contattis[i].CodicePostale
</td>
<td>
#item.Contattis[i].Email
</td>
</tr>
}
}
</table>
</body>
</html>
You can try populating the company collection for each of your contacts and then fix the view to access its own member directly instead of looking for it in the Companies list.
public ActionResult Index(String Page)
{
ContactsUni2 CU = new ContactsUni2();
CU.Contattis = db2.Contatti.ToList();
CU.Contacts = db.Contacts.ToList();
CU.Companies = db.Companies.ToList();
foreach(var contact in CU.Contacts)
{
contact.Companies = CU.Companies
.Where(com => com.CompanyId == contact.CompanyId)
.ToList();
}
List<ContactsUni2> contactlist = new List<ContactsUni2>();
contactlist.Add(CU);
return View(contactlist);
}
In the view, you can replace:
#if (#item.Contacts[i].CompanyId == item.Companies[i].CompanyId)
{
<td>
#item.Companies[i].CompanyName
</td>
<td>
#item.Companies[i].CompanyCity
</td>
<td>
#item.Companies[i].CompanyArea
</td>
}
With something like this: (Notice that the if statement is removed)
<td>
#item.Contacts[i].Companies[0].CompanyName
</td>
<td>
#item.Contacts[i].Companies[0].CompanyCity
</td>
<td>
#item.Contacts[i].Companies[0].CompanyArea
</td>
EDIT: Since ICollection does not support indexes, the companies collection should be changed from
public virtual ICollection<Companies> Companies { get; set; }
to
public virtual IList<Companies> Companies { get; set; }
Or any other type of collection supporting indexes.
Very new to ASP.NET MVC and Entity Framework.
I'm trying to set up a database with three tables, when I run my code and go to the page "Tickets", I get the following exception:
There is already an open DataReader associated with this Command which must be closed first.
Class 1
public class Ticket
{
[Key]
public int ID { get; set; }
public string Description { get; set; }
[ForeignKey("Practice")]
public int PracticeID { get; set; }
public string Contact { get; set; }
public string Category { get; set; }
//insert Support type using ViewBag (Support type listed in Models.Practices)
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime Due { get; set; }
[DataType(DataType.DateTime)]
[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}", ApplyFormatInEditMode = true)]
public DateTime TimeLogged { get; set; }
[ForeignKey("Consultant")]
public int ConsultantID { get; set; }
public string ConsultantName { get; set; }
public string Status { get; set; }
public virtual Practice Practice { get; set; }
public virtual Consultant Consultant { get; set; }
}
Class 2:
public class Practice
{
[Key]
public int PracticeID { get; set; }
[Display(Name = "Practice Name")]
public string PracName { get; set; }
[Display(Name = "Practice Number")]
public int PracNumber { get; set; }
public string Contact { get; set; }
[Display(Name = "Support Type")]
public string Support { get; set; }
public string Tel { get; set; }
public string Cell { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public string Address { get; set; }
public virtual List<Ticket> Ticket { get; set; }
}
Class 3:
public class Consultant
{
[Key]
public int ConsultantID { get; set; }
public string Name { get; set; }
[DataType(DataType.Password)]
public string Password { get; set; }
public string Role { get; set; }
public virtual List<Ticket> Ticket { get; set; }
}
I have a search function in my TicketsController:
public ActionResult Index(string searchString, string Consultants)
{
var UserLst = new List<string>();
var UserQry = from d in db.Consultants
orderby d.Name
select d.Name;
UserLst.AddRange(UserQry.Distinct());
ViewBag.User = new SelectList(UserLst);
var tickets = from m in db.Ticket
select m;
if (!String.IsNullOrEmpty(searchString))
{
tickets = tickets.Where(s => s.Description.Contains(searchString));
}
if (!string.IsNullOrEmpty(Consultants))
{
tickets = tickets.Where(x => x.ConsultantName == Consultants);
}
return View(tickets);
}
The error seems to be coming from the HTML code in the INDEX.
#model IEnumerable<MAD.Models.Ticket>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<p>
User: #Html.DropDownList("User", "All")
Description: #Html.TextBox("SearchString") <br />
<input type="submit" value="Search" />
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Consultant.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Practice.PracName)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.Contact)
</th>
<th>
#Html.DisplayNameFor(model => model.Category)
</th>
<th>
#Html.DisplayNameFor(model => model.Due)
</th>
<th>
#Html.DisplayNameFor(model => model.TimeLogged)
</th>
<th>
#Html.DisplayNameFor(model => model.Status)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Consultant.Name)--ERROR CODE
</td>
<td>
#Html.DisplayFor(modelItem => item.Practice.PracName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Contact)
</td>
<td>
#Html.DisplayFor(modelItem => item.Category)
</td>
<td>
#Html.DisplayFor(modelItem => item.Due)
</td>
<td>
#Html.DisplayFor(modelItem => item.TimeLogged)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</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 have passed in an IQueryable from your controller as your model - called tickets in the controller method. When you start your for each loop on the model, EF starts retrieving results through the connection, but it doesn't actually finish using the connection for this until the end of the loop. The line which is causing the error is trying to access the related Consultant property, which triggers EF to try to load that from the DB, but that causes an exception because you are still in the loop and it is still using the connection to retrieve the tickets query.
The easiest way around this is to force EF to retrieve the results before the loop. I would go for changing the final line in the controller to View (tickets.ToArray) or similar.
I'm not sure, but enabling multiple active result sets might also fix this.
How can I achieve the same result using my view Model
Model 1:
public class Unit
{
public int Id { get; set; }
[Required]
public string UnitName { get; set; }
public virtual ICollection<Staff> Staffs { get; set; }
}
Model 2:
public class Staff
{
public int Id { get; set; }
public string FullName { get; set; }
public int UnitId { get; set; }
public virtual Unit Unit { get; set; }
}
My ViewModel:
public class StaffVM
{
public int Id { get; set; }
public string FullName { get; set; }
public int UnitId { get; set; }
public string UnitName { get; set; }
}
Controller Index function:
// GET: Staffs
public ActionResult Index()
{
var query = from c in db.MyStaff
join d in db.MyUnit on c.UnitId equals d.Id
select new StaffVM
{
Id = c.Id,
FullName = c.FullName,
UnitName = d.UnitName
};
ViewBag.query = query;
return View();
}
My View Index view:
#model IEnumerable<MVC5WAuth.ViewModels.StaffVM>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FullName)
</th>
<th>
Unit
</th>
<th></th>
</tr>
#foreach (var item in ViewBag.query) {
<tr>
<td>
#item.FullName
</td>
<td>
#item.UnitName
</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>
I'm putting together a fairly simple Code-First MVC5 Inventory Tracking application. I've gotten my app to Seed() and all of my Maintenance tables (Locations, Vendors, Statuses, etc.) I can view/create/edit/delete. I'm now working on the View for my main [INV_Assets] model, but when trying to foreach through the items in my model to display all [INV_Assets] in a table, I get the error: foreach statement cannot operate on variables of type 'Tracker.Models.INV_Assets' because 'Tracker.Models.INV_Assets' does not contain a public definition for 'GetEnumerator'.
Below is the Model for my [INV_Assets]:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using GridMvc.DataAnnotations;
using System.Web.Mvc;
using Tracker.Models;
namespace Tracker.Models
{
[GridTable(PagingEnabled = true, PageSize = 30)]
public class INV_Assets
{
// Setting GridColumn Annotations allows you to use AutoGenerateColumns on view to auto create the Grid based on the model.
public int Id { get; set; }
public int Model_Id { get; set; }
[ForeignKey("Model_Id")]
public virtual INV_Models Model { get; set; }
[Required]
public int Manufacturer_Id { get; set; }
[ForeignKey("Manufacturer_Id")]
public virtual INV_Manufacturers Manufacturer { get; set; }
[Required]
public int Type_Id { get; set; }
[ForeignKey("Type_Id")]
public virtual INV_Types Type { get; set; }
[Required]
public int Location_Id { get; set; }
[ForeignKey("Location_Id")]
public virtual INV_Locations Location { get; set; }
public int Vendor_Id { get; set; }
[ForeignKey("Vendor_Id")]
public virtual INV_Vendors Vendor { get; set; }
[Required]
public int Status_Id { get; set; }
[ForeignKey("Status_Id")]
public virtual INV_Statuses Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public int invoice_number{ get; set; }
[Required]
public string serial_number { get; set; }
[Required]
public string asset_tag_number { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? acquired_date { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime? disposed_date { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime modified_date { get; set; }
public string modified_by { get; set; }
// Flag to specify if item is available? (Not signed out, not auctioned, recycled, etc.)
//public bool available { get; set; }
}
}
[INV_Assets] View:
#using GridMvc.Html
#model Tracker.Models.INV_Assets
#{
ViewBag.Title = "Home Page";
}
<table style="width:100%;">
#foreach (var item in Model) {
<tr>
<td>#Html.DisplayFor(modelItem => item.Status)</td>
<td>#Html.DisplayFor(modelItem => item.Location)</td>
<td>#Html.DisplayFor(modelItem => item.owner)</td>
<td>#Html.DisplayFor(modelItem => item.Type)</td>
<td>#Html.DisplayFor(modelItem => item.Manufacturer)</td>
<td>#Html.DisplayFor(modelItem => item.Model)</td>
<td>#Html.DisplayFor(modelItem => item.Vendor)</td>
<td>#Html.DisplayFor(modelItem => item.description)</td>
<td>#Html.DisplayFor(modelItem => item.asset_tag_number)</td>
<td>#Html.DisplayFor(modelItem => item.serial_number)</td>
<td>#Html.DisplayFor(modelItem => item.ip_address)</td>
<td>#Html.DisplayFor(modelItem => item.mac_address)</td>
<td>#Html.DisplayFor(modelItem => item.po_number)</td>
<td>#Html.DisplayFor(modelItem => item.invoice_number)</td>
<td>#Html.DisplayFor(modelItem => item.cost)</td>
<td>#Html.DisplayFor(modelItem => item.note)</td>
<td>#Html.DisplayFor(modelItem => item.acquired_date)</td>
<td>#Html.DisplayFor(modelItem => item.disposed_date)</td>
<td>#Html.DisplayFor(modelItem => item.created_date)</td>
<td>#Html.DisplayFor(modelItem => item.created_by)</td>
<td>#Html.DisplayFor(modelItem => item.modified_date)</td>
<td>#Html.DisplayFor(modelItem => item.modified_by)</td>
</tr>
}
</table>
I'm not quite sure how to get around this error and wondered if someone with more experience could weigh-in?
I am getting no issue (not sure why) from my [INV_Locations] Model/View when doing the same:
[INV_Locations]:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Tracker.Models
{
public class INV_Locations
{
public int Id { get; set; }
public string location_dept { get; set; }
public string location_room { get; set; }
[Required]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime created_date { get; set; }
[Required]
public string created_by { get; set; }
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")]
public DateTime modified_date { get; set; }
public string modified_by { get; set; }
}
}
[INV_Locations] View:
#model IEnumerable<Tracker.Models.INV_Locations>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3>Maintenance - Locations</h3>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th></th>
<th>
#*#Html.DisplayNameFor(model => model.location_dept)*#
Dept:
</th>
<th>
Room:
</th>
<th>
Created:
</th>
<th>
By:
</th>
<th>
Modified:
</th>
<th>
By:
</th>
</tr>
#foreach (var item in Model) {
<tr>
<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>
<td>
#Html.DisplayFor(modelItem => item.location_dept)
</td>
<td>
#Html.DisplayFor(modelItem => item.location_room)
</td>
<td>
#Html.DisplayFor(modelItem => item.created_date)
</td>
<td>
#Html.DisplayFor(modelItem => item.created_by)
</td>
<td>
#Html.DisplayFor(modelItem => item.modified_date)
</td>
<td>
#Html.DisplayFor(modelItem => item.modified_by)
</td>
</tr>
}
</table>
I tried changing #model Tracker.Models.INV_Assets to #model IEnumerable<Tracker.Models.INV_Assets> on my [INV_Assets] View (just like how my [INV_Locations] View has it. This allows my solution to Build, but when trying to run my application to that View I receive:
System.InvalidOperationException
The model item passed into the dictionary is of type 'Tracker.Models.INV_Assets', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable 1[Tracker.Models.INV_Assets]'.
EDIT - Regarding Shyju's Suggestion:
I changed my HomeController Index() from:
TrackerContext _db = new TrackerContext();
public ActionResult Index(INV_Assets defModel)
{
return View(defModel);
}
to:
TrackerContext _db = new TrackerContext();
public ActionResult Index(INV_Assets defModel)
{
var assetList = new List<Tracker.Models.INV_Assets>();
assetList.Add(defModel);
return View(assetList);
}
While my View now loads, all I get for the Table HTML is:
<table style="width:100%;">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0</td>
<td>0.00</td>
<td></td>
<td></td>
<td></td>
<td>01/01/0001</td>
<td></td>
<td>01/01/0001</td>
<td></td>
</tr>
</table>
I've confirmed that my DBContext has 2 complete [INV_Assets] records in it, but they are not showing up in the View? How do I correctly load all the instances of my [INV_Assets] model into the new assetList variable?
EDIT2:
Modified my Index() to:
TrackerContext _db = new TrackerContext();
public ActionResult Index(INV_Assets defModel)
{
var assetList = _db.INV_Assets.ToList(); // EXCEPTION
return View(assetList);
}
but now, while the solution builds, the application fails when I try to run it. Details below:
Error: An exception of type 'System.Data.DataException' occurred in EntityFramework.dll but was not handled in user code. Additional information: An exception occurred while initializing the database. See the InnerException for details.
Message: An exception occurred while initializing the database. See the InnerException for details.
InnerException: {"The underlying provider failed on Open."}
Source: EntityFramework
Your view is bound to a single instance of Tracker.Models.INV_Assets. But inside your view, you are trying to loop through it. You need to make sure what was passed to your view is a collection, so that we can loop through it.
In INV Assets view, change
#model Tracker.Models.INV_Assets
to
#model List<Tracker.Models.INV_Assets>
Also you need to make sure that you are passing a collection of INV_Assets objects from your action method.
public ActionResult INVAssets()
{
var assetList=new List<Tracker.Models.INV_Assets>();
// Ex : manually adding one record. replace with your actual code to load data
// to do : Add item to the list now
assetList.Add(new INV_Assets { Name ="Test"});
return View(assetList);
}
Edit : As per the edit in the question
Your Index action should not be taking an object of INV_Assets as parameter.
TrackerContext _db = new TrackerContext();
public ActionResult Index()
{
var assetList =_db.INV_Assets.ToList();
return View(assetList);
}
Asssuming INV_Assets is a property on your TrackerContext class. If your property name is different, change the above code to reflect that.
If you want to load load the assets for a specific location, update your Index action method to accept the location id as a parameter.
public ActionResult Index(int id)
{
var assetList =_db.INV_Assets.Where(s=>s.Location_Id==id).ToList();
return View(assetList);
}
So your url to access this page would be like
http://yoursitename/YourControllerName/Index/5
where 5 is a valid location id which has some assets associated with it.