6

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

4
  • 1
    Are you sure that model.ToString() produces proper JSON? And even if it is, you'd better at least use a separate method like ToJsonString or even don't put the serialization code inside that class at all. Commented Jan 15, 2017 at 12:05
  • 1
    In any case without minimal reproducible example we can't help you much. Commented Jan 15, 2017 at 12:08
  • spot on @EugenePodskal. model.ToString() was not doing what I thought it's doing. changing to content: JsonConvert.SerializeObject(model) works. is that a way to go? Commented Jan 15, 2017 at 12:28
  • That should work assuming that endpoint uses compatible model class. Commented Jan 15, 2017 at 12:33

1 Answer 1

4

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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.