Using [FromUri] attribute - bind complex object with nested array

大兔子大兔子 提交于 2019-12-09 16:11:38

问题


I want to send a complex object with a nested array in the uri to an MVC action method in a GET request.

Consider the following code:

 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) { ... }
 });

This works just fine and binds correctly using the default model binder in MVC Web Api.

However, switch this to plain MVC not WebApi and the default model binder breaks down and cannot bind the properties on objects in the nested array:

Watch List

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

I would like to know why this breaks down in plain MVC and how to make FromUriAttribute bind this object correctly in plain MVC


回答1:


Core issue here is that MVC and WebApi use different model binders. Even base interfaces are different.

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

When you send data with your $.ajax call, you are sending following query string parameters:

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

While, proper format that would bind with MVC default model binder has different naming convention for parameter names:

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

So, this method call would work:

$.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) { ... }
});

You need to construct your query string respecting MVC model binder naming conventions.

Additionally [FromUri] attribute in your example action is completely ignored, since it's not known to MVC DefaultModelBinder.



来源:https://stackoverflow.com/questions/17578878/using-fromuri-attribute-bind-complex-object-with-nested-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!