Reputation: 4593
I'm trying to create a view which takes in an instance of my own class RichListViewModel
, then creates a pretty list of the elements in the view model by invoking Html.DisplayFor
on each one (trying to keep the app DRY by putting this all in one partial view). However, I'm running into trouble with what type to declare in the .cshtml file... I tried:
@model MyProject.ViewModels.RichListViewModel<dynamic>
<ol class="rich @(Model.SetName.ToLower())-list">
@if (Request.IsAuthenticated)
{
<li id="@Model.ElementName-controls" class="@Model.ElementName buttons">
<a href="@Url.Action("Create", Model.SetName, null)" class="button create-button"><span class="icon"></span> <span class="text">Add @Model.SetMemberName</span></a>
</li>
}
@foreach (var item in Model)
{
<li class="@Model.ElementName">
@Html.DisplayFor(model => item)
</li>
}
</ol>
@if (!Model.Any())
{
<div class="notice">Sorry, there aren’t any @String.Format("{0}s", Model.SetMemberName.ToLower()) available right now. Check back soon, or call us at @Model.PhoneNumber.</div>
}
But then I get this message...
Server Error in '/' Application. The model item passed into the dictionary is of type 'MyProject.ViewModels.RichListViewModel
1[MyProject.ViewModels.SaleViewModel]', but this dictionary requires a model item of type 'MyProject.ViewModels.RichListViewModel
1[System.Object]'.
The actual RichListViewModel<T>
is exactly what you'd expect, and compiles fine - it's just a class with a type parameter which implements IEnumerable<T>
and has the properties necessary to fill in the information above.
Is what I'm attempting possible in a clean way? If so, how do I go about it?
Upvotes: 1
Views: 1384
Reputation: 4092
You mistake here is assuming generics follow polymorphic rules for the specified type. Google Covariance vs Contravariance
If student derives from person then:
List<Student> != List<Person>
Here, dynamic (which is essentially object) is not the type you are passing in. Try use RichListViewModel (taking a stab here)
Upvotes: 1
Reputation: 888177
You cannot convert a RichListViewModel<SaleViewModel>
to a RichListViewModel<object>
.
If you're passing a RichListViewModel<SaleViewModel>
to the view, you should declare it as taking a RichListViewModel<SaleViewModel>
.
Alternatively, you can use a generic covariant interface, which would be convertible.
Upvotes: 2