Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient PostAsync posting null content

I have one api calling another.

and here is my code which seems to cause ModelState.IsValid = false on the other side of world.

var baseUri = new Uri("http://localhost:5001/"):
_httpClient.BaseAdress = baseUri;
var data = new StringContent(content: model.Tostring(),
             encoding: Encoding.UTF8, 
             mediaType: "application/json");

var response = await _httpClient.PostAsync("api/product", data);

watching Post([FromBody]Product product) on the api being called I just see product=null.

changing to Post([FromBody]object product) also shows null.

calling the api from Postman works perfectly fine. which localize my problem to PostAsync. what's going on with my PostAsync?

Edit:

I know people might suggest PostAsJsonAsync, but I'll try it only after I know what's the problem with PostAsync. :(

like image 271
rethabile Avatar asked Jan 15 '17 11:01

rethabile


People also ask

What is httpclient postasync?

The HTTP request content to send to the server. The object representing the asynchronous operation. See HttpClient for examples of calling HttpClient.PostAsync. This operation will not block. The returned IAsyncOperationWithProgress (of HttpResponseMessage and HttpProgress) completes after the whole response (including content) is read.

Why doesn't post async return a Content-Type header?

PostAsync ( "http://localhost", null) There is no 'Content-Type' header sent on the wire to the server and thus, probably, the server can't echo one back. It is invalid for the server, in general, to send a 'Content-Type' header back as the response header unless it is the correct 'Content-Type' header for the response body.

What is the difference between postasync and sendrequestasync methods?

The PostAsync and PutAsync methods only allow setting a limited number of HTTP content headers. In contrast, the SendRequestAsync method allows setting headers on the request message as well as on the HTTP content to be sent. Below are the exceptions that this function throws.

Is it possible to call an asynchronous method in post async?

In a nutshell, you can't call an asynchronous method as it causes a deadlock to occur when method2 attempts to return execution to the caller. Hi Richard, Iis there a way tu await PostAsync?


1 Answers

As indicated in the comments the model was not being converted to JSON when you called model.ToString. You eventually figured out that you can use Json.Net to serialize the model to JSON with JsonConvert.SerializeObject(model). This will work for serializing the model to JSON.

You could go one step further and create an extension method to perform that functionality for you

public class JSONStringExtension {
    public static string ToJsonString(this object model) {
        if(model is string) throw new ArgumentException("mode should not be a string");
        return JsonConvert.SerializeObject(model);
    }
}

This will now allow you to call the method on your model and covert it to JSON in your code.

var baseUri = new Uri("http://localhost:5001/"):
_httpClient.BaseAdress = baseUri;
var data = new StringContent(content: model.ToJsonString(), //<--Extension method here
             encoding: Encoding.UTF8, 
             mediaType: "application/json");

var response = await _httpClient.PostAsync("api/product", data);

The PostAsJsonAsync extension method that is frequently used basically performs the same thing you eventually realized by abstracting the JSON serialization step for you. internally it is calling the same PostAsync method.

which would look something a little like this

public static Task<HttpResponseMessage> PostAsJsonAsync(this HttpClient httpClient, string url, object content) {
    var json = JsonConvert.SerializeObject(content)
    var data = new StringContent(content: json,
                 encoding: Encoding.UTF8, 
                 mediaType: "application/json");
     return httpClient.PostAsync(url, data);
}
like image 155
Nkosi Avatar answered Sep 25 '22 16:09

Nkosi