We have a public API call in which we would like to take the raw content of the Request body and store in a log record in our database. The basic use of our code is as follows:
public HttpResponseMessage PutObjects([FromBody] List<ObjectDTO> objectsDto)
{
string bodyText = "";
//HttpContext.Current.Request.GetBufferedInputStream().Close();
using (var bodyStream = new StreamReader(HttpContext.Current.Request.InputStream))
{
bodyStream.BaseStream.Seek(0, SeekOrigin.Begin);
bodyText = bodyStream.ReadToEnd();
}
// ... Rest of logic proceeds
Using this solution works when the Body being passed across is of valid JSON to deserialize into the objectsDto
. However, when the JSON is malformed and can't be loaded into the objectsDto
parameter, the following error is thrown:
System.InvalidOperationException: 'Either BinaryRead, Form, Files, or InputStream was accessed before the internal storage was filled by the caller of HttpRequest.GetBufferedInputStream.'
I had a thought that if it was because the parameter wasn't filled due to (I'm assuming) an automatic call to GetBufferedInputStream
, that if I execute Close()
on this, it would reset the Stream and I would be able to proceed. The line of code I've used to do this is the commented out line seen in the code example.
This appears to have worked until closer inspection. The ReadToEnd()
result put in bodyText
appears to have cut off in the middle rather than reading to the end. One interesting detail I noticed is that it stops at a length of 1024. In other words, only the first 1024 characters are being returned from ReadToEnd()
. Of course, 1024 is a very suspicious number to me but my lack of knowledge with StreamReaders has me at a stopping point.
The main question now is: Why does the StreamReader in this case only return the first 1024 characters when calling ReadToEnd()
? Again, this appears to only occur if the JSON sent over is not formatted correctly.
Also, if anyone thinks of an easier way to grab the raw Body of the Request, I'm open to trying that as well. Thanks in advance.
EDIT: I attempted to use HttpContext.Current.Request.GetBufferlessInputStream(disableMaxRequestLength:true)
to see what the outcome would be. The error received mentioned not being able to use GetBufferlessInputStream
after GetBufferedInputStream
was already called.