MVC Model is null in view HTTPGET [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 4 years ago.
I have been messing around to find a solution as on of my view which is created using add view from respective action in List Template is giving an exception of System.NullReferenceException: Object reference not set to an instance of an object.
Line 45: </tr>
Line 46:
Line 47: #foreach (var item in Model) {
Line 48: <tr>
Line 49: <td>
Here is my Controller Function
public ActionResult ViewCarpets()
{
IEnumerable<SelectListItem> Qualities = context.Qualities.Select(c => new SelectListItem
{
Value = c.Quality_Id.ToString(),
Text = c.QName
});
IEnumerable<SelectListItem> Suppliers = context.Suppliers.Select(c => new SelectListItem
{
Value = c.Supplier_Id.ToString(),
Text = c.SName
});
IEnumerable<SelectListItem> Designs = context.Design.Select(c => new SelectListItem
{
Value = c.Design_Id.ToString(),
Text = c.DName
});
ViewBag.Quality_Id = Qualities;
ViewBag.Supplier_Id = Suppliers;
ViewBag.Design_Id = Designs;
return View("ViewCarpets");
}
Here is my View
#model IEnumerable<SOC.Models.Product>
#{
ViewBag.Title = "ViewCarpets";
}
<h2>View Carpets</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Design.DName)
</th>
<th>
#Html.DisplayNameFor(model => model.Quality.QName)
</th>
<th>
#Html.DisplayNameFor(model => model.Supplier.SName)
</th>
<th>
#Html.DisplayNameFor(model => model.PColor)
</th>
<th>
#Html.DisplayNameFor(model => model.PBorder_Color)
</th>
<th>
#Html.DisplayNameFor(model => model.PSKU)
</th>
<th>
#Html.DisplayNameFor(model => model.PLength)
</th>
<th>
#Html.DisplayNameFor(model => model.PWidth)
</th>
<th>
#Html.DisplayNameFor(model => model.PCost)
</th>
<th>
#Html.DisplayNameFor(model => model.IsSold)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Design.DName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Quality.QName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Supplier.SName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PColor)
</td>
<td>
#Html.DisplayFor(modelItem => item.PBorder_Color)
</td>
<td>
#Html.DisplayFor(modelItem => item.PSKU)
</td>
<td>
#Html.DisplayFor(modelItem => item.PLength)
</td>
<td>
#Html.DisplayFor(modelItem => item.PWidth)
</td>
<td>
#Html.DisplayFor(modelItem => item.PCost)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsSold)
</td>
<td>
#Html.ActionLink("Edit", "EditCarpet", new { id = item.Product_Id }) |
#Html.ActionLink("Details", "CarpetDetails", new { id = item.Product_Id }) |
#Html.ActionLink("Delete", "DeleteCarpet", new { id = item.Product_Id })
</td>
</tr>
}
</table>
and Finally Model
namespace SOC.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Product")]
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
Order_Details = new HashSet<Order_Details>();
}
public Product(Product product)
{
this.Quality_Id = product.Quality_Id;
this.Design_Id = product.Design_Id;
this.Supplier_Id = product.Supplier_Id;
this.PColor = product.PColor;
this.PBorder_Color = product.PBorder_Color;
this.PSKU = product.PSKU;
this.PLength = product.PLength;
this.PWidth = product.PWidth;
this.IsSold = product.IsSold;
}
[Key]
public int Product_Id { get; set; }
[Display(Name="Quality")]
public int Quality_Id { get; set; }
[Display(Name = "Design")]
public int Design_Id { get; set; }
[Display(Name = "Supplier")]
public int Supplier_Id { get; set; }
[Required]
[StringLength(20)]
[Display(Name = "Color")]
public string PColor { get; set; }
[Required]
[StringLength(20)]
[Display(Name = "Border Color")]
public string PBorder_Color { get; set; }
[Required]
[Display(Name = "Stock #")]
public string PSKU { get; set; }
[Display(Name = "Length")]
public decimal PLength { get; set; }
[Display(Name = "Width")]
public decimal PWidth { get; set; }
[Display(Name = "Cost")]
public decimal PCost { get; set; }
[Display(Name = "In Stock")]
public bool IsSold { get; set; }
public virtual Design Design { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Order_Details> Order_Details { get; set; }
public virtual Quality Quality { get; set; }
public virtual Supplier Supplier { get; set; }
}
}

