8

URIにネストされた配列を持つ複雑なオブジェクトを、GET 要求で MVC アクション メソッドに送信したいと考えています。

次のコードを検討してください。

 public ActionResult AutoCompleteHandler([FromUri]PartsQuery partsQuery){ ... }

 public class PartsQuery
 {
     public Part[] Parts {get; set; }
     public string LastKey { get; set; }
     public string Term { get; set; }
 }

 $.ajax({ 
    url: "Controller/AutoCompleteHandler", 
    data: $.param({                                        
                      Parts: [{ hasLabel: "label", hasType: "type", hasIndex : 1 }],
                      LastKey : "Last Key",
                      Term : "Term"                             
                   }),
    dataType: "json", 
    success: function(jsonData) { ... }
 });

これは問題なく動作し、 MVC Web Apiの既定のモデル バインダーを使用して正しくバインドします。

ただし、これを WebApi ではなくプレーンな MVC に切り替えると、デフォルトのモデル バインダーが機能しなくなり、ネストされた配列内のオブジェクトのプロパティをバインドできなくなります。

ウォッチリスト

partsQuery      != null          //Good
--LastKey       == "Last Key"    //Good
--Term          == "Term"        //Good
--Parts[]       != null          //Good
----hasLabel    == null          //Failed to bind
----hasType     == null          //Failed to bind
----hasIndex    == 0             //Failed to bind

FromUriAttributeこれがプレーン MVC で失敗する理由と、プレーン MVC でこのオブジェクトを正しくバインドする方法を知りたい

4

1 に答える 1

10

ここでの中心的な問題は、MVC と WebApi が異なるモデル バインダーを使用することです。基本インターフェースも異なります。

Mvc - System.Web.Mvc.IModelBinder
Web API - System.Web.Http.ModelBinding.IModelBinder

$.ajax 呼び出しでデータを送信すると、次のクエリ文字列パラメーターが送信されます。

Parts[0][hasLabel]:label
Parts[0][hasType]:type
Parts[0][hasIndex]:1
LastKey:Last Key
Term:Term

一方、MVC の既定のモデル バインダーとバインドする適切な形式では、パラメーター名の命名規則が異なります。

Parts[0].hasLabel:label
Parts[0].hasType:type
Parts[0].hasIndex:1
LastKey:Last Key
Term:Term

したがって、このメソッド呼び出しは機能します。

$.ajax({ 
    url: "Controller/AutoCompleteHandler?Parts[0].hasLabel=label&Parts[0].hasType=type&Parts[0].hasIndex=1&LastKey=Last+Key&Term=Term",
    dataType: "json", 
    success: function(jsonData) { ... }
});

MVC モデル バインダーの命名規則に従って、クエリ文字列を作成する必要があります。

さらに[FromUri]、サンプル アクションの属性は、MVC DefaultModelBinder に認識されていないため、完全に無視されます。

于 2013-07-10T20:15:33.563 に答える