I'm trying to display the list I made in my view but keep getting : "The model item passed into the dictionary is of type 'System.Collections.Generic.List1[System.String]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[Standings.Models.Teams]'."
My Controller:
public class HomeController : Controller
{
Teams tm = new Teams();
public ActionResult Index()
{
var model = tm.Name.ToList();
model.Add("Manchester United");
model.Add("Chelsea");
model.Add("Manchester City");
model.Add("Arsenal");
model.Add("Liverpool");
model.Add("Tottenham");
return View(model);
}
My model:
public class Teams
{
public int Position { get; set; }
public string HomeGround {get; set;}
public string NickName {get; set;}
public int Founded { get; set; }
public List<string> Name = new List<string>();
}
My view:
#model IEnumerable<Standings.Models.Teams>
#{
ViewBag.Title = "Standings";
}
#foreach (var item in Model)
{
<div>
#item.Name
<hr />
</div>
}
Any help would be appreciated :)
Your action method considers model type asList<string>. But, in your view you are waiting for IEnumerable<Standings.Models.Teams>.
You can solve this problem with changing the model in your view to List<string>.
But, the best approach would be to return IEnumerable<Standings.Models.Teams> as a model from your action method. Then you haven't to change model type in your view.
But, in my opinion your models are not correctly implemented. I suggest you to change it as:
public class Team
{
public int Position { get; set; }
public string HomeGround {get; set;}
public string NickName {get; set;}
public int Founded { get; set; }
public string Name { get; set; }
}
Then you must change your action method as:
public ActionResult Index()
{
var model = new List<Team>();
model.Add(new Team { Name = "MU"});
model.Add(new Team { Name = "Chelsea"});
...
return View(model);
}
And, your view:
#model IEnumerable<Standings.Models.Team>
#{
ViewBag.Title = "Standings";
}
#foreach (var item in Model)
{
<div>
#item.Name
<hr />
</div>
}
You are passing wrong mode to you view. Your view is looking for #model IEnumerable<Standings.Models.Teams> and you are passing var model = tm.Name.ToList(); name list. You have to pass list of Teams.
You have to pass following model
var model = new List<Teams>();
model.Add(new Teams { Name = new List<string>(){"Sky","ABC"}});
model.Add(new Teams { Name = new List<string>(){"John","XYZ"} });
return View(model);
Related
I have a ASP.Net Core project that I'm working on. So I have a Linq call that gets the information from the database and sends it back to the Controller, no problem there. When I send this data to the View I get an error
The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List`1[PhotoUploader.Models.UnitPictures]', but this ViewDataDictionary instance requires a model item of type 'PhotoUploader.Models.FileViewModel'.
Now I know why this is, Its because the model types don't match from the controller to the View. My question is, how do I assign the UnitPictures to the FileViewModel list I've created inside of it.
Model
public class UnitPictures
{
public long ImageId { get; set; }
public string FileName { get; set; }
public string FileLocation { get; set; }
public int SortOrder { get; set; }
}
View Model
public class FileViewModel
{
public FileViewModel()
{
UnitPicturesList = new List<UnitPictures>();
}
//Other Fields here
public List<UnitPictures> UnitPicturesList { get; set; }
}
Method Call return data of type UnitPictures
private List<UnitPictures> GetImages(long Id)
{
var images = (from a in _db.Images
join b in _db.AutoImage
on a.ImageId equals b.ImageId
where b.Id == Id
select new UnitPictures
{
FileLocation = "",
FileName = a.FileName,
SortOrder = 0,
ImageId = a.ImageId
}).ToList();
return images;
}
Controller
public IActionResult UnitImages(long Id, long unitId)
{
var images = GetImages(Id);
return View(images);
}
View
#model FileViewModel
<div class="row">
<div class="col-lg-4 col-md-12 mb-4 mb-lg-0">
#for (var i = 0; i < Model.UnitPicturesList.Count; i++)
{
<img
src="https://mdbcdn.b-cdn.net/img/Photos/Horizontal/Nature/4-col/img%20(73).webp"
class="w-100 shadow-1-strong rounded mb-4"
alt="Boat on Calm Water"
/>
}
</div>
If your viewmodel is of type FileViewModel, that's what you need to pass to View:
public IActionResult UnitImages(long Id, long unitId)
{
FileViewModel viewModel = new(){ UnitPicturesList = GetImages(Id) };
return View(viewModel);
}
Since you have a mutable UnitPicturesList property, just assigning it directly like this will work.
You create an instance of the view model, populate the relevant members and return that to the view.
public IActionResult UnitImages(long Id, long unitId)
var images = GetImages(Id);
FileViewModel model = new FileViewModel() {
UnitPicturesList = images
};
return View(model);
}
The will allow the view to now properly bind to the matching members in the ViewDataDictionary
You need to create an instance of FileViewModel and then assign the property UnitPictureList to the result of GetImages. Finally you return the View passing the instance of FileViewModel
public IActionResult UnitImages(long Id, long unitId)
{
var fileModel = new FileViewModel();
fileModel.UnitPicturesList = GetImages(Id);
return View(fileModel);
}
Can be shortened even more with
var fileModel = new FileViewModel{UnitPicturesList=GetImages(Id)};
I have a model passed from controller to view in my asp.net mvc5 website. Then I show the dropdownlist using the model and I want to pass an id back when submitting the form. Here is my model :
public class SiteDirectionModel
{
public int id { get; set; }
public string name { get; set; }
}
Then in the model, I use a List<SiteDirectionModel> to which I add new instances of each item I need. I fill up both these lists and then pass my model to the view.
#model List<SiteDirectionModel>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.name,new SelectList(Model.name,"Sites"));
<input type="button" value="Selectionner" class="btn btn-primary"/>
}
Then how to retrieve the ids for each name ? And how to pass it as a parameter to my controller? Such that I would have :
public ActionResult GetSiteRF(int id)
{
int newId = id;
//Call method to searchId ...
return View("CreateADUser");
}
I have given how to bind and get value from dropdown. Please use your own BL in this.
Your model should be like this.
public class Something
{
public int Id { get; set; }
public string Name { get; set; }
}
public class SiteDirectionModel
{
public SelectList MyDropDown { get; set; }
public int SelectedValue { get; set; }
}
You BL should be like this.
public List<Something> GetListofSomething()
{
//your logic.
}
Your Get method should be like this.
public ActionResult MyGetMethod()
{
SiteDirectionModel model = new SiteDirectionModel();
model.MyDropDown = new SelectList(GetListofSomething(), "key_field_name", "value_field_name", "default_value");
}
Then finally HTML
#Html.DropDownListFor(x => x.SelectedValue,Model.MyDropDown)
Okay, so i have my ViewModel and I understand what the controller does, I'm just having difficulty implementing it. I don't know how to code a controller for the ViewModel, i've tried researching it myself and can't find anything.
Here is my viewModel, how would I go about constructing the controller? Not asking you to do it for me, just how to do it
public class ViewOrderViewModel
{
//From ORDER Table
public int OrderId { get; set; }
public System.DateTime OrderDate { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string Country { get; set; }
public string Email { get; set; }
public decimal Total { get; set; }
//from Products
public List<Product> Products { get; set; }
}
UPDATE
public class ViewOrderController : Controller
{
// GET: ViewOrder
public ActionResult ViewOrders()
{
var order = new Order();
var viewModel = GetViewModel(order);
return View(viewModel);
}
public ViewOrderViewModel GetViewModel(Order orderObject)
{
ViewOrderViewModel viewModel = new ViewOrderViewModel();
viewModel.OrderId = orderObject.OrderId;
viewModel.OrderDate = orderObject.OrderDate;
viewModel.FirstName = orderObject.FirstName;
viewModel.LastName = orderObject.LastName;
viewModel.City = orderObject.City;
viewModel.Address = orderObject.Address;
viewModel.Country = orderObject.Country;
viewModel.Email = orderObject.Email;
viewModel.PostalCode = orderObject.PostalCode;
viewModel.Total = orderObject.Total;
return viewModel;
}
}
Still unsure about how to map the List of products in the ViewModel class to the list of products in the db
Typically, your view is going to be "bound" to the ViewModel. It's like saying "Ok, I'm the view for an 'Order' and I only need to worry about the properties that you defined in ViewOrderViewModel".
The controller is not required for that binding to happen. The binding is declared at the top of your view:
Order.cshtml
#Model MyProject.Web.ViewModels.ViewOrderViewModel
<div>
<!-- Html for the view-->
</div>
This allows you to access properties on that model within the view. Razor has some functions that make life easy. For example, if you want to display the OrderId it might look like this:
<span>OrderId: #Model.OrderId </span>
The view doesn't care what values are set for each of those properties, it only cares that the properties exist. Where the controller comes into play is populating those properties with the values you want and then passing the ViewModel to the view:
public ActionResult Order()
{
var viewModel = new ViewOrderViewModel();
// Load data into each property
viewModel.OrderId = 123; // etc..
// Return it to the view. Asp.net knows to return
// it to the Order.cshtml view because the view
// and the controller action share the same name.
return View(viewModel);
}
Edit: In response to your questions in the comments: If you need to populate your ViewModel with values from a different model (such as a database model) you can create a mapper like so:
public ViewOrderViewModel GetViewModel(Order orderObject)
{
ViewOrderViewModel viewModel = new ViewOrderViewModel();
viewModel.OrderId = orderObject.OrderId;
viewModel.FirstName = orderObject.FirstName;
// etc...
return viewModel;
}
and then in your controller you would do something like this:
// var order = new Order()
var viewModel = GetViewModel(order);
I am accessing Data in Controller using a WCF Service.
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
return View();
}
Now how to pass the orderdetails from Controller to view and how to access them in View.
Edit:
I have a Model :
public class OrderDetails
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public decimal UnitPrice { get; set; }
public int quanity { get; set; }
public decimal Discount { get; set; }
}
and _proxy.GetProductDetails(null) returns List<ServiceType.OrderDetails>
Do I need a Local Model at all in this scenario?
How do I display the List values in a table in my view?
Edit2:
public class AutoMapperConfig
{
public static void Configure()
{
Mapper.Map(ServiceOrders.OrderDetails, NorthWindMVCWCF.Models.OrderDetails);
}
}
Now getting the Error
'NorthWindMVCWCF.ServiceOrders.OrderDetails' is a 'type', which is not valid in the given context
'NorthWindMVCWCF.Models.OrderDetails' is a 'type', which is not valid in the given context
I prefer to create view models, I would do it as follows:
Create View Models
public class OrderDetailViewModel
{
public int OrderId { get; set; }
public int ProductId { get; set; }
public decimal UnitPrice { get; set; }
public int Quanity { get; set; }
public decimal Discount { get; set; }
}
public class OrderDetailsViewModel
{
public OrderDetailsViewModel()
{
OrderDetails = new List<OrderDetailsViewModel>();
}
public List<OrderDetailsViewModel> OrderDetails { get; set; }
}
Manual projection
You could create an OrderDetails view model and project an instance manually as follows:
var orderDetailsViewModel = new OrderDetailsViewModel();
foreach(var orderdetail in orderDetails)
{
orderDetailsViewModel.Add(new OrderDetailsViewModel { OrderId = orderDetail.OrderId, ProductId = orderDetail.ProductId, UnitPrice = orderDetail.UnitPrice, Quanity = orderDetail.quantity, Discount = orderDetail.Discount });
}
AutoMapper alternative projection
Install AutoMapper, run the following from the package manager console:
Install-Package AutoMapper
Create an AutoMapperConfig.cs in the App_Start folder with the mappings, similar to below:
public static class AutoMapperConfig
{
public static void Configure()
{
Mapper.CreateMap<OrderDetails, OrderDetailViewModel>();
}
}
In your global asax call the configure method:
protected void Application_Start()
{
...
AutoMapperConfig.Configure();
...
}
Then map in your controller:
var orderDetailsViewModel = new OrderDetailsViewModel();
orderDetailsViewModel.OrderDetails = Mapper.Map<List<OrderDetails>, List<OrderDetailsViewModel>>(orderDetails);
I prefer to use the AutoMapper approach as the mapping is defined globally and can be reused within your app.
Returning your view model
Your view model would then be passed back as follows:
return View(orderDetailsViewModel);
Razor output
You access it in your view by adding a model reference at the top:
#model OrderDetailsViewModel
Then output the properties as follows, I've only included OrderId but you can just add the fields the same way:
<table>
<tr>
<th>OrderId</th>
</tr>
#foreach(var orderDetail in Model.OrderDetails)
{
<tr>
<td>#orderDetail.OrderId</td>
</tr>
}
</table>
You have create ViewModel for that.
For example in your model folder create a class:
public class MyViewModel // Whatever name you want to give
{
//My fields which I want to pass to View
publis string Field1{get;set;}
etc
etc
}
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
List<MyViewModel> viewModelList = new List<MyViewModel>();
foreach(var orderDetail in orderDetails)
{
MyViewModel viewModel = new MyViewModel(); //Create an object of your ViewModel
viewModel.Field1 = orderDetails.Field1; //set all feilds like that
viewModelList.Add(viewModel);
}
return View(viewModelList); // Pass View Model to View
}
Note: You have to create View for your ViewModel
Like
#model `List<MyViewModel>`
then use this ViewModel to access properties.
To know more about what is ViewModel, refer to the link below:
http://sampathloku.blogspot.ae/2012/10/how-to-use-viewmodel-with-aspnet-mvc.html
in the Controller class write :
public ActionResult Index()
{
DataRerieveClient _proxy = new DataRerieveClient();
var orderDetails = _proxy.GetProductDetails(null);
return View(orderDetails);
}
i assume your project name is MvcApplication2 and your class name is in Model Folder. so add follow code in top of View (sample.cshtml) :
#model MvcApplication2.Models.OrderDetail
ok , you can use this code to access properties of DataRecieveClient :
<div class="display-label">
#Html.DisplayNameFor(model => model.F1)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.F1)
</div>
Sorry for poor english.!
I'm using mvc and I'm passing the class called DataModel as my model to the view:
public class DataModel
{
public List<ServerStats> statsPerMonthPerServer { get; set; }
}
And here is the class ServerStats:
public class ServerStats
{
public string ServerID { get; set; }
public List<ColumnData> ServerMonthStats { get; set; }
}
And here is the class ColumnData:
public class ColumnData
{
public string Date { get; set; }
public double Sum { get; set; }
}
I have managed to build my ModelData object, if I debug it, it looks like the information I want is in it, but I can not manage to print it out from the view. This is what I've tried to do:
View:
#model IEnumerable<WebApp.Models.DataModel>
#foreach (var server in Model)
{
foreach (var month in server.statsPerMonthPerServer)
{
#month.ServerID
foreach (var column in month.ServerMonthStats)
{
#column.Date <br />
#column.Sum <br />
}
}
}
And the controller where I build the DataModel and send it to the view:
DataModel dm = new DataModel();
dm.statsPerMonthPerServer = new List<ServerStats>();
foreach (var row in serverStats)
{
ServerStats ss = new ServerStats();
ss.ServerID = row.ServerID;
ss.ServerMonthStats = new List<ColumnData>();
ColumnData cd = new ColumnData();
cd.Date = row.Year.ToString() + "-" + row.Month.ToString();
cd.Sum = row.ServerSum;
ss.ServerMonthStats.Add(cd);
dm.statsPerMonthPerServer.Add(ss);
}
return View(dm);
The error I get:
The model item passed into the dictionary is of type 'WebApp.Models.DataModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[WebApp.Models.DataModel]'.
I'm using lists but it says this is a dictionary, but I assume it is talking about my lists. I've read some about the IEnumerable interface. Do I have to implement it on all the classes except DataModel? I thought the model decleration on the top of the view took care of this? Any help would be preciated!
The error message is pretty clear. Your view is strongly typed to IEnumerable<DataModel> but from your controller action you passed only a single DataModel instance to the view. I guess you meant this:
#model WebApp.Models.DataModel
#foreach (var month in Model.statsPerMonthPerServer)
{
<h3>#month.ServerID</h3>
#foreach (var column in month.ServerMonthStats)
{
#column.Date <br />
#column.Sum <br />
}
}