【问题标题】:Complex type is getting null in a ApiController parameter复杂类型在 ApiController 参数中为空
【发布时间】: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);
    }
});

【问题讨论】:

    标签: c# ajax json asp.net-web-api


    【解决方案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;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 2021-08-30
      • 1970-01-01
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多