使用[FromUri]属性 - 使用嵌套数组绑定复杂对象

问题描述 投票:8回答:1

我想在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中的默认模型绑定器正确绑定。

但是,将其切换为普通MVC而不是WebApi,并且默认模型绑定器会崩溃,并且无法绑定嵌套数组中对象的属性:

观察名单

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

我想知道为什么这会在普通的MVC中崩溃,以及如何让FromUriAttribute在普通的MVC中正确绑定这个对象

c# asp.net-mvc model-binding
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不知道它。

© www.soinside.com 2019 - 2024. All rights reserved.