Enumerated list of child class not working - c#

I am creating a webpage for a help desk software where the top shows the information from the ticket class and then the bottom for the ticketNotes that are attached to the ticket class through an ICollection. Currently if I comment out the bottom, the top portion (the static table) works correctly. However, the bottom two tables that point to the ICollection are not working. Here is the error that I am getting:
Here is my view:
#model HelpDesk.Model.Ticket
#{
ViewBag.Title = "Ticket# " + Html.DisplayFor(model => model.TicketNumber);
}
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.CategoryId)
</th>
<th>
#Html.DisplayFor(model => model.Category.CategoryName)
</th>
</tr>
<tr>
<th>
#Html.DisplayNameFor(model => model.OpenUserId)
</th>
<th>
#Html.DisplayFor(model => model.OpenUser.FullName)
</th>
</tr>
<tr>
<th>
#Html.DisplayNameFor(model => model.OpenDate)
</th>
<th>
#Html.DisplayFor(model => model.OpenDate)
</th>
</tr>
<tr>
<th>
#Html.DisplayNameFor(model => model.TechnicianId)
</th>
<th>
#Html.DisplayFor(model => model.Technician.FullName)
</th>
</tr>
<tr>
<th>
#Html.DisplayNameFor(model => model.TicketStatusId)
</th>
<th>
#Html.DisplayFor(model => model.TicketStatus.StatusDescription)
</th>
</tr>
<tr>
<th>
#Html.DisplayNameFor(model => model.CloseDate)
</th>
<th>
#Html.DisplayFor(model => model.CloseDate)
</th>
</tr>
<tr></tr>
</table>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.TicketNotes.Note)
</th>
<th>
#Html.DisplayNameFor(model => model.TicketNotes.TicketNoteDate)
</th>
<th>
#Html.DisplayNameFor(model => model.TicketNotes.UserNote.FullName)
</th>
<th></th>
</tr>
#foreach (var item in Model.TicketNotes)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.TicketNotes.Note)
</td>
<td>
#Html.DisplayFor(modelItem => item.TicketNotes.TicketNoteDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.TicketNotes.UserNote.FullName)
</td>
</tr>
}
</table>
Here is my controller Code:
public ActionResult EditUserTicket(Guid id)
{
Ticket ticket = tickets.GetById(id);
var model = db.Tickets
.Include(t => t.TicketNotes)
.Where(t => t.TicketId == id).First();
return View(model);
}
and here is my Model:
namespace HelpDesk.Model
{
public class Ticket
{
public Ticket()
{
this.TicketNotes = new HashSet<TicketNote>();
}
public Guid TicketId { get; set; }
[Display(Name = "#")]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
public int TicketNumber { get; set; }
[ForeignKey("Category")]
[Required]
public Guid CategoryId { get; set; }
public virtual Category Category { get; set; }
[ForeignKey("OpenUser")]
[Required]
public Guid OpenUserId { get; set; }
[Display(Name = "Ticket Owner")]
public virtual User OpenUser { get; set; }
[Display(Name = "Opened")]
[DataType(DataType.Date)]
[Required]
public DateTime OpenDate { get; set; }
[ForeignKey("Technician")]
[Required]
public Guid TechnicianId { get; set; }
[Display(Name = "Technician")]
public virtual User Technician { get; set; }
[ForeignKey("TicketStatus")]
[Required]
public Guid TicketStatusId { get; set; }
public virtual TicketStatus TicketStatus { get; set; }
[Display(Name = "Closed")]
[DataType(DataType.Date)]
public Nullable<DateTime> CloseDate { get; set; }
[Display(Name = "Note")]
public virtual ICollection<TicketNote> TicketNotes { get; set; }
//public virtual ICollection<TicketSubscription> TicketSubscriptions { get; set; }
}
}

In your foreach loop
#foreach (var item in Model.TicketNotes)
item is already an instance of TicketNote, so
#Html.DisplayFor(modelItem => item.TicketNotes.Note)
fails because TicketNote does not have a property named TicketNotes
It should be just
#Html.DisplayFor(m => item.Note)
For the table headings, you can use
#Html.DisplayNameFor(model => model.TicketNotes[0].Note)

