上礼拜在公司开荒Web API,被爆出翔了。遇到个具体问题是这样的:Web API中的方法接受的参数是个复杂对象,这个对象里嵌套了另一个对象。但使用API的人不知道如何在JSON里传递复杂对象给Web API。大家一起爆了很久,尝试了各种写法,还是没能解决。

今天我突然想到一个办法,可以获取正确的Nested JSON字符串。并且开荒成功了。与大家分享:

首先,我写的例子是这样的,Product对象里嵌套了一个Category对象,AddProduct的方法接受的是Product对象,我不仅需要Product的信息,也需要被嵌套的Category的信息:

[HttpPost]
public string AddProduct(Product productModel)
{
    var sb = new StringBuilder();

    sb.Append("Product.Id = " + productModel.Id);
    sb.Append("Product.Name = " + productModel.Name);

    if (null != productModel.Category)
    {
        sb.Append("Product.Category.CategoryId = " + productModel.Category.CategoryId);
        sb.Append("Product.Category.CategoryName = " + productModel.Category.CategoryName);
    }
    
    return sb.ToString();
}

[HttpGet]
public Product GetProduct()
{
    var product = new Product()
    {
        Id = 1,
        Name = "a",
        Category = new Category()
        { 
            CategoryId = 2,
            CategoryName = "b"
        }
    };

    return product;
}

AddProduct方法是真正要给别人用的。GetProduct是为了获取正确的JSON写的临时方法。但没有它我就永远也不知道正确的JSON到底是怎么样的了。

我们还要用到一个工具,来截获HTTP请求和响应——著名的Fiddler。因为如果我们在Firefox或Chrome中直接请求“/API/Product/GetProduct”,返回的是XML。要想得到JSON,最简单的方式就是用Fiddler伪造一个请求,把type换成json:

然后,我们就可以得到一个正确的,Product对象嵌套着Category的JSON:

{ Id: '1', Name: 'a', Category: { CategoryId: '5', CategoryName: 'b' } }

现在试试用JQuery发送这个请求:

$.ajax({
    url: "/API/Product/AddProduct",
    data: "{ Id: '1', Name: 'a', Category: { CategoryId: '5', CategoryName: 'b' } }",
    dataType: "json",
    type: "POST",
    contentType: "application/json; charset=utf-8",
    success: function (data) {
        alert(data);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
        alert(textStatus + ": " + errorThrown);
    }
})

在VS中,可以看到,对象已经被正确的反序列化了:

搞定: