我们有一个自定义模型绑定器,它将json反序列化为一个对象列表,我想将该模型绑定器用于多个视图,每个视图使用不同的视图模型。
我们要避免的是必须为每个视图模型注册模型绑定器,如下所示:
Random rnd = new Random();
//inside nested for loop
while (value has already been picked){
// gives a random value btwen 0 and (n*n)-1
value = rnd.nextInt((n*n));
}
// value has not been used
puzzle [i][j]= value;
我们想要做的是让ViewModel派生自基类(他们这样做)并注册该基类:
ModelBinders.Binders.Add(typeof(ViewModelOne), new JsonPropertyBinder());
ModelBinders.Binders.Add(typeof(ViewModelTwo), new JsonPropertyBinder());
其中ModelBinders.Binders.Add(typeof(ViewModelBase), new JsonPropertyBinder());
和ViewModelOne
从ViewModelTwo
继承。我试过这个,但我没有运气。问题在于,需要自定义绑定的属性不在ViewModel基础中。我们真正想要的是以通用方式实现我的模型绑定器的优雅解决方案。
我的viewmodels中的属性也有自定义绑定的自定义属性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);
}
}
属性添加到我的viewmodel中,但没有成功。虽然,我不确定我喜欢这种方法,因为我想将活页夹的注册保留在一个地方,而不是分散
- 编辑 -
我想我可以创建一个继承自[ModelBinder]
的中间类(例如ViewModelIntermediate
),只包含我要自定义绑定的属性,然后有ViewModelBase
和{{1从ViewModelOne
继承,以便我可以使用派生的ViewModel注册一次绑定,例如
ViewModelTwo
但这似乎是一个笨拙的解决方案。我希望能够声明一次自定义绑定器并将其与任何视图模型一起使用 - 而不必将我的类抽象为遗忘。
现在我认为我可能需要声明一个新的默认绑定器,它继承自DefaultModelBinder并且在那里有一些逻辑来检查某些(或自定义)属性并相应地处理它们。像this
这样的东西答案 0 :(得分:4)
我认为您可能正在寻找的是一个自定义模型绑定提供程序..基本上是一个超级抽象,它决定了模型类型所使用的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());
P.S。 nit:为了清楚起见,我会将JsonPropertyBinder
重命名为JsonPropertyModelBinder
。