通过HttpClient

时间:2018-03-26 12:46:55

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

我试图通过httpclient发布匿名对象,但是当命中控制器时,orderId为null且集合为空。

    public async Task<Response> CancelOrderAsync(int orderId, ICollection<int> ids)
    {
        Response result = null;
        using (IHttpClient client = HttpClientFactory.CreateHttpClient())
        {
            var obj = new {OrderId = orderId, Ids = ids};
            string json = JsonConvert.SerializeObject(obj);
            HttpContent postContent = new StringContent(json, Encoding.UTF8, "application/json");

            using (var response = await client.PostAsync($"{url}/admin/cancel", postContent).ConfigureAwait(false))
            {
                if (response != null && response.IsSuccessStatusCode)
                {
                    ...
                }
            }
        }

        return result;
    }


    // Controller
    [HttpPost]
    [ActionName("cancel")]
    public async Task<Response> Cancel(int orderId, ICollection<int> ids)
    {
        // order is null, collection empty
        ...

编辑:

为简单起见,将我的控制器更改为此

    [HttpPost]
    [ActionName("cancel")]
    public async Task<SimpleResponse> Cancel(int orderId)

通过Postman,我发布了这个机构:

{
  "orderId": "12345"
}

仍然,orderId为0(零)??

2 个答案:

答案 0 :(得分:3)

服务器端的控制器操作需要具体类型来读取请求的整个主体

public class Order {
    public int OrderId { get; set; }
    public int[] Ids { get; set; }
}

这主要是因为动作只能从身体上读取一次。

将行动更新为......

[HttpPost]
[ActionName("cancel")]
public async Task<Response> Cancel([FromBody]Order order) {
    if(ModelState.IsValid) {
        int orderId = order.OrderId;
        int[] ids = order.Ids;
        //...
    }
    //...
}

用于在示例中发送请求的原始代码将按原样运行,但如上所述,它可以进行改进。

答案 1 :(得分:1)

HttpClient可以为您进行序列化。看看

var response = await client.PostAsJsonAsync($"{url}/admin/cancel", obj);

效果更好。那你就不需要自己编写序列化代码了。

如果您仍有问题,请使用Fiddler等工具监控实际请求,并查看请求正文中提交的参数和值,以查看它们是否与端点的预期相符。