4

我有一个自定义模型绑定器,它为进入操作方法的特定参数调用:

public override ActionResult MyAction(int someData, [ModelBinder(typeof(MyCustomModelBinder))]List<MyObject> myList ... )

这很好用——按预期调用活页夹。但是,我想为Request.Form 集合中的一些附加值调用默认模型绑定器。表单键的命名如下:

dataFromView[0].Key
dataFromView[0].Value
dataFromView[1].Key
dataFromView[1].Value

如果我将 IDictionary 添加为操作方法的参数,默认模型绑定器会很好地将这些值转换为 IDictionary。

但是,我想在模型绑定器级别(以及上面的原始 List 对象)操作这些值。

有没有办法让默认模型绑定器从BindModel()我的自定义模型绑定器的方法中的表单值创建这个字典?

public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
    //Get the default model binder to provide the IDictionary from the form values...           
}

我尝试使用 bindingContext.ValueProvider.GetValue,但是当我尝试转换为 IDictionary 时,它似乎总是返回 null。

4

2 回答 2

4

这是我发现的一个潜在解决方案(通过查看默认模型绑定器源代码),它允许您使用默认模型绑定器功能来创建字典、列表等。

创建一个新的 ModelBindingContext 详细说明您需要的绑定值:

var dictionaryBindingContext = new ModelBindingContext()
            {
                ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => null, typeof(IDictionary<long, int>)),
                ModelName = "dataFromView", //The name(s) of the form elements you want going into the dictionary
                ModelState = bindingContext.ModelState,
                PropertyFilter = bindingContext.PropertyFilter,
                ValueProvider = bindingContext.ValueProvider
            };

var boundValues = base.BindModel(controllerContext, dictionaryBindingContext);

现在,使用您指定的绑定上下文调用默认模型绑定器,并将正常返回绑定对象。

到目前为止似乎工作...

于 2012-07-10T10:13:43.550 回答
3

如果您的模型绑定器需要使用其他一些表单数据,这意味着您没有将此模型绑定器定位在正确的类型上。您的模型活页夹的正确类型如下:

public class MyViewModel
{
    public IDictionary<string, string> DataFromView { get; set; }
    public List<MyObject> MyList { get; set; }
}

进而:

public class MyCustomModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var model = base.BindModel(controllerContext, bindingContext);

        // do something with the model

        return model;
    }
}

进而:

[HttpPost]
public ActionResult Index([ModelBinder(typeof(MyCustomModelBinder))] MyViewModel model)
{
    ...
}

这假设发布了以下数据:

dataFromView[0].Key
dataFromView[0].Value
dataFromView[1].Value
dataFromView[1].Key
myList[0].Text
myList[1].Text
myList[2].Text
于 2012-07-10T08:54:04.673 回答