Incorrent model passed to Partial View - asp.net-mvc

This might be a duplicate question but I can't for the life of me know what the solution is. I'm trying to load a partial view with a table based on the ID of a clicked link.
I'm getting this error:
System.InvalidOperationException: 'The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[MasigasigTrackingSystem.Models.Invoice]', but this ViewDataDictionary instance requires a model item of type 'MasigasigTrackingSystem.Pages.Masigasig.MainPage.TripTicket.TripTicketListModel'.'
I can't seem to figure out how should I passed the model to the partial view.
Here is what my OnGet looks like:
public IList<Invoice> Invoice { get; set; }
public PartialViewResult OnGetDetails(int TripTicketID)
{
var invoices = from m in _context.Invoice
select m;
invoices = invoices.Where(x => x.TripTicketID == TripTicketID);
Invoice = invoices.ToList();
return Partial("_TripTicketListDetails", Invoice);
}
Here is my partial view:
#model TripTicketListModel
<h1>Hello, test</h1>
<table id="TripEntryList" class="table table-bordered table-hover">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Invoice[0].InvoiceNumber)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Invoice)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.InvoiceNumber)
</td>
</tr>
}
</tbody>

You Partial View Required TripTicketListModel and you are passing the model Invoice. It means you are passing wrong model.
From your View code i can say your Invoice is used inside TripTicketListModel, so try below solution.
public PartialViewResult OnGetDetails(int TripTicketID)
{
var invoices = from m in _context.Invoice select m;
invoices = invoices.Where(x => x.TripTicketID == TripTicketID);
TripTicketListModel model = new TripTicketListModel();
model.Invoice = invoices.ToList();
return Partial("_TripTicketListDetails", model);
}

Related

How can I read list from controller into foreach view in Mvc?

I got this error
The model item passed into the dictionary is of type 'System.Collections.Generic.List'1[CandidateScreening.Data.Entities.Patient]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable'1[CandidateScreening.Models.Patient]'.)
public ActionResult Index()
{
var Patient = _context.Patients.ToList();
return View(Patient);
}
#model IEnumerable<CandidateScreening.Models.Patient>
#{
ViewBag.Title = "index";
}
<h2>List Of the Patient</h2>
<table class="table">
<thead>
<tr>
<th>firstName</th>
<th>SurName</th>
<th>Gender</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td> #Html.ActionLink(item.Firstname, "Index", "detail")</td>
<td> #Html.ActionLink(item.Surname, "Index", "detail")</td>
<td> #Html.ActionLink(item.Gender, "Index", "detail")</td>
</tr>
}
</tbody>
</table>
could you tell me why I get this error?
I have try by changing IEnumerable to List but is not working yet
Assumed Patients is an Entity Framework data context, ToList() will generate list with object type set as IEnumerable<CandidateScreening.Data.Entities.Patient>, which doesn't match with object type set by #model directive (i.e. IEnumerable<CandidateScreening.Models.Patient>).
To solve this issue, simply use Select() LINQ query to project entity context into list of viewmodel class:
public ActionResult Index()
{
var Patient = _context.Patients.Select(x => new CandidateScreening.Models.Patient
{
// list of properties here
// example:
// PatientId = x.PatientId
}).ToList();
return View(Patient);
}
Or using query expression as alternative:
var Patient = (from patient in _context.Patients
select new CandidateScreening.Models.Patient
{
// list of properties here
// example:
// PatientId = patient.PatientId
}).ToList();

How to post back a list of object to the controller in MVC [duplicate]

