View passing wrong viewmodel - asp.net-mvc

I've created a website using ASP.Net MVC5 (VS 2013) but I guess the same problem would present itself in MVC3 or MVC4
I have the following view:
#model IEnumerable<WilhanWebsite.Models.TestimonialViewModel>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Testimonial.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.Testimonial.Author)
</td>
<td>
#Html.DisplayFor(modelItem => item.Testimonial.Timestamp)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Testimonial.TestimonialId }) |
#Html.ActionLink("Details", "Details", new { id=item.Testimonial.TestimonialId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Testimonial.TestimonialId })
</td>
</tr>
}
</table>
The Index action of my Testimonial controller sends back a List and the view displays existing testimonials correctly in the html table. My problem is that when I click the Edit hyperlink I get the following error:
The model item passed into the dictionary is of type
'WilhanWebsite.DomainClasses.Testimonial', but this dictionary
requires a model item of type
'WilhanWebsite.Models.TestimonialViewModel'
I was previously using DomainClasses.Testimonial as the model passed between controller an view but today I refactored to create the new dedicated view model. It seems strange that the view is happy to process the new viewmodel when displaying the data so why is it passing the old DomainClasses.Testimonial when I click the Edit link?
Any help greatly appreciated!

The View expects #model IEnumerable<WilhanWebsite.Models.TestimonialViewModel> so you have to return it from the Controller's Index action method. Without seeing your controller I would guess that your returning a List of type Testimonial rather than a List of Type TestimonialViewModel
// GET: /Testimonial/
public ActionResult Index()
{
List<TestimonialViewModel> testimonialViewModel = new List<TestimonialViewModel>();
// Add some testimonials to your list.
return View(testimonialViewModel);
//NOT THIS - IT WILL THROW THE ERROR YOUR GETTING
return View(db.Testimonial.ToList());
}
//Testimonial/Index
#model IEnumerable<WilhanWebsite.Models.TestimonialViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
Alternativly if you are returning a System.Collection and TestimonialViewModel is specified. Make sure that its implements IEnumerable. The following types do.
ICollection
IDictionary
IDictionaryEnumerator
IEnumerable
IEnumerator
IHashCodeProvider
IList

I was able to fix by updating the Edit action to the following:
public ActionResult Edit(int id)
{
var query = from t in _context.Testimonials
where t.TestimonialId == id
select t;
TestimonialViewModel tvm = new TestimonialViewModel();
tvm.Testimonial = query.First();
return View(tvm);
}

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();

Passing data base info from controller to view in .NET MVC

Hello I'm trying to pass some database info from my controller to my view, but don't find the best way to do it. I'm populating the model in my controller, but I need to populate those values from database. I have a class called DataAccess which is the one that contains all my queries but not sure where I should put the logic to populate. I would say a for loop in my controller to populate the values, but seems to fail since I'm declaring the SchedulerViewModel there
The idea is having my values next to a radio button, so when selecting a radio button, I can "detect" the value and do something with that option....any suggestion would be appreciated...
My model:
public class SchedulerViewModel
{
public string theValue { get; set; }
public SelectListItem[] Items { get; set; }
}
My Controller:
public ActionResult Scheduler()
{
//DataAccess dataAccess = new DataAccess();
//for loop here???
var model = new SchedulerViewModel
{
Items = new[]
{
new SelectListItem { Value = "U", Text = "USA" }
}
};
return View(model);
}
My view:
#using (Html.BeginForm())
{
for (int i = 0; i < Model.Items.Count(); i++)
{
#Html.RadioButtonFor(x => x. theValue, Model.Items[i].Value, new { id = "item_" + i })
#Html.Label("item_" + i, Model.Items[i].Text)
<br />
}
}
Ideally you would have a service class that handles your database access. You shouldn't directly invoke the data layer from the controller, although nothing prevents you from doing it. For simplicity, I'm just putting calling the data access directly in the controller. The idea is that you need to return a collection of data, here an IEnumerable, in the View at the controller level so that the View can display this data.
Controller:
[HttpGet]
public ActionResult Index()
{
KnowledgeBaseEntities context = new KnowledgeBaseEntities();
IEnumerable<ISSUE> issues = context.ISSUES;
if(issues == null)
{
return HttpNotFound();
}
return View(issues);
}
View:
As you can see I'm referencing the collection of data that I'm expecting from the controller.
#model IEnumerable<ISSUE>
In this case it's an IEnumerable just like I had in the controller. Then you'll notice I'm referencing a Model object when I iterate the model.
#foreach (var item in Model)
Then I'm looping through each row of the model in order to add table rows to the table. Because we're using Model Binding from the Entity Framework. We're using Razor Syntax. You also notice I'm using Action Links for each row in the last column. This allows me to Edit, Delete or provide Details for a row of data. However, I will need to invoke another Controller Action for that. For example, you'd have an Edit controller action method that returns a single ISSUE to an Edit View.
#model IEnumerable<ISSUE>
#{
ViewBag.Title = "Knowledge Base Issues";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2 class="line">All Issues</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="flat">
<tr>
<th>#Html.DisplayNameFor(model => model.KEYWORDS)</th>
<th>#Html.DisplayNameFor(model => model.SUBJECT)</th>
<th>#Html.DisplayNameFor(model => model.DATE_ENTERED)</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>#Html.DisplayFor(modelItem => item.KEYWORDS)</td>
<td>#Html.DisplayFor(modelItem => item.SUBJECT)</td>
<td>#Html.DisplayFor(modelItem => item.DATE_ENTERED)</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.ISSUE_ID }) |
#Html.ActionLink("Details", "Details", new { id=item.ISSUE_ID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.ISSUE_ID })
</td>
</tr>
}