You are not building your model nor invoking the overload of View() that accepts a model, so your model is null.
public ActionResult ViewCarpets()
{
IEnumerable<SelectListItem> Qualities = context.Qualities.Select(c => new SelectListItem
{
Value = c.Quality_Id.ToString(),
Text = c.QName
});
IEnumerable<SelectListItem> Suppliers = context.Suppliers.Select(c => new SelectListItem
{
Value = c.Supplier_Id.ToString(),
Text = c.SName
});
IEnumerable<SelectListItem> Designs = context.Design.Select(c => new SelectListItem
{
Value = c.Design_Id.ToString(),
Text = c.DName
});
ViewBag.Quality_Id = Qualities;
ViewBag.Supplier_Id = Suppliers;
ViewBag.Design_Id = Designs;
var products = GetProducts(); // whatever you need to do to get a list of products, database call etc.
return View("ViewCarpets", model: products);
}

You don't pass model to view:
return View("ViewCarpets");
Should be:
var model = new Your_model_class(); // Product for example
return View("ViewCarpets", model);

Thank you so much for the help guys, I got a hint from #Dan D so I changed my action method like below and the problem is solved
public ActionResult ViewCarpets()
{
//TODO: Implement View Carpets Logic
IEnumerable<SelectListItem> Qualities = context.Qualities.Select(c => new SelectListItem
{
Value = c.Quality_Id.ToString(),
Text = c.QName
});
IEnumerable<SelectListItem> Suppliers = context.Suppliers.Select(c => new SelectListItem
{
Value = c.Supplier_Id.ToString(),
Text = c.SName
});
IEnumerable<SelectListItem> Designs = context.Design.Select(c => new SelectListItem
{
Value = c.Design_Id.ToString(),
Text = c.DName
});
var model = new Product();
ViewBag.Quality_Id = Qualities;
ViewBag.Supplier_Id = Suppliers;
ViewBag.Design_Id = Designs;
List<Product> product = context.Products.ToList();
return View(product);
}

Related

What properties do i have to give my controller index method?

I am building a project for school. I am almost there but there is one error I can't fix.
I am making a bike reservation asp.net website.
The error says I pass a list to the index page of reservations and it expects an IEnumerable.
I already tried making the expected a list, but that also gives an error.
I have seen other fixes of this problem, but I can't get it to work.
Here is my original index method.
// GET: Reservations
public ActionResult Index()
{
var reservations = db.Reservations.Include(r => r.Bike).Include(r => r.Customer).Include(r => r.DropoffStore).Include(r => r.PickupStore);
return View(reservations.ToList());
}
Here is my new Controller index method that i got from someone else, but i dont know why i wont work:
// GET: Reservations
public ActionResult Index()
{
var reservations = db.Reservations.Include(r => r.Bike).Include(r => r.Customer).Include(r => r.DropoffStore).Include(r => r.PickupStore);
IEnumerable<ReservationViewModel> reservationViewModels = new List<ReservationViewModel>();
foreach (var reservation in reservations)
{
var reservationViewModel = new ReservationViewModel
{
(PROPERTY)
};
reservationViewModels.ToList().Add(reservationViewModel);
}
return View(reservationViewModels);
}
Here is my index page:
#model IEnumerable<ASP.NET_Framwork_for_real_bitch.ViewModels.ReservationViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Reservation.Customer.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.Customer.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.Customer.Email)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.Customer.Gender)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.DropoffStore_Id)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.PickupStore_Id)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.StartDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Reservation.EndDate)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Reservation.Customer.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.Customer.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.Customer.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.Customer.Gender)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.DropoffStore.StoreName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.PickupStore.StoreName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.StartDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reservation.EndDate)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.Reservation.Id }) |
#Html.ActionLink("Delete", "Delete", new { id = item.Reservation.Id })
</td>
</tr>
}
</table>
This is the exact error:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[ASP.NET_Framwork_for_real_bitch.Models.Reservation]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[ASP.NET_Framwork_for_real_bitch.ViewModels.ReservationViewModel]'.
my Whole ReservationViewModel:
using ASP.NET_Framwork_for_real_bitch.Models;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace ASP.NET_Framwork_for_real_bitch.ViewModels
{
public class ReservationViewModel
{
private BikeShoppaModel db = new BikeShoppaModel();
public Reservation Reservation { get; set; }
public SelectList DropoffStore_Id { get; private set; }
public SelectList PickupStore_Id { get; private set; }
public SelectList Bikes { get; private set; }
public SelectList CustomerGender { get; set; }
public int TotalDays { get; set; }
public double TotalPrice { get; set; }
public ReservationViewModel()
{
DropoffStore_Id = new SelectList(db.Stores, "Id", "StoreName");
PickupStore_Id = new SelectList(db.Stores, "Id", "StoreName");
Bikes = new SelectList(db.Bikes, "Id", "Brand");
CustomerGender = new SelectList(db.Customers, "Id", "Gender");
}
public ReservationViewModel(int id) : this()
{
Reservation = db.Reservations.Find(id);
TotalDays = (Reservation.EndDate.Date - Reservation.StartDate.Date).Days + 1;
}
public void Save()
{
if(Reservation.Id > 0)
{
db.Entry(Reservation).State = EntityState.Modified;
}
else
{
db.Reservations.Add(Reservation);
}
db.SaveChanges();
}
}
}
my Reservations model:
public class Reservation
{
public int Id { get; set; }
[ForeignKey("Customer")]
[Display(Name = "Customer")]
public int Customer_Id { get; set; }
public virtual Customer Customer { get; set; }
[ForeignKey("Bike")]
public int Bike_Id { get; set; }
public Bike Bike { get; set; }
[DataType(DataType.Date)]
[Column(TypeName = "Date")]
[Display(Name = "Start date")]
public DateTime StartDate { get; set; }
[DataType(DataType.Date)]
[Column(TypeName = "Date")]
[Display(Name = "End date")]
public DateTime EndDate { get; set; }
[ForeignKey("PickupStore")]
[Display(Name = "Pickup store")]
public int PickupStore_Id { get; set; }
public Store PickupStore { get; set; }
[ForeignKey("DropoffStore")]
[Display(Name = "Dropoff store")]
public int DropoffStore_Id { get; set; }
public Store DropoffStore { get; set; }
}