This question already has answers here:
MVC Form not able to post List of objects
(3 answers)
Post an HTML Table to ADO.NET DataTable
(2 answers)
Closed 6 years ago.
I have an object model and I am passing it to the view so that user can input their comments for some of the object's properties as a part of a survey.
I am able to receive what the user has entered for an object if I am only rendered one single object to the view. However, when I want to render multiple (a list) of objects to the view then I receive a null list of objects when the user click on the submit form.
Please see my code below:
This is my object model
public class SurveyViewModel
{
public string Name { get; set; }
public double PV { get; set; }
public double QtyUsePerMonth { get; set; }
public double TotalPVPerMonth { get; set; }
}
This is my view where I render the list of object
#model IEnumerable<WebApplication4.Models.SurveyViewModel>
#{
ViewBag.Title = "Survey";
}
<h2>Survey</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { id = "form1" }))
{
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.PV)
</th>
<th>
#Html.DisplayNameFor(model => model.QtyUsePerMonth)
</th>
<th>
#Html.DisplayNameFor(model => model.TotalPVPerMonth)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
#Html.HiddenFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.PV)
#Html.HiddenFor(modelItem => item.PV)
</td>
<td>
#Html.TextBoxFor(modelItem => item.QtyUsePerMonth)
</td>
<td>
#Html.TextBoxFor(modelItem => item.TotalPVPerMonth)
</td>
</tr>
}
</table>
<input type="submit" value="Submit">
}
And this is my HttpPost method
[HttpPost]
public ActionResult Survey(List<Models.SurveyViewModel> model)
{
...
}
When the user click on the Submit button I got a null for model where I am expecting to see a list.
Please let me know what I am doing wrong.
Thank you for your help.
Normally, you can't post the list of objects to the controller in default model binder.
Best solution you can pass the object only based on Index to perform the CRUD operation in POST, and GET request you could get all list of objects. So in POST method it works if pass the object only.
If you want to post the list of object, you can achieve it by overriding the ModelBinder or using the FormCollection.
Here is an example, but to perform this way of operation we need to iterate and convert into the list. Because formcollection contains more number of items and not in the List type. The key of the property varies, because of html helper. Be aware when getting the value from formcollection.
[HttpPost]
public ActionResult Index(FormCollection model)
{
List<SurveyViewModel> obj = new List<SurveyViewModel>();
var name =Request.Form["item.Name"].Split(',').ToArray();
var pv =Request.Form["item.PV"].Split(',').ToArray();
//length must be same
for (var i = 0; i < name.Length; i++)
{
obj.Add(new SurveyViewModel()
{
Name = name[i],
PV = Convert.ToDouble(pv[i])
});
}
return View();
}

Partial View is not rendering td elements inside foreach razor tag

I am using a List of Products as a Model for my Partial view. In the partial view I am using a foreach loop to get the values of Product class and trying to render it to users. In the partial view I've written this code:
#model Project.ViewModel.ListofProductsVM
#using Project.Models
<table>
<tr>
<th>
Name
</th>
<th>
Cost
</th>
</tr>
#{
foreach (Products prod in Model.products)
{
<tr>
<td>#prod.Name.ToString()</td>
<td>#prod.Cost.ToString()</td>
</tr>
}
}
</table>
I can see the headers "Name" and "Cost" in the page but Product Name and its Cost is not rendering. When I am checking the source code in HTML it is showing me this HTML only:
<table>
<tr>
<th>
Name
</th>
<th>
Cost
</th>
</tr>
</table>
While debugging I can see the values are correctly getting passed to Partial Views. Even the "#prod.Name" and "#prod.Cost" is showing me the correct value. But it is not rendering it to HTML. I don't understand what I am doing wrong here. Thanks in advance.
The #{ } means that this is c# code block, you can fix the problem by writing your foreach loop code this way:
#foreach (Products prod in Model.products)
{
<tr>
<td>#prod.Name.ToString()</td>
<td>#prod.Cost.ToString()</td>
</tr>
}
and if you want to stick with your way then you have to specify to render that as html like:
#{
foreach (Products prod in Model.products)
{
#:<tr>
#:<td>#prod.Name.ToString()</td>
#:<td>#prod.Cost.ToString()</td>
#:</tr>
}
}
I had a similiar problem. In my case, all I needed was to add "#" before the foreach nested in an if statement. This is a pared down snippet of my working code
C# Model class:
public class MyModel
{
public string FirstName{ get; set; }
public string LastName{ get; set; }
}
CSHTML file:
#model List<MyProject.Models.MyModel>
#if (Model.Count > 0)
{
<div class="row" >
<table>
#foreach (var item in Model)
{
<tr>#item.FirstName #item.LastName</tr>
}
</table>
</div>
}
But it's the same answer that another user gave you.

