是否可以使用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”
这当前没有用,因为首先有一个前缀(“viewModel”)我可以整理,但其次bindingContext.ModelName
是“classificationItems”,它是被绑定的参数的名称而不是索引的列表中的项目,即“classificationItems [0]”
我应该补充一点,当我在global.asax中将此绑定器声明为全局ModelBinder时,它可以正常工作......
答案 0 :(得分:2)
您的自定义模型活页夹用于整个列表,而不仅仅用于每个特定项目。当您通过实现IModelBinder从头开始编写新的绑定器时,您需要处理将所有项添加到List和列表优先级等。这不是简单的代码,请检查DefaultModelBinder here。
相反,您可以扩展DefaultModelBinder
类,让它像往常一样工作,然后将这两个属性设置为true:
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;
}
可以通过向action参数添加bind属性来处理前缀,例如[Bind(Prefix="viewModel")]
所以最后你的action方法参数如下:
[Bind(Prefix="viewModel")]
[ModelBinder(typeof(SelectableLookupAllSelectedModelBinder))]
List<SelectableLookup> classificationItems