I know this question has been asked numerous times, but I haven't found an already-asked question that addresses my problem exactly. My problem is that, for some reason, I am unable to use as a model a type that inherits from the expected type.
The exact error I am getting is:
The model item passed into the dictionary is of type 'ShoppingDealsClient.Models.ListViewModel`1[ShoppingDealsClient.Models.Deal]', but this dictionary requires a model item of type 'ShoppingDealsClient.Models.ListViewModel`1[ShoppingDealsClient.Models.BaseResponseModel]'.
and I get this error whenever I try to access the page http://localhost:50548/Home/Deal
.
Let's look at the Deal.cshtml
page:
@{
ViewBag.Title = "Deals";
Layout = "~/Views/Shared/_ListLayout.cshtml";
}
All it has is a reference to _ListLayout.cshtml
:
<!DOCTYPE html>
@{
Layout = "~/Views/Shared/_MenuedLayout.cshtml";
}
@model ShoppingDealsClient.Models.ListViewModel<ShoppingDealsClient.Models.BaseResponseModel>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
</head>
<body>
<h1>
<span>@ViewBag.Title</span>
<button class='btn btn-primary pull-right'>+ Add New</button>
</h1>
<div>
@RenderBody()
</div>
</body>
</html>
As you can see, the _ListLayout.cshtml
page is expecting a ListViewModel<BaseResponseModel>
object as its model.
Below is the code where I return the view:
public ActionResult Deal()
{
return View(new ListViewModel<Deal>());
}
where Deal
inherits from BaseResponseModel
.
As you can see, I am returning the correct type in the Deal()
method, but I am still getting this type of error. Could there be a problem with my use of Layout
views? Is there a better way to use partial views that can accept models?
EDIT On My Inheritance
I am intending for this same _ListLayout
to be reused to eventually display lists of a wide range of different models that all inherit from BaseResponseModel
. That is why the inheritance I have is necessary.
I am new to MVC development, so if anyone knows of a better way to accomplish, a comment would be helpful :)
There are lots of questions that address your problem. Either you just don't recognize it as the same or those answers aren't what you want to hear.
A ListViewModel<Deal>
is NOT a ListViewModel<BaseResponseModel>
because BaseResponseModel
is not covariant. In the same way, a Cage<Tiger>
is not a Cage<Animal>
because you can add a Rabbit
to a Cage<Animal>
but not o a Cage<Tiger>
(at least without horrific results).
Do some research on covariance to see if you need to create a covariant interface or find some other solution to your problem.
An exmnaple of a covariant interface would be something like:
public interface IBaseModel<out TModel> where TModel : TBaseResponseModel
the constraint is that the interface can only output TModel
objects - it cannot accept any as input (and cannot have any properties that are covariant, like a List<TModel>
.
So an interface with get-only properties and/or properties that return covariant interfaces (like IEnumerable<TModel>
) an likely be made covariant.