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;
});
Related
I am darned new to the world of MVC 5 .NET... I am trying to get my head around the Tree Control from Ignite UI.
I need to retrieve my data from my model and pass it to my view... However, I keep getting the following error:
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery1[System.String]', but this dictionary requires a model item of type 'System.Linq.IQueryable1[DataViewer.Models.Viewer]'.
Here is my model:
namespace DataViewer.Models
{
[Table("dbo.table")]
public class Viewer
{
[Key, Column(Order=0)] public long id { get; set; }
public int Revision { get; set; }
public string GeoPSRType { get; set; }
public string GeoName { get; set; }
public string L2Name { get; set; }
public string L3Name { get; set; }
}
}
etc.
And my Controller:
namespace DataViewer.Controllers
{
public class ViewerController : Controller
{
private ViewerDBContext db = new ViewerDBContext();
public ActionResult Index()
{
var result = db.Items.Select(i => i.GeoName).Distinct().OrderBy(n => n);
return View(result);
}
}
}
And my view:
#model IQueryable<DataViewer.Models.Viewer>
#using Infragistics.Web.Mvc
#(Html.Infragistics().Tree()
.DataSource(Model)
.Bindings(b =>
b.TextKey("GeoName")
.PrimaryKey("ID")
.ValueKey("ID")
.ChildDataProperty("L2PSRType")
)
)
.DataSource(Model)
.LoadOnDemand(true)
.DataSourceUrl(Url.Action("tree-data-on-demand"))
.DataBind()
.Render()
)
I figured the issue was that I should be passing a strongly typed return-type by using
IQueryable<Viewer> result =
db.Items.Select(i => i.GeoName).Distinct().OrderBy(n => n);
but that throws a different error:
InvalidOperationException: The model item passed into the dictionary is of type
'System.Data.Entity.Infrastructure.DbQuery`1[System.String]',
but this dictionary requires a model item of type
'System.Linq.IQueryable<DataViewer.Models.Viewer>.'
An explicit conversion exists, are you missing a cast?
Is this relating to the fact that I'm pretty rusty on strongly typed syntax, or am I just being a total maroon (or is it a combination)?
P.S. Also, I have no doubt that the Infragistics().Tree() portion of the view is not correct, I am really more concerned about getting my data to my view (at this point). I just wanted to include all code I had...
You're passing the wrong type to your view. Look at the type of model the view expects:
#model IQueryable<DataViewer.Models.Viewer>
A queryable collection of Viewer objects. But look at what you're giving it:
db.Items.Select(i => i.GeoName).Distinct().OrderBy(n => n);
A collection of GeoName properties. Is GeoName by any chance a string? (The error implies that it is.)
If your model is expecting a collection of objects, you need to give it such a collection. You can't just give it some strings and expect it to convert those strings into objects.
The problem is the view is expecting different data than you're providing it with your controller.
Inside your view:
#model IQueryable<DataViewer.Models.Viewer>
means the view is expecting an IQueryable<> collection of Viewer's, but inside your controller:
// GET: /Viewer/
public ActionResult Index()
{
var result = db.Items.Select(i => i.GeoName).Distinct().OrderBy(n => n);
return View(result);
}
You are passing a collection of strings.
You need to either return Viewer's, or change the model of the view.
Change your Action Result to this...
public ActionResult Index()
{
// var result = db.Items.Select(i => i.GeoName).Distinct().OrderBy(n => n);
Viewer model = new Viewer();
model = (from x in db.Items
select new Viewer
{
GeoPSRType = x.FieldName
}).Distinct().FirstOrDefault().OrderBy(x => x.SomeField);
return View(model);
}
There's probably some syntax errors in that query but this gives you a general understanding of what you need to pass into the View
Last days I learning ASP.NET MVC. I have a problem when I would use two or more models in "master" view.
Model one:
public class PersonController : Controller
{
private Context ctx = new Context();
public IEnumerable<Employer> employersCol { get;set; }
// GET: Person]
public ActionResult Index()
{
employersCol = ctx.employers.ToList();
return View(ctx.persons.ToList());
}
}
Model two:
public class EmployerController : Controller
{
private Context ctx = new Context();
// GET: Employer
public ActionResult Index()
{
return View(ctx.employers.ToList());
}
}
so, now in "master" view I would to display data:
#foreach (var p in Model)
{
#Html.DisplayFor(m => p.firstName);
#Html.DisplayFor(m => p.lastName);
}
#Html.Partial("~/Views/Employer/_emp.cshtml")
but the Visual Studio say:
An exception of type 'System.InvalidOperationException' occurred in
System.Web.Mvc.dll but was not handled in user code
Additional information: The model item passed into the dictionary is
of type
'System.Collections.Generic.List1[WebApplication7.Models.Person]',
but this dictionary requires a model item of type
'System.Collections.Generic.IEnumerable1[WebApplication7.Models.Employer]'.
The question is: how Can I pass the type to the partial view. Maybe you prefer another approach. Hm.. maybe I have to use Ajax.. but how?
By default, Razor will pass the page model down to the partial. Therefore, assuming the _emp.cshtml view has a model of IEnumerable<Employee> rather than IEnumerable<Person> then you can use the overload for #Html.Partial to override the model
#Html.Partial("~/Views/Employer/_emp.cshtml", Model.Cast<Employee>())
Try This (dont have a machine running vs right now) but should work
#Html.Partial("~/Views/Employer/_emp.cshtml", model.Employer) ; // the property name by which u expose your model, if your model is not an Arraylist, then you need to loop through it.
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.
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.
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.