I'm trying to get a agrip on MVC3 but im failing on a Viewmodel which is supposed to display a List but constantly running into an dictionary error.
The model item passed into the dictionary is of type
"marc_bew_online.ViewModels.StellenlisteViewModel", but this dictionary requires a model item of type "System.Collections.Generic.IEnumerable`1[marc_bew_online.ViewModels.StellenlisteViewModel]".
Here's the code to my repository:
public class Stellenbeschr_Repo : IStellenBeschrRepository
{
marc_bew_entities db = new marc_bew_entities();
public IEnumerable<STELLENBESCHREIBUNGEN> ListAktuell()
{
DateTime dt1 = new DateTime(2011, 1, 1);
var stelleBeschreibungAbDatum = (from stellebeschreibung in db.STELLENBESCHREIBUNGEN
where DateTime.Compare((DateTime)stellebeschreibung.VON_DATUM, dt1) >= 0
select stellebeschreibung).ToList();
return stelleBeschreibungAbDatum;
}
}
Controller + ViewModel:
private IStellenBeschrRepository _repository;
public Default1Controller()
: this(new Stellenbeschr_Repo())
{
}
public Default1Controller(IStellenBeschrRepository repository)
{
_repository = repository;
}
#endregion
public ActionResult Index()
{
return View(_repository.ListAktuell());
}
public ActionResult Stellenliste()
{
var viewModels = new StellenlisteViewModel { StellenListe = _repository.ListAktuell() };
return View(viewModels);
}
public class StellenlisteViewModel
{
public IEnumerable<STELLENBESCHREIBUNGEN> StellenListe { get; set; }
}
Viewpage extract:
#foreach(var item in Model.StellenListe)
{
<tr>
<td>
#Html.Display(item.STELLENBESCHREIBUNG);
</td>
</tr>
}
The Viewpage is currently displaying ";" for every item the LINQ expression has found
I just cant find a solution to get the list displayed in my view.
The problem is most likely your view code.
Make sure your model is declared as:
#model StellenlisteViewModel
and not:
#model IEnumerable<StellenlisteViewModel>
EDIT
From the sounds of it you may be confusing a few things.
Your page will have a single view model. On this view model will be a list of STELLENBESCHREIBUNGEN which you are wanting to display.
To do this, first make sure your view page accepts a single view model:
#model StellenlisteViewModel
Secondly, you want to add a ToList() call in your repository:
var stelleBeschreibungAbDatum = (from stellebeschreibung in db.STELLENBESCHREIBUNGEN
where DateTime.Compare((DateTime)stellebeschreibung.VON_DATUM, dt1) >= 0
select stellebeschreibung).ToList();
Thirdly, your view page will look something like this:
#model StellenlisteViewModel
foreach(var item in Model.StellenListe)
{
// output each individual item to the page
// here you can access the individual properties on your STELLENBESCHREIBUNGEN, e.g.:
<span>#item.Description</span>
}
Sorry, I don't have access to MVC3 currently, so I can't check the syntax.
EDIT#2
You are using Display incorrectly. You may wish to check the documentation for it.
It is also like DisplayFor() is what you are looking for.
Your are returning a single item rather than a list of items. You either need to declare the view to take marc_bew_online.ViewModels.StellenlisteViewModel (rather than an IEnumerable) or return a list of the viewmodel items.
Related
This question already has answers here:
The model item passed into the dictionary is of type .. but this dictionary requires a model item of type
(7 answers)
Closed 5 years ago.
I have a controller that takes in an instance of getbldgaddr_Result. I am trying to create a view that uses partials to put two separate viewmodels on the page. Below is the "Parent View"
#using DirectoryMVC.Models
#model Tuple<getbldgaddr_Result,getadministrators_Result>
#{
ViewBag.Title = "Central Office";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Central Office</h2>
<div class="row">
#*Display the getAddress view*#
#Html.Partial("_BuildingAddress", Model.Item1)
</div>
So above I am using Item1 from the model that is a getbldgaddr_Result. I have tried casting it to getbldgaddr_Result as well, but I get the below error.
The model item passed into the dictionary is of type 'System.Tuple`2[DirectoryMVC.Models.getbldgaddr_Result,DirectoryMVC.Models.getadministrators_Result]', but this dictionary requires a model item of type 'DirectoryMVC.Models.getbldgaddr_Result'.
The actual controller is...
public class BuildingAddressController : Controller
{
private DirectoryEntities de;
public BuildingAddressController()
{
de = new DirectoryEntities();
}
// GET: BldgAddr
public ActionResult BldgAddr(getbldgaddr_Result bldgres)
{
//getbldgaddr_Result bldgResult = de.getbldgaddr(district, bldg_no, null).FirstOrDefault();
return View(bldgres);
}
}
My guess is, I can have it take a tuple object as the parameter, but this seems counter intuitive. the Building Address, does not need anything in regards to administration.
Any thoughts?
Why send a Tuple back to the view? Just create a parent viewmodel having two child viewmodels—i.e. one for each item of the tuple—and return that from the controller instead.
Assuming a Tuple<Class1, Class2>, you could structure your viewmodel like this:
public class ParentViewModel
{
public Class1 ChildViewModel1 { get; set; }
public Class2 ChildViewModel2 { get; set; }
}
On the controller side, you'd simply do:
var parentViewModel = new ParentViewModel
{
ChildViewModel1 = Tuple.Item1,
ChildViewModel2 = Tuple.Item2
};
return View(parentViewModel);
Your view would then be:
#model ParentViewModel
// ...
#Html.Partial("_Partial1", Model.ChildViewModel1)
#Html.Partial("_Partial2", Model.ChildViewModel2)
Make sure that the Model.Item1 is not null. When the member/property you're passing in is null, MVC reverts back to the parent type.
I currently have a controller with a LINQ statement that i am passing data from to my view. I am trying to find a more efficient and better coding method to do this.
My home controller statement is as follows.
Var Melt
Furnace1 =
(from item in db.tbl_dppITHr
where item.ProductionHour >= StartShift && item.ProductionHour <= EndDate
select item).Sum(x => x.Furnace1Total),
ViewData["Furnace1Total"] = Melt.Furnace1;
In my view i then reference the ViewData To show this. Using
#model dynamic
Now i have quite alot of linq statements inside the Index method. And for each one i am doing the ViewData[]
I am hoping that someone can show how i pass more than one var from a controller across to a view without the ViewData or ViewBag methods. And how i would get access to this within my view.
You should create a ViewModel with all of your data needed and then pass that down to the view.
public class ViewModel
{
public List<int> Melt1 { get; set; }
public void LoadMeltProperties()
{
if (Melt1 == null)
{
Melt1 = new List<int>();
}
Melt1 = (from item in db.tbl_dppITHr
where item.ProductionHour >= StartShift && item.ProductionHour <= EndDate
select item).Sum(x => x.Furnace1Total).ToList();
}
public ViewModel Load()
{
LoadMeltProperties();
return this;
}
}
public ActionResult YourControllerAction()
{
var vm = new ViewModel().Load();
return View("ViewName", vm);
}
Then in your View you can use a strongly typed model rather than dynamic
#model ViewModel
You can then iterate over your ViewModel properties via:
foreach(var melt in Model.Melt1) {
// do what you require
}
IMHO, you should create a ViewModel an pass data using it.
Create a class
public class MyViewModel
{
public <MeltFurnace1Type> MeltFurnace1{get;set;}
}
In Action Method
public ActionResult Action()
{
MyViewModel vm = new MyViewModel();
vm.MeltFurnace1 = something;
return View("YourViewName", vm);
}
In View
#model MyViewModel
//You can access your property using
Model.MeltFurnace1
If you need to pass data actually from the controller and its data is depend on internal state or input controller parameters or has other properties of "business data" you should use Model part from MVC pattern:
Model objects are the parts of the application that implement the
logic for the application's data domain. Often, model objects retrieve
and store model state in a database. For example, a Product object
might retrieve information from a database, operate on it, and then
write updated information back to a Products table in a SQL Server
database.
You can see details here or look to the Models and Validation in ASP.NET MVC part of Microsoft tutorial.
Add model class:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public string City { get; set; }
}
Pass model object to the view:
public ActionResult Index()
{
var model = GetModel();
return View(model);
}
Add strongly typed View via define model type:
#model Person
Use Model variable in your view:
#Model.City
Use models instead
var Melt
Furnace1 =
(from item in db.tbl_dppITHr
where item.ProductionHour >= StartShift && item.ProductionHour <= EndDate
select item).Sum(x => x.Furnace1Total),
return View("SomeVIew",MeltFurnace1)
In view#model "TypeOfMeltFurnace1"
You can reference model in view by property Model
If someone is still looking for options…
You also can pass object from Controller to View, if you don’t use any particular Model for the View. To pass just a single (or maybe few) parameter from the Controller to the View, you can do it inside View() Method.
In the Controller:
public async Task<IActionResult> Update(int id)
{
return View(new { Id = id });
}
Then in the View you can access your parameter like this (assuming you don’t use any other Model inside your View):
<div>
#Html.ActionLink("Link name", "ControllerMethod", "ControllerName", new { id = (int)Model.Id })
</div>
Otherwise, like already mentioned, pass your model inside View() Method.
The goal
Work with a model in my view.
The problem
I'm getting the follow exception:
The model item passed into the dictionary is of type 'System.Linq.Enumerable+WhereSelectListIterator2[MyApp.Models.Data.bm_product_categories,<>f__AnonymousType31[System.String]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[MyApp.Models.Data.bm_product_categories]'.
Details
I'm using:
C#.Net
Razor Engine
MVC 4
Visual Studio 2012
My partial view (_CategoriesList):
#model IEnumerable<BluMercados.Models.Data.bm_product_categories>
<h1>Testing</h1>
My controller (CategoriesController) and his method:
public ActionResult Render()
{
var sluggifiedProjection =
db.bm_product_categories
.ToList()
.Select(category => new
{
CategoryNameSlugged = category.Category_Name.GenerateSlug()
});
return PartialView("_CategoriesList", sluggifiedProjection);
}
The question
How can I fix this problem? I really do not know what is the model that I have to pass from controller to view.
you are passing an anonymous type as part of the model. While you can do this with the dynamic keyword, you are probably better off making a ViewModel.
Something like
public class CategoryViewModel
{
public WhatEverTypeThisIs NameSlugged { get; set; }
}
then
public ActionResult Render()
{
var sluggifiedProjection =
db.bm_product_categories
.ToList()
.Select(category => new CategoryViewModel
{
NameSlugged = category.Category_Name.GenerateSlug()
});
return PartialView("_CategoriesList", sluggifiedProjection);
}
and the model will be something like
#model IEnumerable<BluMercados.ViewModels.CategoryViewModel>
depending what namespace you put it in
The problem is caused by the select where you currently create instances of an anonymous type with a single property CategoryNameSlugged. You should make sure that your select operation does not change the type of the enumerable. This might work out if the property can be set:
.Select(category =>
{
category.CategoryNameSlugged = category.Category_Name.GenerateSlug();
return category;
});
I am getting this error when trying to pass my object to the view. I am new to MVC so please forgive me.
The model item passed into the dictionary is of type 'System.Collections.Generic.List1[<>f__AnonymousType13[System.Int32,System.String,System.Nullable1[System.DateTime]]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[MvcApplication1.Models.storageProperty]'
I am trying to pass a list for a table that will show objects from the storageProperty table with the last date (if there is one) from the expenses table. Most properties have had at least one expense audit, some have had many, and others have had none.
Here is the code from the controller:
var viewModel = db.storageProperties.Select(s => new
{
s.storagePropertyId,
s.BuildName,
latestExpenseSurvey = (DateTime?)s.expenses.Max(e => e.expenseDate)
}).ToList();
return View(viewModel);
}
and the #model statement in the view calls for a storageproperty object. I am using mvc3 with the entity framework. It appears obvious that I cannot pass this list object in place of the storageproperty object, but I can't figure out what to do instead, how should I do this?
Thanks in advance.
Never pass anonymous objects to views. You should always pass view models.
So as always in an ASP.NET MVC application you start by defining a view model which will reflect the requirements of your view:
public class MyViewModel
{
public int StoragePropertyId { get; set; }
public string BuildName { get; set; }
public DateTime? latestExpenseSurvey { get; set; }
}
Then in your controller return an IEnumerable<MyViewModel>:
public ActionResult Index()
{
var viewModel = db.storageProperties.Select(s => new MyViewModel
{
StoragePropertyId = s.storagePropertyId,
BuildName = s.BuildName,
LatestExpenseSurvey = (DateTime?)s.expenses.Max(e => e.expenseDate)
}).ToList();
return View(viewModel);
}
and finally strongly type your view to a collection of this view model:
#model IEnumerable<MyViewModel>
<div>
#Html.EditorForModel()
</div>
Your Linq query projects to an anonymous type. You need to create a named type for this projection in order to refer to it from the view.
I am using the following code for a master view model that contains two lists of data,
namespace trsDatabase.Models
{
public class masterViewModel
{
public IEnumerable <Customer> Customers { get; set; }
public IEnumerable <CustomerSite> CustomerSites { get; set; }
}
}
I am using the following code to pass the veiwmodel to the view,
public ViewResult Index()
{
masterViewModel sitesModel = new masterViewModel();
return View(sitesModel);
}
Then in my view I have the following,
#model IEnumerable<trsDatabase.Models.masterViewModel>
foreach (var site in customer.CustomerSites)
{
foreach (var cust in customer.Customers)
{
<tr>
<td>
#cust.CustomerName
</td>
<td>
#site.UnitNo
</td>
using the above code I am able to access all properties from the two lists in the viewmodel, however when I navigate to the view I get an error as the view is expecting an IEnumerable. If I change the declaration to just pass the viewmodel
#model trsDatabase.Models.masterViewModel
the foreach statement won't work, it gives this error
The model item passed into the dictionary is of type 'trsDatabase.Models.masterViewModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[trsDatabase.Models.masterViewModel]'.
Can anyone offer any advice or point me in the right direction for resolving this, is it possible to make my viewmodel IEnumerable?
Change this
#model IEnumerable<trsDatabase.Models.masterViewModel>
to this
#model trsDatabase.Models.masterViewModel
You are passing in a single instance of masterViewModel, so your view should expect a single instance, which is exactly what the error is telling you if not in a cryptic way.
Yes You can...
in you Model (masterViewModel) make the Customers and CustomerSites List like this:
namespace trsDatabase.Models
{
public class masterViewModel
{
public List<Customer> Customers { get; set; }
public List<CustomerSite> CustomerSites { get; set; }
}
}
in the same Model, define a method that would return IEnumerable like this:
public IEnumerable<Customer> Getall()
{
List<Customer> lcustomer= new List<Customer>();
//Get Customer data from Database or wherever
lcustomer.Add(new Customer{ firstname= "Quentin ", lastname= "tarantino" });
return lcustomer;
}
In your controller, instantiate your Model. then call Getall() method which would return IEnumerable basically a list of customers, and pass it to your View
var rep = new masterViewModel();
var model = rep.Getall();
return View(model);