In my application, to create a report view I have created a ViewModel:
namespace Asp_PASMVC.ViewModels
{
[NotMapped]
public class ReportViewModel
{
public string RequestBy { get; set; } // AppRequest
public string RequestByDessignation { get; set; } // AppRequest
public string RequestByDepartment { get; set; }// AppRequest
public string RequestedDate { get; set; }// AppRequest
public string ApprovalId { get; set; }// AppRequest
public string CompanyName { get; set; }
public List<ApprovalList> ApprovalList { get; set; }
public List<GeneralItemsApprovedList> GeneralItemsApprovedList { get; set; }
}
[NotMapped]
public class ApprovalList
{
public string ApproveDate { get; set; }
public string ApprovedBy { get; set; }
public string ApprovedByDessignation { get; set; }
}
[NotMapped]
public class GeneralItemsApprovedList
{
public string ItemDescription { get; set; }
public string ItemPrice { get; set; }
public byte[] Attachment { get; set; }
}
}
Then in the controller, I joined each table which I want to get the data and passed that data to the report view model.
public ActionResult Index(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
AppRequest appRequest = db.AppRequest.Find(id);
if (appRequest.General.Count != 0)
{
List<ReportViewModel> RequestView = new List<ReportViewModel>();
var ReqDetails = (from a in db.AppRequest
join e in db.CreateEmployee on a.Req_By equals e.Id
join c in db.CreateCompany on e.CompanyId equals c.Id
join d in db.CreateDesignation on e.DesignId equals d.Id
join dep in db.CreateDepartment on e.DepId equals dep.Id
where a.Id == id
select new ReportViewModel
{
RequestedDate = a.Req_Date.ToString(),
RequestBy = e.EmpName,
CompanyName = c.CompanyName,
RequestByDessignation = d.Designation,
RequestByDepartment = dep.Department,
GeneralItemsApprovedList= (from a in db.AppRequest
join g in db.General on a.Id equals g.Req_Id
join gi in db.GeneralItms on g.Id equals gi.General_Id
where a.Id == id
select new GeneralItemsApprovedList
{
Attachment = gi.Attachment,
ItemDescription = gi.Attachment_Description,
ItemPrice = gi.Attachment_Amount.ToString()
}).ToList(),
ApprovalList = (from a in db.AppRequest
join ap in db.ApprovalProcess on a.Id equals ap.Req_Id
join pa in db.ApproveParties on ap.Id equals pa.ApprovalProcess_Id
join ae in db.CreateEmployee on pa.Approver_Id equals ae.Id
join ad in db.CreateDesignation on ae.DesignId equals ad.Id
where a.Id == id
select new ApprovalList
{
ApproveDate = pa.Approved_Date.ToString(),
ApprovedBy = ae.EmpName,
ApprovedByDessignation = ad.Designation,
}).ToList()
}).ToList();
return View("ApprovedReport", ReqDetails);
}
return View("");
}
So the issue occurs when I called the view model data for the view. It doesn't show me the properties what I want to call. Please note I'm still learning asp.MVC and meanwhile I started to develop this application for my education purpose. So some areas there are still I'm not clear. So don't know If I'm doing any wrong thing here. So this is the view that I passed the ViewModel data
@model IEnumerable <Asp_PASMVC.ViewModels.ReportViewModel>
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
<br />
<div class="invoice p-3 mb-3">
<!-- title row -->
<div class="row">
<div class="col-12">
<h4>
<i class="fas fa-globe"></i> PAS Approval
<small class="float-right">@DateTime.Now</small>
</h4>
</div>
<div class="col-12">
<h4>
</h4>
</div>
<!-- /.col -->
</div>
<!-- info row -->
<div class="row invoice-info">
<div class="col-sm-4 invoice-col">
From
<address>
<strong> @Html.DisplayFor(model => model.RequestBy)</strong><br> @Html.DisplayFor(model => model.RequestByDessignation)<br> @Html.DisplayFor(model => model.RequestByDepartment)<br> @Html.DisplayFor(model => model.CompanyName)<br><br>@Html.DisplayFor(model => model.RequestedDate)<br>
</address>
</div>
<!-- /.col -->
<div class="col-sm-4 invoice-col">
Approved By
@foreach (var item in Model.ApprovalList)
{
<address>
<strong>@Html.DisplayFor(model => item.ApprovedBy)</strong><br>@Html.DisplayFor(model => item.ApprovedByDessignation)<br>@Html.DisplayFor(model => item.ApproveDate)<br>@*Approved Date*@<br>
</address>
}
Error says:
The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[Asp_PASMVC.ViewModels.ReportViewModel]', but this dictionary requires a model item of type 'Asp_PASMVC.ViewModels.ReportViewModel'.
Also in the line @Html.DisplayFor(model => model.RequestBy)
it's says RequestBy
cannot find.
CodePudding user response:
Your model is a collection:
@model IEnumerable<Asp_PASMVC.ViewModels.ReportViewModel>
Therefore, to access any item in the collection it's necessary to iterate it.
You can perform it like below:
<div class="col-sm-4 invoice-col">
From
@foreach (var model in Model)
{
<address>
<strong> @Html.DisplayFor(m => model.RequestBy)</strong><br> @Html.DisplayFor(m => model.RequestByDessignation)<br> @Html.DisplayFor(m => model.RequestByDepartment)<br> @Html.DisplayFor(m => model.CompanyName)<br><br>@Html.DisplayFor(m => model.RequestedDate)<br>
</address>
}
</div>
EDIT:
This version is using nested loop to display ApprovalList
list for each model item:
<div class="col-sm-4 invoice-col">
From
@foreach (var model in Model)
{
<address>
<strong> @Html.DisplayFor(m => model.RequestBy)</strong><br> @Html.DisplayFor(m => model.RequestByDessignation)<br> @Html.DisplayFor(m => model.RequestByDepartment)<br> @Html.DisplayFor(m => model.CompanyName)<br><br>@Html.DisplayFor(m => model.RequestedDate)<br>
</address>
</div>
<div class="col-sm-4 invoice-col">
Approved By
@foreach (var item in model.ApprovalList)
{
<address>
<strong>@Html.DisplayFor(m => item.ApprovedBy)</strong><br>@Html.DisplayFor(m => item.ApprovedByDessignation)<br>@Html.DisplayFor(m => item.ApproveDate)<br>@*Approved Date*@<br>
</address>
}
</div>
}