Related

RestSharp - How to return data from API to View

public class ProductViewModel
{
public int id { get; set; }
public string title { get; set; }
public string description { get; set; }
public int price { get; set; }
public double discountPercentage { get; set; }
public double rating { get; set; }
public int stock { get; set; }
public string brand { get; set; }
public string category { get; set; }
public string thumbnail { get; set; }
public List<string> images { get; set; }
}
public class RootViewModel
{
public ProductViewModel[] Products { get; set; }
public int total { get; set; }
public int skip { get; set; }
public int limit { get; set; }
}
public class WebProductClient : IWebProductClient
{
private readonly RestClient _client;
private readonly string _url;
public WebProductClient()
{
_url = "https://local/host:7123/";
var options = new RestClientOptions(_url);
_client = new RestClient(options);
}
public async Task<ProductViewModel> GetAllProduct()
{
var request = new RestRequest("Api/Products");
var response = await _client.ExecuteGetAsync(request);
var r = JsonConvert.DeserializeObject<ProductViewModel>(response.Content);
return r;
}
}
ProductsController:
public IActionResult Index()
{
var all = _client.GetAllProduct();
return View(all);
}
Index:
#model IEnumerable<DummyShop.Service.ViewModel.ProductViewModel>
#{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.id)
</th>
<th>
#Html.DisplayNameFor(model => model.title)
</th>
<th>
#Html.DisplayNameFor(model => model.description)
</th>
<th>
#Html.DisplayNameFor(model => model.price)
</th>
<th>
#Html.DisplayNameFor(model => model.discountPercentage)
</th>
<th>
#Html.DisplayNameFor(model => model.rating)
</th>
<th>
#Html.DisplayNameFor(model => model.stock)
</th>
<th>
#Html.DisplayNameFor(model => model.brand)
</th>
<th>
#Html.DisplayNameFor(model => model.category)
</th>
<th>
#Html.DisplayNameFor(model => model.thumbnail)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.id)
</td>
<td>
#Html.DisplayFor(modelItem => item.title)
</td>
<td>
#Html.DisplayFor(modelItem => item.description)
</td>
<td>
#Html.DisplayFor(modelItem => item.price)
</td>
<td>
#Html.DisplayFor(modelItem => item.discountPercentage)
</td>
<td>
#Html.DisplayFor(modelItem => item.rating)
</td>
<td>
#Html.DisplayFor(modelItem => item.stock)
</td>
<td>
#Html.DisplayFor(modelItem => item.brand)
</td>
<td>
#Html.DisplayFor(modelItem => item.category)
</td>
<td>
#Html.DisplayFor(modelItem => item.thumbnail)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
</tbody>
</table>
Returned data from my API:
{
"products": [
{
"id": 1,
"title": "iPhone 9",
"description": "An apple mobile which is nothing like apple",
"price": 549,
"discountPercentage": 12.96,
"rating": 4.69,
"stock": 94,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "://i.dummyjson./data/products/1/thumbnail./jpg",
"images": [
"://i.dummyjson./data/products/1/1./",
"://i.dummyjson./data/products/1/2./",
"://i.dummyjson./data/products/1/3./",
"://i.dummyjson./data/products/1/4./",
"://i.dummyjson./data/products/1/thumbnail./"
]
},
{
"id": 2,
"title": "iPhone X",
"description": "SIM-Free, Model A19211 6.5-inch Super Retina HD display with OLED technology A12 Bionic chip with ...",
"price": 899,
"discountPercentage": 17.94,
"rating": 4.44,
"stock": 34,
"brand": "Apple",
"category": "smartphones",
"thumbnail": "://i.dummyjson/data/products/2/thumbnail.",
"images": [
"://i.dummyjson/data/products/2/1.",
"://i.dummyjson/data/products/2/2.",
"://i.dummyjson/data/products/2/3.",
"://i.dummyjson/data/products/2/thumbnail."
]
},
],
"total": 100,
"skip": 0,
"limit": 30
}
The error I got:
System.Collections.Generic.IEnumerable1[DummyShop.Service.ViewModel.ProductViewModel].An unhandled exception occurred while processing the request. InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Runtime.CompilerServices.AsyncTaskMethodBuilder1+AsyncStateMachineBox`1[DummyShop.Service.ViewModel.ProductViewModel,DummyShop.Service.ProductClientsWEB.WebProductClient+d__5]', but this ViewDataDictionary instance requires a model item of type
The attached JSON response is the RootViewModel type. You deserialize the response.Content as RootViewModel type.
public async Task<RootViewModel> GetAllProduct()
{
var request = new RestRequest("Api/Products");
var response = await _client.ExecuteGetAsync(request);
var r = JsonConvert.DeserializeObject<RootViewModel>(response.Content);
return r;
}
Consider using the JsonPropertyName attribute to match the property name in the JSON. Same goes for the other properties, you should name the properties as "Pascal Casing" instead of "camel Case".
public class RootViewModel
{
[JsonPropertyName("products")]
public ProductViewModel[] Products { get; set; }
...
}
As in 1 we will return the RootViewModel value from the controller, modify the ViewModel as RootViewModel. And enumerate with #Model.Products for the <thead> and <tr> elements.
#model RootViewModel
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Products[0].id)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].title)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].description)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].price)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].discountPercentage)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].rating)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].stock)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].brand)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].category)
</th>
<th>
#Html.DisplayNameFor(model => model.Products[0].thumbnail)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Products)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.id)
</td>
<!-- Following td elements -->
</tr>
}
</tbody>
</table>
Your controller action should return Task<IActionResult> and it is an async method.
public async Task<IActionResult> Index()
{
var all = await _client.GetAllProduct();
return View(all);
}

How to display all rows with same ID in ASP.NET MVC?

My Index page displays all rows from an Azure SQL Database. When I click a row I get redirected to a unique URL with a QR code for that URL and it also displays the data for only that row. Each row has it's own unique ID, but also a truckID. The truckID is for a driver who can "own" several rows of data, so I want to show every row with the same truckID after a row is clicked.
This is what I've got so far:
MODEL
namespace QR
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("data")]
public partial class data
{
[Required]
[StringLength(50)]
public string Contract { get; set; }
[StringLength(50)]
public string Sort { get; set; }
public int? Report { get; set; }
public double? InputKG { get; set; }
public double? OutputKG { get; set; }
public double? Recovery { get; set; }
public double? Si { get; set; }
public double? Cu { get; set; }
public double? Mn { get; set; }
public double? Mg { get; set; }
public double? Zn { get; set; }
public double? Cr { get; set; }
public double? Fe { get; set; }
public double? Pb { get; set; }
public int? truckID { get; set; }
[Key]
public int ID{ get; set; }
}
}
VIEW (after a row is clicked from Index)
#model QR.data
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>QR code</h2>
<img src="/Home/BarcodeImage?barcodeText=#Request.Url.OriginalString"/>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Contract)
</th>
<th>
#Html.DisplayNameFor(model => model.Sort)
</th>
<th>
#Html.DisplayNameFor(model => model.Report)
</th>
<th>
#Html.DisplayNameFor(model => model.InputKG)
</th>
<th>
#Html.DisplayNameFor(model => model.OutputKG)
</th>
<th>
#Html.DisplayNameFor(model => model.Recovery)
</th>
<th>
#Html.DisplayNameFor(model => model.Si)
</th>
<th>
#Html.DisplayNameFor(model => model.Cu)
</th>
<th>
#Html.DisplayNameFor(model => model.Mn)
</th>
<th>
#Html.DisplayNameFor(model => model.Mg)
</th>
<th>
#Html.DisplayNameFor(model => model.Zn)
</th>
<th>
#Html.DisplayNameFor(model => model.Cr)
</th>
<th>
#Html.DisplayNameFor(model => model.Fe)
</th>
<th>
#Html.DisplayNameFor(model => model.Pb)
</th>
</tr>
<tr>
<td>
#Html.DisplayFor(model => model.Contract)
</td>
<td>
#Html.DisplayFor(model => model.Sort)
</td>
<td>
#Html.DisplayFor(model => model.Report)
</td>
<td>
#Html.DisplayFor(model => model.InputKG)
</td>
<td>
#Html.DisplayFor(model => model.OutputKG)
</td>
<td>
#Html.DisplayFor(model => model.Recovery)
</td>
<td>
#Html.DisplayFor(model => model.Si)
</td>
<td>
#Html.DisplayFor(model => model.Cu)
</td>
<td>
#Html.DisplayFor(model => model.Mn)
</td>
<td>
#Html.DisplayFor(model => model.Mg)
</td>
<td>
#Html.DisplayFor(model => model.Zn)
</td>
<td>
#Html.DisplayFor(model => model.Cr)
</td>
<td>
#Html.DisplayFor(model => model.Fe)
</td>
<td>
#Html.DisplayFor(model => model.Pb)
</td>
</tr>
</table>
<p>
#Html.ActionLink("Back to List", "Index")
</p>
CONTROLLER
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
data data= db.data.Find(id);
if (data == null)
{
return HttpNotFound();
}
return View(data);
}
And on the Index I have this link:
#Html.ActionLink("QR", "Details", new { id = item.ID})
Help?
With this answer I presume two things:
db is a DbContext and has a property called data which is a DbSet<data>
You don't have any other models for your data, only the data class
If the above is true, here's what you should do:
In the controller:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
data data = db.data.Find(id);
if (data == null)
{
return HttpNotFound();
}
var groupedData = db.data.Where(d => d.truckID == data.truckID).ToList();
return View(groupedData);
}
In your view (Details)
// This is after declaring the table headers
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(model => item.Contract)
</td>
// Fill in rest of the td rows as you did
<td>
#Html.DisplayFor(model => item.Pb)
</td>
</tr>
}
This should display all of the rows correctly.
Also, this is just for readability, but it is really important, capitalize your class names, i.e. it should be public partial class Data not data.
You didn't get any error on this statement ?
data data= db.data.Find(id);
I think it has to be like this
data data= db.data.Find(i=>i.ID == id);
and I supposed you were using foreach loop to print all of the data and in that loop you have that #Html.ActionLink.

Get the Child Class Propert in Parent class

I had a two controllers in my application with database first approach
SampCutReqMaster.CS
public partial class SampCutReqMaster
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public SampCutReqMaster()
{
this.SamCutAssignmentMasters = new HashSet<SamCutAssignmentMaster>();
}
public decimal SampCutreqID { get; set; }
public Nullable<decimal> BuyerID { get; set; }
public Nullable<decimal> PatternRefID { get; set; }
public Nullable<decimal> PatternStyleID { get; set; }
public Nullable<decimal> SampleTypeID { get; set; }
public virtual BuyerMaster BuyerMaster { get; set; }
public virtual PatternStyle PatternStyle { get; set; }
public virtual PatterRefMaster PatterRefMaster { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<SamCutAssignmentMaster> SamCutAssignmentMasters { get; set; }
public virtual SampleType SampleType { get; set; }
}
and The next is
SamCutAssignmentMaster
public partial class SamCutAssignmentMaster
{
public decimal CutAssignID { get; set; }
public decimal SampCutreqID { get; set; }
public System.DateTime ReceivedDate { get; set; }
public string ReceivedBy { get; set; }
public Nullable<decimal> PatternMasterID { get; set; }
public virtual PatternMaster PatternMaster { get; set; }
public virtual SampCutReqMaster SampCutReqMaster { get; set; }
}
I had created a controller with a index view for SampCutReqMaster
public class SampCutReqMastersController : Controller
{
private ArtEntities db = new ArtEntities();
// GET: SampCutReqMasters
public ActionResult Index()
{
var sampCutReqMasters = db.SampCutReqMasters.Include(s => s.BuyerMaster).Include(s => s.PatternStyle).Include(s => s.PatterRefMaster).Include(s => s.SampleType).Include(s=>s.SamCutAssignmentMasters);
var sampCutReqMasterssort = sampCutReqMasters.ToList().OrderByDescending(a => a.AddedDate);
return View(sampCutReqMasterssort.ToList());
}
}
I want to get the "receivedBy" of SamcutAssignmentMaster(child class) in my view of SamCutReqMaster (Parent).But there may be no data in SamcutAssignmentMaster relavant to SamCutReqMaster (FK is SamCutReqID)
In Index view Below I need to access SamcutAssignmentMaster.receivedBy
#model IEnumerable<WebArtSampler.Models.SampCutReqMaster>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ReqNum)
</th>
<th>
#Html.DisplayNameFor(model => model.Fabric)
</th>
<th>
#Html.DisplayNameFor(model => model.SampleRequiredDate)
</th>
<th>
#Html.DisplayNameFor(model => model.AddedDate)
</th>
<th>
#Html.DisplayNameFor(model => model.AddedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.BuyerMaster.BuyerName)
</th>
<th>
#Html.DisplayNameFor(model => model.PatternStyle.StyleName)
</th>
<th>
#Html.DisplayNameFor(model => model.PatterRefMaster.PatterRefNum)
</th>
<th>
#Html.DisplayNameFor(model => model.SampleType.SampleType1)
</th>
<th>
#Html.DisplayNameFor(model => model.SizeDetail)
</th>
<th>
#Html.DisplayNameFor(model => model.Qty)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.ReqNum)
</td>
<td>
#Html.DisplayFor(modelItem => item.Fabric)
</td>
<td>
#Html.DisplayFor(modelItem => item.SampleRequiredDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.AddedDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.AddedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.BuyerMaster.BuyerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PatternStyle.StyleName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PatterRefMaster.PatterRefNum)
</td>
<td>
#Html.DisplayFor(modelItem => item.SampleType.SampleType1)
</td>
<td>
#Html.DisplayFor(modelItem => item.SizeDetail)
</td>
<td>
#Html.DisplayFor(modelItem => item.Qty)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.SampCutreqID }) |
#Html.ActionLink("Details", "Details", new { id=item.SampCutreqID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.SampCutreqID })
</td>
</tr>
}
</table>
Ok. You can't access the properties whilst your type is still as the interface ICollection. You need to cast it to a concrete type before you can access the properties of the collection via an index.
#for (var adCounter = 0; adCounter <= (Model.SamCutAssignmentMasters.Count - 1); adCounter++)
{
#Html.DisplayFor(x => ((List<SamCutAssignmentMaster>)x.SamCutAssignmentMasters)[adCounter].ReceivedBy)
}
Cast the type to a list as per the above and you should see the properties.
NOTE: You are using DisplayFor in your view. If you intend to post the contents of this view the model will not bind unless you have a hidden control for each item or you switch to TextBoxFor. You will also need the for (Counter) syntax as well to bind to items in collections.
Hope that helps.

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)

Getting the UserName of an ApplicationUser into a view

I am trying to display the name of an author of a question but unlike the other properties of the model, the ApplicationUser.UserName property does not show in the view (it's just blank). I am using Entity Framework, MVC 5 and Razor.
My Question model:
public class Question
{
public int QuestionID { get; set; }
public string Title { get; set; }
public ApplicationUser Author { get; set; }
public string Description { get; set; }
[DisplayName("Created")]
public DateTime CreationDateTime { get; set; }
public int Rating { get; set; }
}
My QuestionController Index action:
// GET: Questions
public ActionResult Index()
{
return View(db.Questions.ToList());
}
And the view:
#model IEnumerable<Waegogi.Models.Question>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.Author.UserName)
</th>
<th>
#Html.DisplayNameFor(model => model.Description)
</th>
<th>
#Html.DisplayNameFor(model => model.CreationDateTime)
</th>
<th>
#Html.DisplayNameFor(model => model.Rating)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.Author.UserName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreationDateTime)
</td>
<td>
#Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.QuestionID }) |
#Html.ActionLink("Details", "Details", new { id=item.QuestionID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.QuestionID })
</td>
</tr>
}
</table>
Where am I going wrong?
You should be able to solve this by explicitly loading your relationships in your controller call:
public ActionResult Index()
{
return View(db.Questions.Include(q => q.ApplicationUser).ToList());
}

Categories