Унаследованные классы ASP.NET MVC ModelBinding
У меня есть вопрос о ModelBinding в ASP.NET MVC (я использую MVC 2 превью 2), связанный с наследованием.
Скажем, у меня есть следующие интерфейсы / классы:
interface IBase
class Base : IBase
interface IChild
class Child: Base, IChild
И у меня есть пользовательская модель подшивки BaseModelBinder.
Следующая работа отлично работает:
ModelBinders.Binders[typeof(Child)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IChild)] = new BaseModelBinder();
Следующие не работают (при привязке к объекту типа Child):
ModelBinders.Binders[typeof(Base)] = new BaseModelBinder();
ModelBinders.Binders[typeof(IBase)] = new BaseModelBinder();
Есть ли способ иметь связыватель модели для базового класса, который будет применяться ко всем унаследованным классам? Я действительно не хочу вводить что-то вручную для каждого возможного наследуемого класса.
Кроме того, если это возможно, есть ли способ переопределить связыватель модели для определенного класса наследования? Скажем, у меня все получилось, но мне нужно было специальное связующее для Child2.
Заранее спасибо.
2 ответа
Я выбрал простой путь, я просто динамически регистрирую все производные классы при запуске, используя отражение. Возможно, это не чистое решение, но это пара строк в коде инициализации, который просто работает;-)
Но если вы действительно хотите связываться с модельными папками (вам придется - в конце концов - но есть лучшие способы провести время;-), вы можете прочитать это и это.
Ну, я думаю, один из способов сделать это подкласс ModelBindersDictionary
Класс и переопределить метод GetBinders(Type modelType, bool fallbackToDefault).
public class CustomModelBinderDictionary : ModelBinderDictionary
{
public override IModelBinder GetBinder(Type modelType, bool fallbackToDefault)
{
IModelBinder binder = base.GetBinder(modelType, false);
if (binder == null)
{
Type baseType = modelType.BaseType;
while (binder == null && baseType != typeof(object))
{
binder = base.GetBinder(baseType, false);
baseType = baseType.BaseType;
}
}
return binder ?? DefaultBinder;
}
}
В основном обходите иерархию классов, пока не будет найдено связующее для модели или по умолчанию DefaultModelBinder
,
Следующим шагом является принятие структуры CustomModelBinderDictionary
, Насколько я могу судить, вам нужно выделить подкласс для следующих трех классов и переопределить свойство Binders: DefaultModelBinder
, ControllerActionInvoker
а также Controller
, Вы можете предоставить свой собственный статический CustomModelBinders
учебный класс.
Отказ от ответственности: это просто грубый прототип. Я не уверен, что это на самом деле работает, какие последствия это может иметь или это разумный подход. Возможно, вы захотите скачать код для фреймворка самостоятельно и поэкспериментировать.
Обновление:
Я думаю, что альтернативным решением было бы определить свой собственный CustomModelBindingAttribute
,
public class BindToBase : CustomModelBinderAttribute
{
public override IModelBinder GetBinder()
{
return new BaseModelBinder();
}
}
public class CustomController
{
public ActionResult([BindToBase] Child child)
{
// Logic.
}
}