2013-02-13 51 views
0

是否可以使用ModelBinderAttribute绑定到集合?MVC 3 ModelBinding使用ModelBinderAttribute的集合

这里是我的操作方法参数:

[ModelBinder(typeof(SelectableLookupAllSelectedModelBinder))] List<SelectableLookup> classificationItems 

这是我的自定义模型粘合剂:

public class SelectableLookupAllSelectedModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     var model = bindingContext.Model as SelectableLookup ?? 
          (SelectableLookup)DependencyResolver.Current.GetService(typeof(SelectableLookup)); 

     model.UId = int.Parse(bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue); 
     model.InitialState = true; 
     model.SelectedState = true; 

     return model; 
    } 
} 

下面是该参数的发布JSON数据:

"classificationItems":["19","20","21","22"]}

以下是ValueProvider看到它的方式:

viewModel.classificationItems[0] AttemptedValue = “19” viewModel.classificationItems[1] AttemptedValue = “20” viewModel.classificationItems[2] AttemptedValue = “21” viewModel.classificationItems[3] AttemptedValue = “22”

当前不工作,因为首先有一个前缀( “视图模型” )我可以理清,但其次bindingContext.ModelName是“classificationItems”这是参数的名称被绑定到,而不是列表中的索引项,即“分类项[0]”

我应该补充说,当我将此资料夹声明为全局ModelBin der in global.asax it works fine ...

+0

更改动作方法的签名接收一个收集成员的对象。 – 2013-02-13 12:50:25

回答

2

您的自定义模型联编程序正用于整个列表,而不仅仅是针对每个特定项目。由于您正在通过实施IModelBinder从头开始编写新的联编程序,因此您需要处理将所有项目添加到列表和列表首选项等情况。这不是简单的代码,请检查DefaultModelBinder here

相反,你可以扩展DefaultModelBinder类,让它照常上班,然后设置的2个属性为真:

public class SelectableLookupAllSelectedModelBinder: DefaultModelBinder 
{ 

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     //Let the default model binder do its work so the List<SelectableLookup> is recreated 
     object model = base.BindModel(controllerContext, bindingContext); 

     if (model == null) 
      return null; 

     List<SelectableLookup> lookupModel = model as List<SelectableLookup>; 
     if(lookupModel == null) 
      return model; 

     //The DefaultModelBinder has already done its job and model is of type List<SelectableLookup> 
     //Set both InitialState and SelectedState as true 
     foreach(var lookup in lookupModel) 
     { 
      lookup.InitialState = true; 
      lookup.SelectedState = true; 
     } 

     return model;   
    } 

前缀可以通过添加绑定属性的动作参数进行处理像[Bind(Prefix="viewModel")]

那么,到底你的操作方法参数会是什么样子:

[Bind(Prefix="viewModel")] 
[ModelBinder(typeof(SelectableLookupAllSelectedModelBinder))] 
List<SelectableLookup> classificationItems