Unable to pass data to view; Error: Does not contain a definition for (Each column field in model)

I am trying to have a view that shows all work orders in the state of New Jersey.
This is my work order model:
public class WorkOrder
{
public int UserId { get; set; }
public string LocationId { get; set; }
public string Reason { get; set; }
public bool IsActive { get; set; } = true;
public DateTime Date { get; set; } = DateTime.Now;
public string StateId { get; set; }
}
In my View where I am trying to pass the data I have:
#model IEnumerable<WorkOrder>
#{
ViewData["Title"] = "Work Orders";
}
<div class="by-location">
<h1>By Location</h1>
<ul>
<li> #Html.ActionLink("Delaware", "Delaware",
"HomeController")</li>
<li>
#Html.ActionLink("New Jersey", "New Jersey",
"HomeController")
</li>
<li>
#Html.ActionLink("Pennsylvania", "Pennsylvania",
"HomeController")
</li>
</ul>
</div>
<div class="container">
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.UserId)
</th>
<th>
#Html.DisplayNameFor(model => model.LocationId)
</th>
<th>
#Html.DisplayNameFor(model => model.Reason)
</th>
<th>
#Html.DisplayNameFor(model => model.IsActive)
</th>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.UserId)
</td>
<td>
#Html.DisplayFor(modelItem => item.LocationId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Reason)
</td>
<td>
#Html.DisplayFor(modelItem => item.IsActive)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.StateId)
</td>
</tr>
}
</table>
</div>
I am only trying to display the data where the location is equal to "NJ" so I have a method in my Controller that I am calling in my Controller that is supposed to return the View for New Jersey work orders but all has the logic for Getting work orders where the State = something.
public IActionResult Nj(string stateId)
{
var njWorkOrders = GetWorkOrders()
.Where(x => x.StateId == stateId).ToList();
return View(njWorkOrders);
}
Here is my GetWorkOrders function:
public List<WorkOrder> GetWorkOrders()
{
List<WorkOrder> workOrders = new List<WorkOrder>();
workOrders.Add(new WorkOrder
{
UserId = 1,
LocationId ="Philadelphia",
Date = DateTime.Now,
Reason = "Lights",
IsActive = true,
StateId = "PA"
});
workOrders.Add(new WorkOrder
{
UserId = 2,
LocationId = "Camden",
Date = DateTime.MinValue,
Reason = "Plumbing",
IsActive = true,
StateId = "NJ"
});
workOrders.Add(new WorkOrder
{
UserId = 3,
LocationId = "Burlington",
Date = DateTime.Now,
Reason = "Water",
IsActive = false,
StateId = "NJ"
});
workOrders.Add(new WorkOrder
{
UserId = 4,
LocationId ="Wilmington",
Date = DateTime.MaxValue,
Reason = "Lights",
IsActive = true,
StateId = "DE"
});
// return the work orders to be used by your view methods
return workOrders;
}
Few things:
You can't return IActionResult. You have to return ActionResult.
Since your controller action is expecting an argument, you have to pass the stateId in query string like below
http://localhost:52023/Home/Nj?stateId=NJ

