Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HttpClient issue when calling older ASP.Net webAPIs from net core #232

Closed
Tratcher opened this issue Feb 11, 2019 · 14 comments
Closed

HttpClient issue when calling older ASP.Net webAPIs from net core #232

Tratcher opened this issue Feb 11, 2019 · 14 comments

Comments

@Tratcher
Copy link
Member

From @chrizy on Friday, 08 February 2019 19:13:17

I’m having an issue when calling an ASP.Net 5.2.3 WebAPI (framework 4.7.2) when using net core as the client. The issue does not happen If compile the test console app using framework 4.7.2. The issue is that the message body does not get serialized in the API controller and will always by null.

network traces below for the same code running against each runtime. It looks like some extra bytes is being added in net core.
Thanks

.net core 2.2 (fails)

POST http://croy201703/CrmServer/api/v1/login HTTP/1.1
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Host: croy201703

48
{"username":"Admin","password":"Admin","installID":"test","force":false}
0

.net framework 4.7.2 (works OK)

POST http://croy201703/CrmServer/api/v1/login HTTP/1.1
Content-Type: application/json; charset=utf-8
Host: croy201703
Content-Length: 72

{"username":"Admin","password":"Admin","installID":"test","force":false}

Application calling code used for both tests

            var baseURL = "http://croy201703/CrmServer/";
            var username = "Admin";
            var password = "Admin";

            // Login
            var httpClient = new HttpClient()
            {
                BaseAddress = new Uri(baseURL)
            };
            var loginRequest = new { Username = username, Password = password, InstallID = "test", Force = false };
            var loginResponse = await httpClient.PostAsJsonAsync("api/v1/login", loginRequest);

also tried with not passing as an anonymous type

Copied from original issue: dotnet/corefx#35181

@Tratcher
Copy link
Member Author

From @geoffkizer on Sunday, 10 February 2019 22:43:43

.NET Core is sending the body as chunked, whereas framework is sending using Content-Length. Both are legal. I don't see a problem here.

@Tratcher
Copy link
Member Author

From @davidsh on Sunday, 10 February 2019 23:57:19

The issue is that the message body does not get serialized in the API controller and will always by null.

Perhaps the bug is in your ASP.NET layer. Maybe it assumes 'Content-Length' encoding only for request body? And if it gets 'Transfer-Encoding: chunked' then it might fail with serializing to null?

@Tratcher
Copy link
Member Author

From @davidsh on Monday, 11 February 2019 00:00:16

Also, this code from your client example:

var loginResponse = await httpClient.PostAsJsonAsync("api/v1/login", loginRequest);

where is "loginRequest" defined? I assume it is an HttpContent derived class?

As @geoffkizer mentioned:

.NET Core is sending the body as chunked, whereas framework is sending using Content-Length.

there is a difference in how .NET Framework and .NET Core will transmit a request body in cases where it is ambiguous. If neither 'Content-Length' nor 'Transfer-Encoding: chunked' appear for the request body, each of the frameworks makes a choice. However, you can ensure that a specific choice is made for you by specifically setting either 'Content-Length' or 'Transfer-Encoding: chunked' semantics yourself.

@Tratcher
Copy link
Member Author

From @chrizy on Monday, 11 February 2019 09:56:55

Thanks for the feedback, I suspect the chunked is the issue. The problem as I see it is by default no net core application can talk to older asp net 5.2.3 as asp.net doesn't support or understand the data sent, and does not give an clear indication as to the problem. It seems like an odd default position to be in.
Also changing each http request (talking about over 70 apis here) in my net core application to disable chunked is not easy, Unless there is some global setting which can control this? or is there a way to get asp.net to support it?

@Tratcher
Copy link
Member Author

From @davidsh on Monday, 11 February 2019 16:01:27

The root cause here still hasn't been determined but based on your scenario the problem is in ASP.NET and not the client-side HTTP stack (HttpClient).

Unless there is some global setting which can control this? or is there a way to get asp.net to support it?

I suggest you follow up with the ASP.NET core team on this. @Tratcher Can you comment on this?

@Tratcher
Copy link
Member Author

From @Tratcher on Monday, 11 February 2019 16:23:14

@dougbu any thoughts on why MVC 5.2.3 would care about the difference between chunked and content-length? It shouldn't.

@davidsh this can be moved to https://github.com/aspnet/AspNetWebStack.

@Tratcher
Copy link
Member Author

From @davidsh on Monday, 11 February 2019 16:26:12

@davidsh this can be moved to https://github.com/aspnet/AspNetWebStack.

@Tratcher I know there is a tool that does that. But I don't have it installed. Can you move this please and also let me know where the tool is?

@dougbu
Copy link
Member

dougbu commented Feb 11, 2019

I suspect this is a duplicate of #197. @chrizy could you please check if the problem goes away after upgrading the web site to MVC 5.2.7?

@chrizy
Copy link

chrizy commented Feb 19, 2019

Hi,
Yes issue fixed with 5.2.7. Thanks

@dougbu
Copy link
Member

dougbu commented Feb 19, 2019

Thank you for your feedback. We're closing this issue as you have confirmed it is fixed in the latest release.

@chkeita
Copy link

chkeita commented Mar 22, 2019

I am getting the exact same issue when referencing Microsoft.AspNet.WebApi.Client 5.2.7

This code

var httpClient = new HttpClient();
var loginRequest = new { Username = "test", Password = "test", InstallID = "test", Force = false };
httpClient.PostAsJsonAsync("http://postman-echo.com/post", loginRequest).Wait();

Generates this request when targetting .netcoreapp2.2

POST http://postman-echo.com/post HTTP/1.1
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Host: postman-echo.com

46
{"Username":"test","Password":"test","InstallID":"test","Force":false}
0

@Tratcher
Copy link
Member Author

@chkeita That's the expected output. Note the fix was on the server side to accept this format, did you update the server to 5.2.7?

@chkeita
Copy link

chkeita commented Mar 22, 2019

@Tratcher I am calling an external website that does not seem to support this format.
Is it possible to for HttpClient to use the old format?
I already tried settings DefaultRequestHeaders.TransferEncodingChunked to false without any success.

@Tratcher
Copy link
Member Author

Not while using PostAsJsonAsync. You'll have to generate the JSON text another way and then use StringContent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants