ASP.NET Web Api - the framework is not converting JSON to object when using Chunked Transfer Encoding
Asked Answered
R

1

8

I have an http client in Android sending HTTP PUT requests to a REST api implemented with C# and ASP.NET WebApi framework.

The framework should be able to magically convert (deserialize) the JSON into a model class (plain object) as long as the JSON fields match the properties in the C# class.

The problem comes when the http requests come with Chunked Transfer Encoding that makes the Content-Length = 0 (as per http://en.wikipedia.org/wiki/Chunked_transfer_encoding) and the framework is not able to map the JSON that's within the Http request message so the parameter is null.

See this simple example:

    [HttpPut]
    public HttpStatusCode SendData(int id, int count, [FromBody]MyData records, HttpRequestMessage requestMessage)
    {
        var content = requestMessage.Content;
        string jsonContent = content.ReadAsStringAsync().Result; //this gets proper JSON
        return HttpStatusCode.OK;
    }

The problem is that records is null when the client sends the http request chunked.

As I understand, the Chunked Transfer encoding is simply a transfer property that the http client or server should not have to worry about at the application layer (transport layer's business). But it seems the framework doesn't manage it as I'd like.

I could manually retrieve the JSON from the HttpRequestMessage and de-serialize it into a MyData object, but I wouldn't be able to take advantage of the ASP.NET framework's magic. And you know the rule: the more code you add the more bugs you are likely to introduce.

Is there any way to handle Http Put requests with JSON that come as chunked transfer encoded in ASP.NET Web Api 2?

EDIT: This is the model class for this example that the framework should instantiate when de-serializing the JSON

public class MyData
{
    public string NamePerson {get; set;}
    public int Age {get; set;}
    public string Color {get; set;}
}
Resentment answered 30/9, 2014 at 2:32 Comment(5)
Did you ever find a solution to this problem? I'm running into the same thing and haven't been able to find a solution besides downgrading to the previous version of the Web API.Iona
No, I've never found a solution for this.Resentment
Checking in again! Did you ever solve this? I'm seeing something similar.Tang
I didn't resolve it with this approach no..Resentment
Crazy. I must have changed something in my JSON configurations in my sending routines, because all my POSTs and PUTs stopped working at once, with the same symptoms. On arrival at my Controller, the HttpRequest was chunked, with a Content-Length of 0. But if I do ReadAsStringAsync(), all my JSON is there. AND...if I call the same controller method from PostOffice, it is NOT chunked, and the object parameter is null. What workaround did you settle on?Tang
P
7

I recently stumbled upon the the same issue, and managed to create a workaround for it. I took the original JsonMediaTypeFormatter class, subclassed it and updated the implementation of the ReadFromStreamAsync/ReadFromStream-method.

https://gist.github.com/cobysy/578302d0f4f5b895f459

Hope this helps.

Photophobia answered 3/9, 2015 at 16:48 Comment(3)
I know this is a bit old, but it seems your simplified version doesn't seem like it would work. All it would do is ensure the ContentLength header has a null value and then call the base method, which would result in the same behavior. Am I missing something?Boggle
Magically that's all it takes apparently. I've simplified @Photophobia 's code further here: gist.github.com/jayoungers/0b39b66c49bf974ba73d83943c4b218bForgat
So is the "right" fix to make sure the caller's are adhering to the spec? w3.org/Protocols/rfc2616/rfc2616-sec4.html HttpClients in .NET Core are causing this for us.Thumbstall

© 2022 - 2024 — McMap. All rights reserved.