12

I'm writing an API controller intended to receive and parse the contents of a JSON asynchronous post, and am unable to read the contents of the StringContent object in that post.

Here is the section from my API controller where I expect to see the value. The value arriving in the ApiController method is null. And the jsonContent value is an empty string. What I'm expecting to see is the contents of a JSON object.

public class ValuesController : ApiController
{
    // POST api/values
    public void Post([FromBody]string value)
    {
        HttpContent requestContent = Request.Content;
        string jsonContent = requestContent.ReadAsStringAsync().Result;

        // Also tried this per mybirthname's suggestion.
        // But content ends up equaling 0 after this runs.
        var content = Request.Content.ReadAsStreamAsync().Result.Seek(0, System.IO.SeekOrigin.Begin);
    }
}

here is my controller to show how it's being called.

[HttpPost]
public ActionResult ClientJsonPoster(MyComplexObject myObject)
{
    this.ResponseInfo = new ResponseInfoModel();
    PostToAPI(myObject, "http://localhost:60146", "api/values").Wait();
    return View(this.ResponseInfo);
}

And this is the posting method.

private async Task PostToAPI(object myObject, string endpointUri, string endpointDirectory)
{
    string myObjectAsJSON = System.Web.Helpers.Json.Encode(myObject);
    StringContent stringContent = new StringContent(myObjectAsJSON, Encoding.UTF8, "application/json");
    using (HttpClient httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri(endpointUri);
        using (HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(endpointDirectory, stringContent).ConfigureAwait(false))
        {
            // Do something
        }
    }
}

I suspect something is wrong with the signature of the Post method inside the ApiController. But don't know how that should be changed. Thanks for your help.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
Ken Palmer
  • 2,355
  • 5
  • 37
  • 57
  • 1
    Possible duplicate of [Cannot read Request.Content in ASP.NET WebApi controller](http://stackoverflow.com/questions/10127803/cannot-read-request-content-in-asp-net-webapi-controller). Check the answer with 7 upvotes it explain why really good ! – mybirthname Nov 03 '16 at 17:43
  • 1
    Show how it is being called. looks like you are mixing async and sync calls which usually leads to deadlocks. The clue is the `.Wait()` in your exameple. – Nkosi Nov 03 '16 at 17:49
  • Thanks for the suggestions. I tried resetting the content stream position, and that returned a long with a value of 0. You can see how I applied that in the Post() method. Also, if the .Wait() is wrong, how does that need to be adjusted to avoid deadlocking? Thanks. – Ken Palmer Nov 03 '16 at 18:32

1 Answers1

15

You are mixing async and sync calls which will lead to deadlocks.

Update controller to

[HttpPost]
public async Task<ActionResult> ClientJsonPoster(MyComplexObject myObject) {
    this.ResponseInfo = new ResponseInfoModel();
    await PostToAPI(myObject, "http://localhost:60146", "api/values");
    return View(this.ResponseInfo);
}

Also [FromBody] is used to force Web API to read a simple type from the request body.

Update Api

public class ValuesController : ApiController {
    // POST api/values
    [HttpPost]
    public async Task Post() {
        var requestContent = Request.Content;
        var jsonContent = await requestContent.ReadAsStringAsync();

    }
}
Nkosi
  • 235,767
  • 35
  • 427
  • 472