Why the result from linq to viewmodel been duplicate in MVC

Good day all,
I'm new in MVC.
The Issue : The data repeated (duplicate).
Suppose diffrent data populate but it appear same record.
it took last record and shows all records same (duplicate).
i dont know where is my mistake.
i checked 'Qdata' populate correct data. but when go to view model been duplicate.
Controller
List<ApprovalVM> SmPSetVM = new List<ApprovalVM>();
ApprovalVM setVM = new ApprovalVM();
var Qdata = (from u in db.SSM_RegisSet
join c in db.SSM_LinkRegisUpload on u.PKRegisId equals c.FKRegisId
join v in db.SSM_UploadData on c.FKUpDid equals v.UplId
join b in db.SSM_User on u.FKUserId equals b.PK_Uid
join g in db.SSM_Department on b.FK_DepartId equals g.PK_DeptId
join t in db.SSM_Team on b.FK_TeamId equals t.PK_TeamId
join k in db.SSM_GM on b.FK_GMId equals k.PK_GM_id
//where v.SN_NO == da
//orderby u.AutoEC_id
select new
{
v.PO_NO,
v.SN_NO,
v.Exp_NO,
v.Model,
v.PlanDate,
v.Holder_Id,
ids = "I000" + u.PKRegisId,
c.PKLinkId,
g.HODName,
b.PK_Uid,
b.UserName,
t.PK_TeamId,
t.TeamLeaderName,
k.GMName
}).ToList().OrderByDescending(v=>v.PKLinkId);
foreach (var item in Qdata)//.Where(x => x.SN_NO == da))
{
setVM.PO_NO = item.PO_NO;
setVM.SN_NO = item.SN_NO;
setVM.Exp_NO = item.Exp_NO;
setVM.Model = item.Model;
setVM.PlanDate = item.PlanDate;
setVM.Holder_Id = item.Holder_Id;
setVM.POSNId = item.ids;
setVM.PKLinkId = item.PKLinkId;
setVM.PK_TeamId = item.PK_TeamId;
setVM.HODName = item.HODName;
setVM.PK_Uid = item.PK_Uid;
setVM.UserName = item.UserName;
setVM.TeamLeaderName = item.TeamLeaderName;
setVM.GMName = item.GMName;
SmPSetVM.Add(setVM);
}
return View(SmPSetVM);
View Model
public class ApprovalVM
{
// User
public int PK_Uid { get; set; }
public string UserName { get; set; }
public string FullName { get; set; }
// Team Leader
public int PK_TeamId { get; set; }
public string TeamName { get; set; }
public string TeamLeaderName { get; set; }
// GM Name
public int PK_GM_id { get; set; }
public string GMName { get; set; }
public Nullable<bool> GMIsVisible { get; set; }
//Department
public int PK_DeptId { get; set; }
public string DepartmentName { get; set; }
public string HODName { get; set; }
//Upload Data
public int UplId { get; set; }
[Display(Name = "PO No")]
public string PO_NO { get; set; }
[Display(Name = "S/N")]
public string SN_NO { get; set; }
[Display(Name = "Exp No")]
public string Exp_NO { get; set; }
public string Model { get; set; }
public string PlanDate { get; set; }
public string Holder_Id { get; set; }
// Regis Id
public string POSNId { get; set; }
//Link
public int PKLinkId { get; set; }
// List of Approval
//public List<ApprovalVM> ListApproval { get; set; }
}
View
<div class="col-lg-11">
<div class="panel-body table-responsive">
<table class="table table-striped" id="IntTrntbl">
<tr>
<th>
No
</th>
<th>
#Html.DisplayNameFor(model => model.POSNId)
</th>
<th>
#Html.DisplayNameFor(model => model.PO_NO)
</th>
<th>
#Html.DisplayNameFor(model => model.SN_NO)
</th>
<th>
#Html.DisplayNameFor(model => model.Exp_NO)
</th>
<th>
#Html.DisplayNameFor(model => model.Model)
</th>
<th>
#Html.DisplayNameFor(model => model.PlanDate)
</th>
<th>
#Html.DisplayNameFor(model => model.Holder_Id)
</th>
<th>
#Html.DisplayNameFor(model => model.PKLinkId)
</th>
</tr>
#{int a = 1;}
#foreach (var item in Model)
{
<tr>
<td>
#(a++)
</td>
<td style="width:10%">
#Html.DisplayFor(modelItem => item.POSNId)
</td>
<td>
#Html.DisplayFor(modelItem => item.PO_NO)
</td>
<td>
#Html.DisplayFor(modelItem => item.SN_NO)
</td>
<td>
#Html.DisplayFor(modelItem => item.Exp_NO)
</td>
<td>
#Html.DisplayFor(modelItem => item.Model)
</td>
<td>
#Html.DisplayFor(modelItem => item.PlanDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.Holder_Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.PKLinkId)
</td>
</tr>
}
</table>
</div>
</div>
Thanks In Advance!
It is because you don't instantiate a new setVM in foreach loop. You should move the initialization of setVM object(ApprovalVM setVM = new ApprovalVM();) in foreach loop.
In each iteration you modify the same object and add it to your list.
You are updating the same object in every iteration of the loop. You initialize the setVM once and then add it to the list many times. Therefore the list contains multiple entries of the same item. As you update the object in the foreach then all references that point to that item reference the new value.
Instantiate a new item in each iteration:
foreach (var item in Qdata)//.Where(x => x.SN_NO == da))
{
setVM = new ApprovalVM();
setVM.PO_NO = item.PO_NO;
setVM.SN_NO = item.SN_NO;
setVM.Exp_NO = item.Exp_NO;
setVM.Model = item.Model;
setVM.PlanDate = item.PlanDate;
setVM.Holder_Id = item.Holder_Id;
setVM.POSNId = item.ids;
setVM.PKLinkId = item.PKLinkId;
setVM.PK_TeamId = item.PK_TeamId;
setVM.HODName = item.HODName;
setVM.PK_Uid = item.PK_Uid;
setVM.UserName = item.UserName;
setVM.TeamLeaderName = item.TeamLeaderName;
setVM.GMName = item.GMName;
SmPSetVM.Add(setVM);
}
But if already using linq then you can improve and project this class in the query (and use the object initializer syntax):
return View((from u in db.SSM_RegisSet
join c in db.SSM_LinkRegisUpload on u.PKRegisId equals c.FKRegisId
join v in db.SSM_UploadData on c.FKUpDid equals v.UplId
join b in db.SSM_User on u.FKUserId equals b.PK_Uid
join g in db.SSM_Department on b.FK_DepartId equals g.PK_DeptId
join t in db.SSM_Team on b.FK_TeamId equals t.PK_TeamId
join k in db.SSM_GM on b.FK_GMId equals k.PK_GM_id
//where v.SN_NO == da
//orderby u.AutoEC_id
select new ApprovalVM {
PO_NO = v.PO_NO,
//And so on
}).OrderByDescending(v=>v.PKLinkId).ToList());
And last, if using EF then read into Navigation Properties. Will make joins much simpler.

