I am trying to pass ModelView variables from controller to views but unfortunately views not allowing me to access variables. I mention code below.
Here is the ViewModel:
public class AuctionViewModels
{
public List<Auction> AllAuction { get; set; }
public List<Auction> PromotedAuction { get; set; }
}
Here is the Controller action that passes the data to the View:
public ActionResult Index()
{
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); //If we need to send more then 1 model to views
vmodel.PromotedAuction = service.GetPromotedAuction();
return View(vmodel);
}
Here is view:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
#foreach (var auction in Model.AllAuction )
{
<img class="card-img-top" src="http://placehold.it/700x400" alt="">
}
Here is Error:
CS1061: 'List<AuctionViewModels>' does not contain a definition for
'AllAuction' and no extension method 'AllAuction' accepting a first
argument of type 'List<AuctionViewModels>' could be found (are you missing
a using directive or an assembly reference?)
Can anyone tell me what actually i am doing wrong?
Change
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
To
#model DealDouble.Web.ViewModels.AuctionViewModels
Then you'll be able to do foreach(var auction in Model.AllAuction)
you have error in line:
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
you pass (as a model) Class, not list. List does not contain such property as AllAuction. try to replace this line with this one:
#model DealDouble.Web.ViewModels.AuctionViewModels
It should just be
#model DealDouble.Web.ViewModels.AuctionViewModels
You're only passing in one instance of this object, and then iterating over the AllAuction property.
You're instantiating a single object containing two fields both of which are lists:
AuctionViewModels vmodel = new AuctionViewModels();
vmodel.AllAuction = service.GetAllAuction(); /
vmodel.PromotedAuction = service.GetPromotedAuction();
But treating it as if it were a list in the view
#model List<DealDouble.Web.ViewModels.AuctionViewModels>
You need to change the above to:
#model DealDouble.Web.ViewModels.AuctionViewModels
You can then iterate over the two fields
#foreach (var auction in Model.AllAuction ){}
#foreach (var auction in Model.PromotedAuction ){}
Related
I have 2 Tables with separate Controllers & Views in the Same Database one called
Part
Another Called
Assembly
In my Edit View i get the data from the Parts Table.
I need to ALSO get specific data from the Assembly Table in the Edit view for Parts. The data i need to get has the same Column name.
I need to use #foreach to get / display this data in the Part Edit View
Below is what i'm using
#model WebSpares3.Data.Part
#foreach (var item in Model.Assembly) {
How can i specifically reference the Name from The Assembly table into the parts data if they have the same column name in each of the tables?
You can create a Model or ViewModel for this:
public class ViewModel
{
public Part MyPart { get; set;}
public Assembly MyAssembly { get; set;}
}
Then this is what you will pass to your view:
public ActionResult Create()
{
ViewModel model = new ViewModel();
model.MyPart = new MyPart ()
{
ColumnName1 = "Details here",
ColumnName2 = 1
}
model.MyAssembly = //populate your Assembly details class
return View(model); //return your view with two classes on one class
}
Now you can do this on your razor view:
#Html.DisplayFor(x => x.MyPart.ColumnName1)
#Html.DisplayFor(x => x.MyPart.ColumnName2)
and this one:
#Html.DisplayFor(x => x.MyAssembly.ColumnName1)
#Html.DisplayFor(x => x.MyAssembly.ColumnName2)
This question and community wiki answer has been added to assist in closing out numerous unanswered questions as discussed in this meta post.
I have some code and when it executes, it throws an exception saying:
The model item passed into the dictionary is of type Bar but this dictionary requires a model item of type Foo
What does this mean, and how do I fix it?
The error means that you're navigating to a view whose model is declared as typeof Foo (by using #model Foo), but you actually passed it a model which is typeof Bar (note the term dictionary is used because a model is passed to the view via a ViewDataDictionary).
The error can be caused by
Passing the wrong model from a controller method to a view (or partial view)
Common examples include using a query that creates an anonymous object (or collection of anonymous objects) and passing it to the view
var model = db.Foos.Select(x => new
{
ID = x.ID,
Name = x.Name
};
return View(model); // passes an anonymous object to a view declared with #model Foo
or passing a collection of objects to a view that expect a single object
var model = db.Foos.Where(x => x.ID == id);
return View(model); // passes IEnumerable<Foo> to a view declared with #model Foo
The error can be easily identified at compile time by explicitly declaring the model type in the controller to match the model in the view rather than using var.
Passing the wrong model from a view to a partial view
Given the following model
public class Foo
{
public Bar MyBar { get; set; }
}
and a main view declared with #model Foo and a partial view declared with #model Bar, then
Foo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault();
return View(model);
will return the correct model to the main view. However the exception will be thrown if the view includes
#Html.Partial("_Bar") // or #{ Html.RenderPartial("_Bar"); }
By default, the model passed to the partial view is the model declared in the main view and you need to use
#Html.Partial("_Bar", Model.MyBar) // or #{ Html.RenderPartial("_Bar", Model.MyBar); }
to pass the instance of Bar to the partial view. Note also that if the value of MyBar is null (has not been initialized), then by default Foo will be passed to the partial, in which case, it needs to be
#Html.Partial("_Bar", new Bar())
Declaring a model in a layout
If a layout file includes a model declaration, then all views that use that layout must declare the same model, or a model that derives from that model.
If you want to include the html for a separate model in a Layout, then in the Layout, use #Html.Action(...) to call a [ChildActionOnly] method initializes that model and returns a partial view for it.
This question already has a great answer, but I ran into the same error, in a different scenario: displaying a List in an EditorTemplate.
I have a model like this:
public class Foo
{
public string FooName { get; set; }
public List<Bar> Bars { get; set; }
}
public class Bar
{
public string BarName { get; set; }
}
And this is my main view:
#model Foo
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
#Html.EditorFor(m => m.Bars)
And this is my Bar EditorTemplate (Bar.cshtml)
#model List<Bar>
<div class="some-style">
#foreach (var item in Model)
{
<label>#item.BarName</label>
}
</div>
And I got this error:
The model item passed into the dictionary is of type 'Bar', but this
dictionary requires a model item of type
'System.Collections.Generic.List`1[Bar]
The reason for this error is that EditorFor already iterates the List for you, so if you pass a collection to it, it would display the editor template once for each item in the collection.
This is how I fixed this problem:
Brought the styles outside of the editor template, and into the main view:
#model Foo
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
<div class="some-style">
#Html.EditorFor(m => m.Bars)
</div>
And changed the EditorTemplate (Bar.cshtml) to this:
#model Bar
<label>#Model.BarName</label>
Observe if the view has the model required:
View
#model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>
<div class="row">
<table class="table table-striped table-hover table-width-custom">
<thead>
<tr>
....
Controller
[HttpGet]
public ActionResult ListItems()
{
SiteStore site = new SiteStore();
site.GetSites();
IEnumerable<SiteViewModel> sites =
site.SitesList.Select(s => new SiteViewModel
{
Id = s.Id,
Type = s.Type
});
return PartialView("_ListItems", sites);
}
In my case I Use a partial view but runs in normal views
Consider the partial map.cshtml at Partials/Map.cshtml. This can be called from the Page where the partial is to be rendered, simply by using the <partial> tag:
<partial name="Partials/Map" model="new Pages.Partials.MapModel()" />
This is one of the easiest methods I encountered (although I am using razor pages, I am sure same is for MVC too)
First you need to return an IEnumerable version of your model to the list view.
#model IEnumerable<IdentityManager.Models.MerchantDetail>
Second, you need to return a list from the database. I am doing it via SQL Server, so this is code I got working.
public IActionResult Merchant_Boarding_List()
List<MerchantDetail> merchList = new List<MerchantDetail>();
var model = new MerchantDetail();
try
{
using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
{
con.Open();
using (var command = new SqlCommand("select * from MerchantDetail md where md.UserGUID = '" + UserGUID + "'", con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
model.biz_dbaBusinessName = reader["biz_dbaBusinessName"].ToString();
merchList.Add(model);
}
}
}
}
}
catch (Exception ex)
{
}
return View(merchList);
Passing the model value that is populated from a controller method to a view
public async Task<IActionResult> Index()
{
//Getting Data from Database
var model= await _context.GetData();
//Selecting Populated Data from the Model and passing to view
return View(model.Value);
}
one more thing.
if your view is a partial/sub page and the model for that partial view is null for some reason (e.g no data) you will get this error. Just need to handle the null partial view model
This question and community wiki answer has been added to assist in closing out numerous unanswered questions as discussed in this meta post.
I have some code and when it executes, it throws an exception saying:
The model item passed into the dictionary is of type Bar but this dictionary requires a model item of type Foo
What does this mean, and how do I fix it?
The error means that you're navigating to a view whose model is declared as typeof Foo (by using #model Foo), but you actually passed it a model which is typeof Bar (note the term dictionary is used because a model is passed to the view via a ViewDataDictionary).
The error can be caused by
Passing the wrong model from a controller method to a view (or partial view)
Common examples include using a query that creates an anonymous object (or collection of anonymous objects) and passing it to the view
var model = db.Foos.Select(x => new
{
ID = x.ID,
Name = x.Name
};
return View(model); // passes an anonymous object to a view declared with #model Foo
or passing a collection of objects to a view that expect a single object
var model = db.Foos.Where(x => x.ID == id);
return View(model); // passes IEnumerable<Foo> to a view declared with #model Foo
The error can be easily identified at compile time by explicitly declaring the model type in the controller to match the model in the view rather than using var.
Passing the wrong model from a view to a partial view
Given the following model
public class Foo
{
public Bar MyBar { get; set; }
}
and a main view declared with #model Foo and a partial view declared with #model Bar, then
Foo model = db.Foos.Where(x => x.ID == id).Include(x => x.Bar).FirstOrDefault();
return View(model);
will return the correct model to the main view. However the exception will be thrown if the view includes
#Html.Partial("_Bar") // or #{ Html.RenderPartial("_Bar"); }
By default, the model passed to the partial view is the model declared in the main view and you need to use
#Html.Partial("_Bar", Model.MyBar) // or #{ Html.RenderPartial("_Bar", Model.MyBar); }
to pass the instance of Bar to the partial view. Note also that if the value of MyBar is null (has not been initialized), then by default Foo will be passed to the partial, in which case, it needs to be
#Html.Partial("_Bar", new Bar())
Declaring a model in a layout
If a layout file includes a model declaration, then all views that use that layout must declare the same model, or a model that derives from that model.
If you want to include the html for a separate model in a Layout, then in the Layout, use #Html.Action(...) to call a [ChildActionOnly] method initializes that model and returns a partial view for it.
This question already has a great answer, but I ran into the same error, in a different scenario: displaying a List in an EditorTemplate.
I have a model like this:
public class Foo
{
public string FooName { get; set; }
public List<Bar> Bars { get; set; }
}
public class Bar
{
public string BarName { get; set; }
}
And this is my main view:
#model Foo
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
#Html.EditorFor(m => m.Bars)
And this is my Bar EditorTemplate (Bar.cshtml)
#model List<Bar>
<div class="some-style">
#foreach (var item in Model)
{
<label>#item.BarName</label>
}
</div>
And I got this error:
The model item passed into the dictionary is of type 'Bar', but this
dictionary requires a model item of type
'System.Collections.Generic.List`1[Bar]
The reason for this error is that EditorFor already iterates the List for you, so if you pass a collection to it, it would display the editor template once for each item in the collection.
This is how I fixed this problem:
Brought the styles outside of the editor template, and into the main view:
#model Foo
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
<div class="some-style">
#Html.EditorFor(m => m.Bars)
</div>
And changed the EditorTemplate (Bar.cshtml) to this:
#model Bar
<label>#Model.BarName</label>
Observe if the view has the model required:
View
#model IEnumerable<WFAccess.Models.ViewModels.SiteViewModel>
<div class="row">
<table class="table table-striped table-hover table-width-custom">
<thead>
<tr>
....
Controller
[HttpGet]
public ActionResult ListItems()
{
SiteStore site = new SiteStore();
site.GetSites();
IEnumerable<SiteViewModel> sites =
site.SitesList.Select(s => new SiteViewModel
{
Id = s.Id,
Type = s.Type
});
return PartialView("_ListItems", sites);
}
In my case I Use a partial view but runs in normal views
Consider the partial map.cshtml at Partials/Map.cshtml. This can be called from the Page where the partial is to be rendered, simply by using the <partial> tag:
<partial name="Partials/Map" model="new Pages.Partials.MapModel()" />
This is one of the easiest methods I encountered (although I am using razor pages, I am sure same is for MVC too)
First you need to return an IEnumerable version of your model to the list view.
#model IEnumerable<IdentityManager.Models.MerchantDetail>
Second, you need to return a list from the database. I am doing it via SQL Server, so this is code I got working.
public IActionResult Merchant_Boarding_List()
List<MerchantDetail> merchList = new List<MerchantDetail>();
var model = new MerchantDetail();
try
{
using (var con = new SqlConnection(Common.DB_CONNECTION_STRING_BOARDING))
{
con.Open();
using (var command = new SqlCommand("select * from MerchantDetail md where md.UserGUID = '" + UserGUID + "'", con))
{
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
model.biz_dbaBusinessName = reader["biz_dbaBusinessName"].ToString();
merchList.Add(model);
}
}
}
}
}
catch (Exception ex)
{
}
return View(merchList);
Passing the model value that is populated from a controller method to a view
public async Task<IActionResult> Index()
{
//Getting Data from Database
var model= await _context.GetData();
//Selecting Populated Data from the Model and passing to view
return View(model.Value);
}
one more thing.
if your view is a partial/sub page and the model for that partial view is null for some reason (e.g no data) you will get this error. Just need to handle the null partial view model
This is how I have made a previous post as you can see here.
must retrieve the list from the database
I have tried to make my foreach which have been previously described. but it causes problems for not running my foreach in through while making the mistake on it.
Index.cshtml
#foreach (var u in Model)
{
<div class="col-md-6 col-sm-6">
<div class="plan">
<h3>#u.Name<span>$#u.Price</span></h3>
<p>#u.Text</p>
</div>
</div>
}
and undervisningController.cs
// GET: Undervisning
public ActionResult Index()
{
DatabaseClasseDataContext db = new DatabaseClasseDataContext();
var model = db.Packages.ToList();
return View(model);
}
And the top on index.cshtml have i:
#model MentorOrdblind_MVC.Models.Undervisning.Undervisning
Model Undervisning.cs
public class Undervisning
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Hours { get; set; }
public string Text { get; set; }
}
You are passing your view a List<T> but your model is not a type of IEnumerable. So your view is only expecting a single object of the type Undervisning and not a collection.
Use this:
#model IEnumerable<MentorOrdblind_MVC.Models.Undervisning.Undervisning>
Change your model delcaration to:
#model IEnumerable<MentorOrdblind_MVC.Models.Undervisning.Undervisning>
At this moment your model is a single class, not a list of objects
Always keep in mind what is being passed from controller action to view. If you pass only model from the action then use the model reference in the respective view of the action. If you pass List then use IEnumerable model reference in the view.
If you pass list from action then in the view use:
#model IEnumerable<your model> in the top as reference
If you pass model without a list then use:
#model your model
In your case you are passing list so use IEnumerable of your desired model class.
Thanks
I am trying to get started learning MVC. I built the MVC Music Store project that I found on the Microsoft site. http://www.asp.net/mvc/tutorials/mvc-music-store/mvc-music-store-part-1.
I got it working pretty well but I ran into trouble when I tried to modified it. I want to put the data in a separate project. I used Linq to Entities for the data access.
Here is my class to access the data
public class clsUtilities
{
Utilities.MVCMusicStoreEntities db = new Utilities.MVCMusicStoreEntities();
public object GetAlbums(string GenreName)
{
var query = from tags in db.vieAlbumArtists
where tags.GenreName.Equals(GenreName)
select tags;
return query;
}
}
In my Controller my code is
public ActionResult Browse2(string genre)
{
// retrieve Genre and its associated albums from the database
var genreModel = mcloUtilities.GetAlbums(genre);
return View(genreModel);
}
I generate a cshtml file in my view
#model Utilities.vieAlbumArtist
#{
ViewBag.Title = "Browse2";
}
This all compiles ok but when I run it I get:
The model item passed into the dictionary is of type System.Data.Objects.ObjectQuery'1[Utilities.vieAlbumArtist], but this dictionary requires a model item of type Utilities.vieAlbumArtist.
Change
#model Utilities.vieAlbumArtist
to
#model IEnumerable<Utilities.vieAlbumArtist>
You are returning a list of vieAlbumArtist, not just a single instance.
You might also want to change
public object GetAlbums(string GenreName)
to
public IEnumerable<Utilities.vieAlbumArtist> GetAlbums(string GenreName)
Passing objects around is not the best idea.
This is your problem:
public object GetAlbums(string GenreName)
You're returning the data as an object. But the view expects to receive an item of type Utilities.vieAlbumArtist. Either change the GetAlbums() method to return the appropriate type, or make sure you cast it in the controller to the type the view is expecting.
I was able to solve this with the help of the hints you guys gave me.
From clsUtilies
public class clsUtilities
{
Utilities.MVCMusicStoreEntities db = new Utilities.MVCMusicStoreEntities();
public IEnumerable<Utilities.vieAlbumArtist> GetAlbums(string GenreName)
{
IEnumerable<vieAlbumArtist> query = from tags in db.vieAlbumArtists
where tags.GenreName.Equals(GenreName)
select tags;
foreach (var n in query)
{
}
return query;
}
From Controller
public ActionResult Browse2(string genre)
{
// retrieve Genre and its associated albums from the database
var genreModel = mcloUtilities.GetAlbums(genre);
return View(genreModel );
}
From Views
#model IEnumerable< Utilities.vieAlbumArtist>
#{
ViewBag.Title = "Browse Albums";
}
#foreach(var album in Model)
{
<ul>
<a href="#Url.Action("Details", new { id=album.AlbumId})">
<img alt="#album.Title" src="#album.AlbumArtUrl" />
<span>#album.Title ( #album.Name ) </span> </a>
</ul>
}
}
To display a list of albums try this:
<ul>
#foreach(var item in vieAlbumArtist)
{
<li>item.Name</li> //Not sure if you actually have a name property
}
</ul>