Change from List to IEnumerable - c#

My application stops and give me this error message:
The model item passed into the dictionary is of type
'System.Collections.Generic.List`1[Test.Models.GamesVM]',
but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1
[Test.Models.Runner]'.
My Controller:
return PartialView("PartialViewAllRunners", db.Runners.ToList());
My View:
#Html.Partial("~/Views/Shared/PartialViewAllRunners.cshtml", Model)
Both View and the Partial View has IEnumerable, so what is the problem and what needs to be changed?

Edit - Change your view model to this:
#model IEnumerable < ModelClass Name>
return View(db.modelclass.ToList());

Related

The model item passed into the ViewDataDictionary is of type 'Castle.Proxies.Model' in nopcommerce 4.2

This error throws me when I am pass data to the model and call the view.
Here is the full error shows,
An unhandled exception occurred while processing the request.
InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'Castle.Proxies.VendorProxy', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IList`1[Nop.Web.Models.Common.VendorDetailModel]'.
Now, I create one model, one view and controller in nopcommerce 4.2.
Here is my model place,
Nop.Web => Models => Common => VendorDetailModel
Here is the code of mode
public VendorDetailModel()
{
Address = new List<AddressModel>();
}
public string Name { get; set; }
public IList<AddressModel> Address { get; set; }
Here is the controller placed
Nop.Web => Controllers => CommonController => Vendordetail(method)
Here is the controller code
public virtual IActionResult Vendordetail(int vendorId)
{
var model = _vendorService.GetVendorById(vendorId);
return View("Vendordetail",model);
}
Here is the view placed,
Nop.Web => Views => Common => Vendordetail.cshtml
Here is the view code
#model VendorDetailModel
content.......
So, this error is showing when I place the #model VendorDetailModel in view file while if I remove this line then error is not showing. But I remove this line then how can I get the value without model.
Maybe at some point in your view, you are passing the wrong model to a partial view. In my case, my view was getting a model for "BOX", and using a partial view expecting a model for "ORDER" but I didn't explicitly pass the "ORDER" model to the partial, so the partial view was getting the default "BOX" model, which was wrong and was triggering this "Castle.model.proxy" error.
I got the solution.
problem is that I didnt giving the value to the model, just passing the store data variable from controller to view.
Here is my solution code.
var model = new VendorDetailModel();
var vendor = _vendorService.GetVendorById(vendorId);
model.Name = vendor.Name;
return View(model);
and view page is same as it is previous

Is it possible to populate a DropDownListFor if the model returned to the View is an IEnumerable

I'm obviously missing something.
I thought populating a DropDownListFor would be as easy as returning a list from the controller.
In my controller I return:
public ActionResult ListCollege()
{
return View(db.Colleges.ToList());
}
And the in the View I set the model as:
#model IEnumerable<CollegeApp.Models.DataModels.College>
But that's clearly not the right way to populate a DropDownListFor helper.
I've been doing a bit of reading and I wasn't exactly sure of the role of the new SelectList as the second argument in the DropDownListFor which is meant to be of type IEnumerable<SelectListItem>.
And I don't quite get how this IEnumerable<SelectListItem> is passed from the model/controller to the view.
Thanks
To use The DropDownListFor helper method effectively, you need to use a property of your view model to pass as the expression parameter, which will be a lambda expression. The helper will build the SELECT element with name and Id attribute values matching to that property name. The second parameter of the helper is a collection of SelectListItem , which will be used as the source data to build the options for the dropdown.
So in your case, create a view model which has 2 properties, one for the collection and one for the selected value
public class CollageSelectionVm
{
public IEnumerable<SelectListItem> Collages { set;get;}
public int SelectedCollage { set;get;}
}
And in your GET action, create an object of this view model, load the Collages collection property and send that object to the view
public ActionResult ListCollege()
{
var vm = new CollageSelectionVm () ;
vm.Collages = db.Collages
.Select(x=>new SelectListItem { Value = x.Id.ToString(),
Text=x.Name })
.ToList();
return View(vm);
}
Now in the view,which is strongly typed to your view model, you will use the DropDownListFor helper
#model CollageSelectionVm
#Html.DropDownListFor(a => a.SelectedCollage , Model.Collages , "Select one")

Partial View loading wrong model

I have a partial view in which I have a model specified as such:
#model IEnumerable<AbstractThinking2015.Models.BlogModel>
#foreach (var item in Model.Take(5))
{
<li>#Html.ActionLink(item.Title, "Details", new { id = item.BlogModelId })</li>
}
And I'm calling this using:
<div class="widget">
<h4>Recent Posts</h4>
<ul>
#Html.Partial("View")
</ul>
</div>
But I'm getting the error:
The model item passed into the dictionary is of type
'AbstractThinking2015.Models.BlogModel', but this dictionary requires
a model item of type
'System.Collections.Generic.IEnumerable`1[AbstractThinking2015.Models.BlogModel]'.
I'm sure this is because the model being passed into the view is the single blog but I want to use the list that's defined in the partial view. Is there a way to do this?
If you do not pass a model t the partial explicitly, It will take the model of the parent view. So from your error message, It is clear that you are passing a single object of the BlogModel to your view from your action method, hence getting the error.
You need to make sure that your main view (where you are calling the partial), is also strongly typed to a collection of BlogModel objects.
public ActionResult Index()
{
var blogList=new List<Models.BlogModel>();
// or you may read from db and load the blogList variable
return View(blogList);
}
And the Index view, where you are calling the Partial will be strongly typed to a collection of BlogModel.
#model List<Models.BlogModel>
<h1>Index page which will call Partial</h1>
<div class="widget">
<h4>Recent Posts</h4>
<ul>
#Html.Partial("View")
</ul>
</div>