ASP.NET MVC how to display associative data based on id's

I'm trying to display data on my index view from from my models that are associated with each other based on id's. I.e. display client name, asset name that belongs to this client, and address of this client, etc...
Here's my model:
Client model:
public class Client : Person {
public ICollection<OccupancyHistoryRecord> OccupancyRecords { get; set; }
public ICollection<RentHistoryRecord> RentRecords { get; set; }
}
Asset model:
public class Asset {
public int Id { get; set; }
[Display(Name = "Asset Name")]
public string Name { get; set; }
[Display(Name = "Asset Type")]
public string Type { get; set; }
public FullAddress Address { get; set; }
[Display(Name = "Asking Rent")]
public string AskingRent { get; set; }
public ICollection<OccupancyHistoryRecord> OccupancyRecords;
public ICollection<RentHistoryRecord> RentRecords;
}
Occupancy Record:
public class OccupancyHistoryRecord {
public int Id { get; set; }
public int AssetId { get; set; }
public int ClientId { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
}
Client Controller:
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords) // how to get the asset name instead of the id)
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}
Index View:
#model IEnumerable<RentalManagement.Models.Client>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.OccupancyRecords)
</th>
<th>
#Html.DisplayNameFor(model => model.HomeAddress)
</th>
<th>
#Html.DisplayNameFor(model => model.WorkAddress)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.OccupancyRecords)
</td>
<td>
#Html.DisplayFor(modelItem => item.HomeAddress.StreetAddress)
</td>
<td>
#Html.DisplayFor(modelItem => item.WorkAddress.StreetAddress)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }, null) |
#Html.ActionLink("Assets", "Details", "Assets", new { id = item.Id}, null) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
Right now it's displaying the occupancy record's Id. What I want is to display the asset name based on the occupancy's AssetId.
Thanks.
You need to change your :
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords) // how to get the asset name instead of the id)
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}
code as below:
public ActionResult Index()
{
var clients = db.Clients.Include(c => c.OccupancyRecords.Select(s => new { AssetId = s.AssetId, AssetName = /* Find AssetName By Id here */ }))
.Include(c => c.HomeAddress)
.Include(c => c.WorkAddress);
return View(clients.ToList());
}

