复杂类型在 ApiController 参数中为空
Posted
技术标签:
【中文标题】复杂类型在 ApiController 参数中为空【英文标题】:Complex type is getting null in a ApiController parameter 【发布时间】:2012-10-06 15:35:42 【问题描述】:我不知道为什么我的参数“ParametroFiltro Filtro”为空,而其他参数“page”和“pageSize”却正常。
public class ParametroFiltro
public string Codigo get; set;
public string Descricao get; set;
我的 ApiController 获取方法:
public PagedDataModel<ParametroDTO> Get(ParametroFiltro Filtro, int page, int pageSize)
我的 ajax 调用:
var fullUrl = "/api/" + self.Api;
$.ajax(
url: fullUrl,
type: 'GET',
dataType: 'json',
data: Filtro: Codigo: '_1', Descricao: 'TESTE' , page: 1, pageSize: 10 ,
success: function (result)
alert(result.Data.length);
self.Parametros(result.Data);
);
【问题讨论】:
【参考方案1】:您正在尝试使用GET
方法发送一个复杂对象。失败的原因是 GET
方法不能有正文,并且所有值都被编码到 URL 中。您可以使用[FromUri]
来完成这项工作,但首先您需要更改客户端代码:
$.ajax(
url: fullUrl,
type: 'GET',
dataType: 'json',
data: Codigo: '_1', Descricao: 'TESTE', page: 1, pageSize: 10 ,
success: function (result)
alert(result.Data.length);
self.Parametros(result.Data);
);
如果您像这样更改您的操作方法,[FromUri]
将能够直接从 URL 中获取您的复杂对象属性:
public PagedDataModel<ParametroDTO> Get([FromUri]ParametroFiltro Filtro, int page, int pageSize)
您以前的方法宁愿使用可以有正文的POST
方法(但您仍然需要使用JSON.stringify()
将正文格式化为 JSON)。
【讨论】:
现在它已经奏效了,tks 很多。我浪费了整个上午试图解决它。 谢谢,工作就像一个魅力。[FromUri]
就是我所需要的!奇怪的是它甚至明确需要它......我认为 Web API 会假设它在 Uri 中,因为它是 GET
再次感谢您。有趣的是,复杂对象的参数名称(在本例中为“Filtro”)不应在请求中传递 - 非常违反直觉。我想知道如果您有具有相同名称(或对象列表)字段的子对象会发生什么 - 大概它会抛出?
看起来你必须用 [FromUri] 来装饰每个复杂的参数。我试过装饰控制器无济于事(没有例外只是没有效果),这是一种耻辱。如果有人发现其他情况,请大声疾呼。
这对我不起作用,原始类型参数有效,但对象参数仍然为空。【参考方案2】:
在进行 ajax 调用时提供 contentType
属性。使用JSON.stringify
方法构建要发布的 JSON 数据。将类型更改为POST
,MVC 模型绑定会将发布的数据绑定到您的类对象。
var filter = "Filtro": "Codigo": "_1", "Descricao": "TESTE" ,
"page": "1", "pageSize": "10" ;
$.ajax(
url: fullUrl,
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(filter),
success: function (result)
alert(result.Data.length);
self.Parametros(result.Data);
);
【讨论】:
POST
请求将建议在后端修改某些实体/集合。【参考方案3】:
还可以通过Newtonsoft.Json.Linq JObject 访问 POST 变量。
例如,这个 POST:
$.ajax(
type: 'POST',
url: 'URL',
data: 'Note': note, 'Story': story ,
dataType: 'text',
success: function (data)
);
可以像这样在 APIController 中访问:
public void Update([FromBody]JObject data)
var Note = (String)data["Note"];
var Story = (String)data["Story"];
【讨论】:
我可以通过 GET 方法来实现吗?在我的场景中,我不需要Update
,我需要基于一个假设的复杂对象及其所有属性集来Get
。【参考方案4】:
如果您将 json 数据附加到查询字符串,并稍后在 web api 端解析它。你也可以解析复杂的对象。它比发布 json 对象更有用,尤其是在一些特殊的 httpget 需求案例中。
//javascript file
var data = UserID: "10", UserName: "Long", AppInstanceID: "100", ProcessGUID: "BF1CC2EB-D9BD-45FD-BF87-939DD8FF9071" ;
var request = JSON.stringify(data);
request = encodeURIComponent(request);
doAjaxGet("/ProductWebApi/api/Workflow/StartProcess?data=", request, function (result)
window.console.log(result);
);
//webapi file:
[HttpGet]
public ResponseResult StartProcess()
dynamic queryJson = ParseHttpGetJson(Request.RequestUri.Query);
int appInstanceID = int.Parse(queryJson.AppInstanceID.Value);
Guid processGUID = Guid.Parse(queryJson.ProcessGUID.Value);
int userID = int.Parse(queryJson.UserID.Value);
string userName = queryJson.UserName.Value;
//utility function:
public static dynamic ParseHttpGetJson(string query)
if (!string.IsNullOrEmpty(query))
try
var json = query.Substring(7, query.Length - 7); //seperate ?data= characters
json = System.Web.HttpUtility.UrlDecode(json);
dynamic queryJson = JsonConvert.DeserializeObject<dynamic>(json);
return queryJson;
catch (System.Exception e)
throw new ApplicationException("can't deserialize object as wrong string content!", e);
else
return null;
【讨论】:
以上是关于复杂类型在 ApiController 参数中为空的主要内容,如果未能解决你的问题,请参考以下文章
值不能为空。参数名称:routeCollection + ApiController
如何在 ApiController 中为单个方法返回 JSON?