Assign viewbag value to model items causes an error in mvc4

I am trying to pass an value from my view to my controller:
public ActionResult Create(int id)
{
ViewBag.ConferenceRegesterId = id;
return View();
}
As you can see in create action i save my id in viewbag .i need this id in post back so i have this code for postback :
[HttpPost]
public ActionResult Creat(MvcConference.Models.Details1 ObjDetails)
{
dbcontext.Details1.Add(ObjDetails);
dbcontext.SaveChanges();
List<MvcConference.Models.Details1> lstuser = dbcontext.Details1.ToList();
return View("Index");
}
I use this code to assign my viewbag value to my model item in my create view
#Html.HiddenFor(model => model.ConferenceRegesterId=ViewBag.ConferenceRegesterId)
but finally after executing i got this error :
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation
I will be apprciate for any help
Best regards
You can't just assign the value for a model's property in a view (through viewbag) like the way you're currently doing, because you're not creating an instance of the class. Please note that only value bound to the input elements are posted back to the controller.
Slightly change the way your program currently behaves. Your create action in the controller will crate an instance for your viewmodel and initialize the required members (ConferenceRegesterId). This model will be strongly bound to the create view.
public ActionResult Create(int id)
{
MvcConference.Models.Details1 viewmodel = new MvcConference.Models.Details1();
viewmodel.ConferenceRegesterId = id;
return View(viewmodel);
}
Your create view
#model MvcConference.Models.Details1
#using (Html.BeginForm())
{
......
#Html.HiddenFor(model => model.ConferenceRegesterId)
}
Now your ObjDetails in POST action can access the value of ConferenceRegesterId you passed through the hiddenfield input element.
You don't need any model. That's simple problem. When you use a ViewBag you must convert that object to static object on your Razor View.
Like that;
#{
string varName = ViewBag.varName;
}
And you will not see again that;
Compiler Error Message: CS1963: An expression tree may not contain a dynamic operation

Passing list to view in asp.net mvc

Here is my action method from controller.
public class MoviesController : Controller
{
private MovieDBContext db = new MovieDBContext();
// GET: /Movies/
public ActionResult Index()
{
return View( db.Movies.ToList() );
}
}
As it can be seen a List is being passed to View that is why I am expecting to work with it as Listin view but in View it works as IEnumerable
Following is the first line from View
#model IEnumerable<MVCWebApplication2.Models.Movie>
Why passed value that was List behaves as IEnumerable?
Is IEnumerable super class of List?
List<T> implements the IEnumerable<T> interface:
http://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx
It is typically a best practice to try to work with interfaces where possible to keep your code decoupled, so that's why the View was scaffolded like that. In this instance, you could pass any other Movie collection that implements IEnumerable<T> to your View, and your View would happily render without issue.
So, imagine you have another Action in some other Controller like:
public ActionResult Index()
{
Queue<Movie> movies = new Queue<Movie>();
movies.Enqueue(db.Movies.Single(m => m.Title == "Flash Gordon"));
movies.Enqueue(db.Movies.Single(m => m.Title == "Star Wars"));
return View( "Movie/Index", movies );
}
Because Queue<T> implements IEnumberable<T>, movies will get rendered by the same View without having to make any changes to it. If your View was typed to List<Movies>, you would need to create a whole separate View to accommodate your Queue<Movies> model!
As Chris mentioned, List<T> implements IEnumerable<T>, so that is why it is valid for the View's model to be:
#model IEnumerable<MVCWebApplication2.Models.Movie>
Since you said you want to use it as a List, the List also implements IList<T> which should provide you with the functionality you were expecting to have in your view.
You can make use of the List methods like so:
#model IList<MVCWebApplication2.Models.Movie>
<div>
First movie: #Model.First().Name
</div>
#Model.Count Action Movies:
<ul>
#foreach (var item in Model.Where(x => x.Type = "ActionMovie"))
{
<li>#item.Name - #item.Description</li>
}
</ul>

Categories