0

是否可以使用 绑定到集合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 时,它可以正常工作...

4

1 回答 1

2

您的自定义模型绑定器用于整个列表,而不仅仅是每个特定项目。当您通过实现 IModelBinder 从头开始​​编写新的活页夹时,您需要处理将所有项目添加到列表和列表前缀等。这不是简单的代码,请在此处检查 DefaultModelBinder 。

相反,您可以扩展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;          
    }

可以通过将绑定属性添加到操作参数来处理前缀,例如[Bind(Prefix="viewModel")]

所以最后你的动作方法参数看起来像:

[Bind(Prefix="viewModel")]
[ModelBinder(typeof(SelectableLookupAllSelectedModelBinder))] 
List<SelectableLookup> classificationItems
于 2013-02-13T19:33:53.520 回答