-1

I am trying to view the cart on my page which is already using a different view model. Here is my Layout:

@RenderBody()
....
<div id="cd-shadow-layer"></div>
<div id="cd-cart">
    @Html.Partial("_ItemsCartPartial", (Model as List<TShirtEmpAdmin.Models.Order>))
</div>

The view that is rendered in the body is using

@model TShirtEmpAdmin.ViewModels.ShirtOrdersViewModel

THe html partial is rendering

@model IEnumerable<TShirtEmpAdmin.Models.Order>

The model item passed into the dictionary is of type 'ViewModels.ShirtOrdersViewModel', but this dictionary requires a model item of type 'Models.Order'.

How do I fix this?

Skullomania
  • 2,225
  • 2
  • 29
  • 65
  • 1
    Maybe add an Order property to ShirtOrdersViewModel? – Rick Hodder Jan 27 '17 at 20:55
  • What model does the `_ItemsCartPartial.cshtml` use. You need to pass it the same type. –  Jan 27 '17 at 20:56
  • Is your "ShirtOrdersViewModel" is inherited from "Order"? if yes then you just need an explicit case. If no then you can use utilize the implicit conversion operator overload. Create a method which will automatically convert one object to another based on implementation of overload method. – vendettamit Jan 27 '17 at 20:59
  • @StephenMuecke _ItemsCartPartial.Cshtml inherits model IEnumerable – Skullomania Jan 27 '17 at 21:00
  • `Order` and `IEnumerable` are not the same, but the message related to `ShirtOrdersViewModel`. You have not given nearly enough information in your question, but suggest you read through [The model item passed into the dictionary is of type .. but this dictionary requires a model item of type](http://stackoverflow.com/questions/40373595/the-model-item-passed-into-the-dictionary-is-of-type-but-this-dictionary-requ) to understand why the error occurs –  Jan 27 '17 at 21:03
  • I edited my question to try to make it clearer – Skullomania Jan 27 '17 at 21:10
  • Using `@Html.Partial()` in a layout where the partial declares a model makes no sense (it means you layout can only use one type). And `Model as List` would result in `null` since `ShirtOrdersViewModel` cannot be cast to `List` –  Jan 27 '17 at 21:18
  • Are you wanting every page using that layout to display your collection of Orders? If so, then use `@{ Html.RenderAction(...)` to call a server method that returns a partial view or all Orders –  Jan 27 '17 at 21:20

1 Answers1

2

The error occurs because your view is using a model that is typeof ShirtOrdersViewModel and its layout is calling a partial that expects List<Order>. Because the layout has

@Html.Partial("_ItemsCartPartial", (Model as List<Order>))

you are attempting to cast the model which is ShirtOrdersViewModel to List<Order> which fails and the result of that is the same as

@Html.Partial("_ItemsCartPartial", null)

When you pass null as the model, the method uses the ViewDataDictionary of the main view and so the method now passes ShirtOrdersViewModel to a partial expecting List<Order>, hence the exception.

Your current implementation means that your layout can only be used by a view whose model is List<Order> (or is a model that derives from a BaseModel which contains a property List<Order> in which case you could use @Html.Partial("_ItemsCartPartial", Model.MyListOfOrdersProperty)). However that would be the wrong approach in your case, and instead you should create a method that returns a PartialView of the orders, for example

[ChildActionOnly]
public ActionResult Orders()
{
    List<Order> orders = .... // get orders for the current user
    return PartialView("_Orders", orders);
}

and the _Orders.cshtml file would have @model List<Order> and the code to display them. Then in the layout, render the results of the partial using

@{ Html.RenderAction("Orders", yourControllerName); }