Hector
Hector

Reputation: 1220

Receiving null to Post method when request content is over a certain size

First of all the request content size triggering this is 632 bytes so I don't believe its related to maxRequestLength parameter. I've tried increasing this and it hasn't helped. The request content is available via ReadAsStreamAsync so its not IIS blocking it.

I have a controller with a Post method which takes a class object. This always works from my development machine and most of the time it works on our QA server under IIS. It looks like -

[RoutePrefix("api/message")]
public class MessageController : ApiController
{
    [Route("send")
    public async Task<SendMessageResponse> PostSend([FromBody] SendMessageRequest request)
    {
        ...

SendMessageRequest looks like -

public class SendMessageRequest
{
    public string[] sendTo { get; set; }
    public string subject { get; set; }
    public string body { get; set; }
}

However when the request content is over 632 characters PostSend receives null as the request parameter. It is possible to manually pull the request stream and serialise using Newtonsoft.JSON.

Any ideas?

Thanks, Hector

*Example request content

{
    "subject" : "Test Message",
    "sendTo" : [ "[email protected]" ],
    "body" : "...Long String..."
}

Changing subject or body to bring the request content over 632 bytes will cause null to be passed to PostSend

Upvotes: 0

Views: 1252

Answers (1)

Hector
Hector

Reputation: 1220

So it turns out in production and QA we have a node based server which proxies requests. This passes the request on in Chunked form.

There appears to be a bug in WebApi v2.1 with chunked request handling as per https://forums.asp.net/t/1978292.aspx.

The solution is to add something into the pipeline before the deserializer which sets request.Content.Headers.ContentLength = null.

i.e.

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
    if (request.Headers.TransferEncodingChunked.HasValue 
        && request.Headers.TransferEncodingChunked.Value)
    {
        request.Content.Headers.ContentLength = null;
    }
    return base.SendAsync(request, cancellationToken);
}

Upvotes: 1

Related Questions