Filtering by parameter & Routing

I have an MachineInfo view page which I am showing 60 different specifications of the related machine like processor info, ram info, disk info, db info etc.
ActionLink to this page is:
#Html.ActionLink("Machine Info", "MachineInfo", new { id = Model.LicenseKey }) |
Controller:
public ActionResult MachineInfo(string LicenseKey)
{
if (LicenseKey == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Farm farm = db.Farms.Find(LicenseKey);
if (farm == null)
{
return HttpNotFound();
}
return View(farm);
}
Farm Model:
public partial class Farm
{
public Farm()
{
this.FarmChanges = new HashSet<FarmChange>();
this.FarmDetails = new HashSet<FarmDetail>();
this.FarmTables = new HashSet<FarmTable>();
}
public int Id { get; set; }
public string LicenseKey { get; set; }
public string Name { get; set; }
public string CustomerName { get; set; }
public virtual ICollection<FarmChange> FarmChanges { get; set; }
public virtual ICollection<FarmDetail> FarmDetails { get; set; }
public virtual ICollection<FarmTable> FarmTables { get; set; }
}
FarmDetails Model:
public partial class FarmDetail
{
public System.Guid Id { get; set; }
public int FarmId { get; set; }
public int Type { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public virtual Farm Farm { get; set; }
}
All the MachineInfo is coming from the "Value" in the FarmDetails table.
View:
#model IEnumerable<FarmManagement.Models.FarmDetail>
#{
ViewBag.Title = "Machine Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Machine Info</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Value)
</th>
<th>
#Html.DisplayNameFor(model => model.Farm.LicenseKey)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Type)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Value)
</td>
<td>
#Html.DisplayFor(modelItem => item.Farm.LicenseKey)
</td>
<td>
</td>
</tr>
}
</table>
#Html.ActionLink("Back to Farms List", "Index")
I am trying to show MachineInfo of a specific machine (LicenseKey=ABXYZ-XYZAB) with this url: mydomain.com/MachineInfo/ABXYZ-XYZAB
I need to filter the view by LicenseKey.
After my all tries, I'm only getting 400 - Bad Request error (Because LicenseKey == null) or getting the MachineInfo of ALL machines, not the specific machine with LicenseKey=ABXYZ-XYZAB.
What I am doing wrong?
Change your actionlink code
#Html.ActionLink("Machine Info", "MachineInfo", new { id = Model.LicenseKey })
to
#Html.ActionLink("Machine Info", "MachineInfo", new { LicenseKey = Model.LicenseKey })
As the Action link parameter name should match with the controller action parameter name.
Solved the problem after making following changes:
New Controller After Change:
public ActionResult MachineInfo(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FarmDetail farmdetail = db.FarmDetails.Where(x => x.FarmId == id).FirstOrDefault();
if (farmdetail == null)
{
return HttpNotFound();
}
return View(farmdetail);
}
New View After Change:
#model FarmManagement.Models.FarmDetail
#{
ViewBag.Title = "Machine Info";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Machine Info</h2>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Type)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Value)
</th>
<th>
#Html.DisplayNameFor(model => model.Farm.LicenseKey)
</th>
<th></th>
</tr>
#for (int i = 0; i < Model.Farm.FarmDetails.Count(); i++)
{
<tr>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Type)
</td>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Name)
</td>
<td>
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Value)
</td>
<td>
#Html.DisplayFor(model => model.Farm.LicenseKey)
</td>
<td>
</tr>
}
</table>
#Html.ActionLink("Back to Farms List", "Index")
I needed to use a where sentence in Controller;
FarmDetail farmdetail = db.FarmDetails.Where(x => x.FarmId == id).FirstOrDefault();
And removed IEnumerable from the View and changed #foreach to #for with ElementAt(i).
#Html.DisplayFor(model => model.Farm.FarmDetails.ElementAt(i).Name)

Categories