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 に答える