0

2 つの機能を必要とする MVC アプリのカスタム バインディング シナリオがあります。

1)フォーム/クエリ プロパティをクラス プロパティにマッピングできる、汎用で再利用可能なカスタム バインダー。

2)特定のフォーム/クエリ パラメータをディクショナリ (または 2 つのプロパティ) に分割する、クラス固有のカスタム バインダー。

最初の要件は、Google で見つけた解決策で達成されました (見つけた場所を忘れたため、リンクを提供できないことをお詫びします)。

要するに、2つの部分があります

public class BindAliasAttribute : Attribute {
    ...
    public string Alias { get; set; }
    ...
}

これは次のように使用されます

public class SearchRequest {
   ...
   [BindAlias("q")]
   public string SearchTerms { get; set; }
   ...
}

2枚目は

public class AliasModelBinder : DefaultModelBinder {
   ...
   protected override ProperyDescriptorCollection GetModelProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) {
      var returnProps = base.GetModelProperties(controllerContext, bindingContext);

      // check model for properties with alias attribute
      // add additional PropertyDescriptors as needed
   }
   ...
}

私の問題は要件#2にあります。この場合、SearchRequest クラスに追加のプロパティがあります。

public class SearchRequest {
   ...
   [BindAlias("q")]
   public string SearchTerms { get; set; }
   ...
   [BindAlias("s")]
   public IDictionary<string, string> SortOrder { get; set; }
   ...
}

Dictionary のキーはフィールド名で、Dictionary 項目の値は順序 (昇順または降順) です。

のサンプル使用

/Search?...s=Score DESC...
/Search?...s=ModifiedDate ASC&s=OwningUser DESC...

フォーム/クエリの値をバインドするために必要なロジックは次のようになります

// loop through each form/query parameter of SortOrder or s
// get the value and split it on the space
// add thw two split values to the SortOrder property as new dictionary item

Alias をサポートするために DefaultModelBinder から再度継承する必要があることはわかっています... または、この場合は AliasModelBinder (これは DefaultModelBinder から継承されます) を使用して Alias をサポートしますが、どのメソッドをオーバーライドすればよいかわからないという問題があります。DefaultModelBinder を再利用する最善の方法に関する情報はほとんどないようです (つまり、ほとんどありません)。

私のもう 1 つの質問は、2 つのカスタム モデル バインダーを使用する最善の方法に関するものです。私の知る限り、モデル バインダー チェーンはありません。#2 のソリューションがソリューション #1 について明示的に知らなくても、要件 #2 を達成する方法はありますか? 要件 2 は、単一の値を取り、それを辞書に分割することを考慮しています。SortOrder プロパティの値がエイリアス化されたフォーム/クエリ パラメータに由来することを本当に気にしますか?

どんな助けでも大歓迎です。

ありがとうございました。

ジェイソン

4

1 に答える 1

2

私は主に OnModelUpdated() をオーバーライドしてきましたが、場合によっては BindModel をオーバーライドする必要がありましたが、めったにありません。OnModelUpdated では、モデルは既にハイドレートされていますが、コントローラーと ModelBinding コンテキストに完全にアクセスできるだけでなく、適切と思われる方法でモデルを変更することもできます。

于 2013-12-16T21:04:08.600 に答える