问题
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