How to display a collection in View of ASP.NET MVC Razor project?

How to display a collection in View of ASP.NET MVC Razor project?
My Model and View is below. For one person i've to display Many tests on the screen. Thanks in Advance
namespace UI.Models
{
public class SuperStudent
{
public string FullName { get; set; }
public ICollection<TestDetail> CandidateTestDetails { get; set; }
}
public class TestDetail
{
public DateTime TestDate { get; set; }
public string RegNum { get; set; }
}
}
View
#model IEnumerable<UI.Models.SuperStudent>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FullName)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
Print all test details
</td>
</tr>
}
</table>
For one person your view must be like :
#model UI.Models.SuperStudent
<h2>#Model.FullName</h2>
<table class="table">
<tr>
<th>
TestDate
</th>
<th>
RegNum
</th>
</tr>
#foreach (var item in Model.CandidateTestDetails ) {
<tr>
<td>
#item.TestDate
</td>
<td>
#item.RegNum
</td>
</tr>
}
</table>
The code works the same inside a loop as it does outside the loop. Just reference the loop item. For example:
#foreach (var student in Model) {
#foreach (var test in student.CandidateTestDetails) {
<tr>
<td>#test.RegNum</td>
</tr>
}
}
That would output just the RegNum value. You can also make use of things like DisplayNameFor by referencing an element in the collection:
#foreach (var student in Model) {
#foreach (var test in student.CandidateTestDetails) {
<tr>
<td>
#Html.DisplayNameFor(model => student.CandidateTestDetails.First().RegNum)<br />
#test.RegNum
</td>
</tr>
}
}
While intuitively it may seem that this could fail if Model is empty (since First() would throw an exception), it doesn't actually execute First() on the collection. The engine simply uses that to reflect into the model returned by First() to determine the display name.
Given this, you can construct the markup however you wish for those items. If it's complex enough, you might even create a partial view for just an item in that collection and render that partial view in the loop by passing the item value to the partial view.

How to display list items in view passed from the controller ?

I am developing MVC app.
I want to create the list in the controller and pass it to the view.
I have written the method in the controller but dont know how to call it form view and display the value which it return.
Method in controller.
public List<Invoice> GetInvoiceList(int Pid)
{
List<Invoice> Invoices = new List<Invoice>();
var InvoiceList = (from i in db.Invoices
where i.PaymentAdviceId == Pid
select i);
Invoices = InvoiceList.ToList();
return (Invoices);
}
View Code
<div class="row-fluid">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Advice No
</th>
<th>
Invoices
</th>
</tr>
</thead>
#foreach (var item in Model)
{
<tbody>
<tr>
<td>
#Html.DisplayFor(modelItem => item.AdviceNo)
</td>
I wan to call the controller method GetInvoiceList here and
want to display list items here...
<td>
</tr>
</tbody>
Add a PartialView to your project that has it's model set to List<Invoice>
then modify your code:
public PartialViewResult GetInvoiceList(int Pid)
{
List<Invoice> Invoices = new List<Invoice>();
var InvoiceList = (from i in db.Invoices
where i.PaymentAdviceId == Pid
select i);
Invoices = InvoiceList.ToList();
return PartialView("partialViewName", Invoices);
}
in your other view:
<tr>
<td>
#Html.DisplayFor(modelItem => item.AdviceNo)
</td>
<td> #Html.Action("GetInvoiceList", new {Pid = item.id})</td>
</tr>

Resources