I have been meaning to post this for some time to help anybody else out there who has faced a similar problem.
I recently needed to receive a Post callback from a web service that would pass a large volume of JSON in the body of the request to my API back end. Simply using the [FromBody] decorator for a parameter on the action definition in the controller resulted in the sending service creating an error trying to reach the Controller. The only way to get round this was to interpret the Body in raw format but this too causes a problem because the Body of a request in .NET core can only be read once, which makes it impossible to catch it and then stream it into a file or handle the data in some other way.
I went down many rabbit holes on this, creating all sorts of Middleware etc but in the end the solution was as simple as this:
[AllowAnonymous]
[HttpPost]
[Route("[action]")]
public async Task<IActionResult> SpeechToTextCallBack()
{
Request.EnableRewind();
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
using (MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(reader.ReadToEnd())))
{
await this._utilsService.SaveBlobAsync(stream, UtilsService.BlobType.WatsonTranscription, "mp3test.json");
}
}
return Ok();
}
The call back API above takes the raw body and stores it in Azure as a blob using a shared method called SaveBlobAsync. The method is irrelevant in this post. The most important bit in the code above is the line:
Request.EnableRewind();
Bingo! That’s it. No complex Middleware! This simply makes the Body accesible for you to do what you wish with it. In my example I needed to take what could be a very large lump of JSON and set it up in a Memory Stream so that my shared method could save it as a Blob in Azure Storage.