ASP.NET MVC 3 Универсальные шаблоны отображения
Я только начал проект с использованием ASP.NET MVC 3. Я строю поверх существующей объектной системы, поэтому одно из первых, что мне нужно сделать, это определить шаблоны отображения и редактирования для различных существующих типов.
Возможно ли в MVC определить DisplayTemplate с общим аргументом? Например, у нас есть BitString<T>
класс, который принимает перечисление в качестве универсального аргумента и представляет список параметров, заключающих в себе предоставленное перечисление. Я надеюсь, что смогу определить один шаблон Display/Editor, который обрабатывает все экземпляры BitString.
В настоящее время я использую Razor для своих представлений, но я не против смешивания и сопоставления с ascx (или прямым C#, если есть способ сделать это), чтобы добиться этого
Спасибо
РЕДАКТИРОВАТЬ: Я думаю, что это может быть дуплекс этого вопроса... Но это полтора года, так что, возможно, у кого-то есть лучший ответ на данный момент? Общий частичный вид: как установить общий класс в качестве модели?
4 ответа
Проблема, которую вы описываете, является фундаментальным принципом дженериков.
ICollection<Object>
не является базовым классом ICollection<String>
даже если String
это детский класс Object
, Это делается во время компиляции, поэтому вы в основном получаете два разных определения класса ICollection. Поэтому их нельзя кастовать. (Умные люди ТАК, пожалуйста, не стесняйтесь исправлять меня на любые неточности)
В MVC3 я работал над этим, делая следующее:
class Container{
/* Stuff here */
}
class Container<T> : Container{
T Data {get;set;}
}
Тогда по вашему мнению
@model Container
Когда вам нужны только общие вещи, не зная общего типа.
@model Container<SomeDataType>
Когда вам нужны данные общего типа.
Случай использования:
Я создаю класс ModelContainer, в котором хранится моя Модель вместе с массивом сообщений об ошибках, которые могут отображаться на странице частично. Поскольку частичное можно использовать на каждой странице, он не знает, каким будет тип Generic, поэтому этот обходной путь необходим.
Это нельзя использовать, если вы пытаетесь получить доступ к общим данным, не зная их типа. Надеюсь, это решит вашу проблему.
Я согласен с ответом Дэрила, но я бы добавил небольшое улучшение.
interface IContainer{
dynamic Data {get;}
}
class Container<T> : IContainer{
T Data {get;set;}
dynamic IContainer.Data
{
get { return this.Data; }
}
}
Затем, по вашему мнению, сделайте следующее:
@model IContainer
Нет, невозможно иметь представления с универсальным типом, если этот универсальный тип не известен. Вы не можете определить модель следующим образом:
@model AppName.Models.BitString<T>
T
должно быть известно:
@model AppName.Models.BitString<SomeEnum>
При этом я бы порекомендовал вам вместо того, чтобы пытаться повторно использовать некоторые модели, которые были у вас в старой системе, чтобы подумать о том, какие модели представлений вы могли бы установить и какие будут переданы представлениям.
Это может быть не идеально, но вы должны быть в состоянии использовать
@model BitString<dynamic>