Reputation: 31
I'm really struggling with what should be a pretty simple issue. We are accepting HTTP POSTs to our API. Everything works great when we try to access the Body until today.
We are trying to receive a POST that has the following value in the HTTP Header: content-type: application/json
Something about that value is causing the byteArray to contain nothing but NULL values. The array size remains correct though. Just by changing the content-type to anything else fixes the problem (application/jso, application\json, etc) so something has be triggered off that value. We can accept other JSON just fine without that header value.
We were using MVC3 and I've tried upgrading to MVC4 and that did not seem to help. We also build our own controllers but we don't do anything with the content-type HTTP Header. I'd appreciate any ideas on where to look to see why this is happening.
HttpContextBase httpContext = HttpContext;
if (!httpContext.IsPostNotification)
{
throw new InvalidOperationException("Only POST messages allowed on this resource");
}
Stream httpBodyStream = httpContext.Request.InputStream;
if (httpBodyStream.Length > int.MaxValue)
{
throw new ArgumentException("HTTP InputStream too large.");
}
int streamLength = Convert.ToInt32(httpBodyStream.Length);
byte[] byteArray = new byte[streamLength];
const int startAt = 0;
httpBodyStream.Read(byteArray, startAt, streamLength);
httpBodyStream.Seek(0, SeekOrigin.Begin);
switch (httpContext.Request.ContentEncoding.BodyName)
{
case "utf-8":
_postData = Encoding.UTF8.GetString(byteArray);
Upvotes: 2
Views: 2341
Reputation: 31
The fault in the code seemed to be the very first line. The code was assigning the HttpContext to a local variable called httpContext. For reasons unbeknownst to me, by removing this line and using the HttpContext directly, the code worked.
if (!HttpContext.IsPostNotification)
throw new InvalidOperationException("Only POST messages allowed on this resource");
HttpContext.Request.InputStream.Position = 0;
if (HttpContext.Request.InputStream.Length > int.MaxValue)
throw new ArgumentException("HTTP InputStream too large.");
int streamLength = Convert.ToInt32(HttpContext.Request.InputStream.Length);
byte[] byteArray = new byte[streamLength];
const int startAt = 0;
HttpContext.Request.InputStream.Read(byteArray, startAt, streamLength);
HttpContext.Request.InputStream.Seek(0, SeekOrigin.Begin);
switch (HttpContext.Request.ContentEncoding.BodyName)
{
case "utf-8":
_postData = Encoding.UTF8.GetString(byteArray);
Upvotes: 1
Reputation: 3979
Can you use the original HttpContext
instead of a reference to the stream.
Or potentially get the context of the application instance, from this stack overflow answer.
// httpContextBase is of type HttpContextBase
HttpContext context = httpContextBase.ApplicationInstance.Context;
Upvotes: 2