适用于多种类型的 MVC 自定义模型绑定
本文关键字:自定义 模型 绑定 MVC 种类 类型 适用于 | 更新日期: 2023-09-27 18:34:51
我们有一个自定义模型绑定器,它将 json 反序列化为对象列表,我想将该模型绑定器用于多个视图,每个视图使用不同的视图模型。
我们要避免的是必须为每个视图模型注册模型绑定器,如下所示:
ModelBinders.Binders.Add(typeof(ViewModelOne), new JsonPropertyBinder());
ModelBinders.Binders.Add(typeof(ViewModelTwo), new JsonPropertyBinder());
我们要做的是让 ViewModels 从基类派生(他们这样做(并注册该基类:
ModelBinders.Binders.Add(typeof(ViewModelBase), new JsonPropertyBinder());
其中ViewModelOne
和ViewModelTwo
继承形式ViewModelBase
.我试过这个,但我没有任何运气。那里的问题是,需要自定义绑定的属性不在基本视图模型中。我们真正想要的是一个优雅的解决方案,以通用的方式实现我的模型绑定器。
我们还对要自定义绑定的视图模型中的属性[JsonBindable]
自定义属性,然后我在绑定器中检查此属性:
public class JsonPropertyBinder : DefaultModelBinder
{
protected override object GetPropertyValue(ControllerContext controllerContext, System.Web.Mvc.ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, System.Web.Mvc.IModelBinder propertyBinder)
{
if (propertyDescriptor.Attributes.OfType<Attribute>().Any(x => (x is JsonBindableAttribute)))
{
var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue;
return JsonConvert.DeserializeObject(value, propertyDescriptor.PropertyType);
}
return base.GetPropertyValue(controllerContext, bindingContext, propertyDescriptor, propertyBinder);
}
}
我尝试将 [ModelBinder]
属性添加到我的视图模型中,但没有成功。虽然,我不确定我是否喜欢这种方法,因为我想将活页夹的注册保留在一个地方,而不是分散开来
--编辑--我想我可以创建一个中间类(例如 ViewModelIntermediate
(,它将从ViewModelBase
继承,仅包含我要自定义绑定的属性,然后ViewModelOne
和ViewModelTwo
从ViewModelIntermediate
继承,以便我可以使用派生的 ViewModel 注册一次绑定器,例如
ModelBinders.Binders.Add(typeof(ViewModelIntermediate), new JsonPropertyBinder());
但这似乎是一个笨拙的解决方案。我希望能够声明一次自定义绑定程序并将其用于任何视图模型 - 而不必将我的类抽象为遗忘。
现在我在想我可能必须声明一个新的默认绑定器,它继承自 DefaultModelBinder,并且其中有一些逻辑来检查某些(或自定义(属性并相应地处理它们。 像这样的东西
我认为您可能正在寻找的是一个自定义模型绑定提供程序......基本上是一个超级抽象,它确定在给定模型类型的情况下使用哪种ModelBinder。
因此,基本上,实现 IModelBinderProvider
接口,并让 GetBinder
方法根据您的条件返回模型绑定器。
public class ViewModelBaseBinderProvider
: IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
// this or whatever condition you want to apply to determine
// if your model binder needs to be used.
if (typeof(ViewModelBase).IsAssignableFrom(modelType))
return new JsonPropertyBinder();
// this means, the view model did not match our criteria
// let it flow through the usual model binders.
return null;
}
}
定义自定义提供程序后,在应用程序中注册,如下所示:
ModelBinderProviders.BinderProviders.Add(new ViewModelBaseBinderProvider());
PS Nit:为了清楚起见,我将JsonPropertyBinder
重命名为JsonPropertyModelBinder
。