ASP.NET MVC ViewModel Generics - PullRequest
       3

ASP.NET MVC ViewModel Generics

1 голос
/ 01 апреля 2011

Я пытаюсь создать представление, которое принимает экземпляр моего собственного класса RichListViewModel, а затем создает симпатичный список элементов в модели представления, вызывая Html.DisplayFor для каждого из них (пытаясь сохранить приложениеСУХОЙ, поместив все это в один частичный вид).Однако у меня возникают проблемы с тем, какой тип объявить в файле .cshtml ... Я попытался:

@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&rsquo;t any @String.Format("{0}s", Model.SetMemberName.ToLower()) available right now. Check back soon, or call us at @Model.PhoneNumber.</div>
}

Но затем я получаю это сообщение ...

Ошибка сервера в приложении.Элемент модели, переданный в словарь, имеет тип «MyProject.ViewModels.RichListViewModel 1[MyProject.ViewModels.SaleViewModel]', but this dictionary requires a model item of type 'MyProject.ViewModels.RichListViewModel 1 [System.Object]».

Фактический RichListViewModel<T> - это именно то, что вы ожидаете, ипрекрасно компилируется - это просто класс с параметром типа, который реализует IEnumerable<T> и имеет свойства, необходимые для заполнения вышеприведенной информации.

Возможно ли то, что я пытаюсь сделать чистым способом?Если да, то как мне это сделать?

Ответы [ 2 ]

2 голосов
/ 01 апреля 2011

Нельзя преобразовать RichListViewModel<SaleViewModel> в RichListViewModel<object>.

Если вы передаете RichListViewModel<SaleViewModel> представлению, вы должны объявить его как RichListViewModel<SaleViewModel>.

В качестве альтернативы, вы можете использовать универсальный ковариантный интерфейс, который был бы конвертируемым.

1 голос
/ 01 апреля 2011

Здесь вы ошиблись, предполагая, что генерики следуют полиморфным правилам для указанного типа.Google Covariance vs Contravariance

Если ученик происходит от человека, то:

List<Student> != List<Person>

Здесь динамический (по сути, объект) не тот тип, в который вы передаете.удар здесь)

...