Post Html table created by a model in MVC view to controller

I created a list based on the scaffolding
#model IEnumerable<FleetLink.Domain.Entities.UserTable>
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<table>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Master_IP)
#Html.TextBoxFor(modelItem=>item.Master_IP)
</td>
<td>
#Html.DisplayFor(modelItem => item.Master_Name)
</td>
</tr>
<tr><td><input type="submit" value="Submit" /></td></tr>
</table>
}
In my controller I have a get and a post method for index
[HttpPost]
public ActionResult Index(List<UserTable> list)
{
return View();
}
[HttpGet]
public ActionResult Index()
{
var users= from userTable in _repo.GetUsers()
select userTable;
return View(users);
}
I was expecting it would call post method when I clicked on submit and would pass the entire tables data to the Index HTTPPost method. But it is always calling the get method of Index. The goal is to pass entire table data after user edits it so I can save all table data at once. Please advice on what I am doing wrong.
I resolved this issue by changing the foreach to for(int i=0....) as well as changing the #using (Html.BeginForm("Index", "Home", FormMethod.Post)) to
#using (Html.BeginForm(FormMethod.Post))
Thanks

pass model to view using viewbag

i want to send two model in my view
and in other page maybe and need more
controller
ViewBag.Users = db.Users.ToList();
and in View
#using Documentation.Models
#{
var Users = (Documentation.Models.User)ViewBag.Users;
}
<table>
#foreach (var item in Users) {
<tr>
<td>
#Html.DisplayFor(item.username)
</td>
</tr>
}
</table>
but i get no answer , i know my code is not right
i got this error
foreach statement cannot operate on variables of type 'Documentation.Models.User' because 'Documentation.Models.User' does not contain a public definition for 'GetEnumerator'
you should cast viewbag.model to List of User. Not to User.
#{
var Users = (List<User>)ViewBag.Users;
}

MVC 3 - The model item passed into the dictionary is of type 'System.Collections.Generic.List`1

Hi I am very new to mvc and need help
I created this
public ActionResult Index()
{
var joblist = (from s in _entities.TaleoJobs
group s by new { s.JobTitle}
into myGroup
where myGroup.Count() > 0
select new { myGroup.Key.JobTitle }
);
return View(joblist.ToList());
}
but when I create the view I get the following error
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType01[System.String]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[careers.TaleoJobs]'.
Here is the code for the view
*#model IEnumerable<careers.TaleoJobs>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
JobTitle
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.JobTitle)
</td>
</tr>
}
</table>*
I would be grateful if anyone can help - tried looking at other examples but i am at a loss.
When you are selecting the list, you are only selecting the JobTitle, which is a string. So your list is indeed a List<string>.
You can either update your select to select the entire object:
var joblist = (from s in _entities.TaleoJobs
group s by new { s.JobTitle}
into myGroup
where myGroup.Count() > 0
select s
);
Or, keep your current select and update the type of the view to:
IEnumerable<string>

Resources