ShaneKm
ShaneKm

Reputation: 21328

Post anonymous object via HttpClient

I'm trying to post anonymous object via httpclient, however orderId is null and collection empty when it hits controller.

    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
        ...

EDIT:

Changed my controller to this for simplicity

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

Via Postman, i'm posting this body:

{
  "orderId": "12345"
}

Still, orderId comes in as 0 (zero) ??

Upvotes: 3

Views: 5866

Answers (2)

Nkosi
Nkosi

Reputation: 247088

The controller action on the server side will need a concrete type to read the entire body of the request

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

This is primarily because the action can only read from the body once.

Update action to...

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

the original code used to send the request in the example will work as is, but as mentioned it can be improved.

Upvotes: 4

ADyson
ADyson

Reputation: 61859

The HttpClient can do the serialisation for you. See if

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

works better. Then you don't need to write the serialisation code yourself.

If you still have a problem, use a tool such as Fiddler to monitor the actual request and see what parameter and values are submitted in the request body, to see if they match what's expected by the endpoint.

Upvotes: 2

Related Questions