These methods were and are available on the .NET framework using the HttpClientExtensions
class. They make life easy for developers trying to make HTTP calls from their code as they don't have to manually deal with creating objects from the responses or parsing their typed payload into StringContent
or what not.
The HttpClientExtensions class is not actually in the .NET Framework. It is a class available as part of a NuGet package that contains various HttpClient extension classes/methods.
Can you please point to the location of this NuGet package that you are referring to?
If you want to use this class against .NET Core things, you might simply be able to just reference that package. Or have the package authors update the package to include .NET Core / NETStandard20 references.
Isn't that method part of Microsoft.AspNet.WebApi.Client? In that case, you can test out version 5.2.4-preview1, which was released a few days ago with support for .NET Standard 2.0 :smile:
@khellang I don't think it is part of that package. It is part of System.Net.Http which doesn't support Net Core as far as I know
@bolorundurowb No, it's not. It's a bit complicated, but the extensions are in the System.Net.Http
namespace, but in the System.Net.Http.Formatting
DLL, shipped in the Microsoft.AspNet.WebApi.Client
NuGet package.
I just tested this successfully:
using System.Net.Http;
using System.Threading.Tasks;
public static class Program
{
public static async Task Main(string[] args)
{
using (var client = new HttpClient())
{
var person = new Person
{
FirstName = "Kristian",
LastName = "Hellang",
};
await client.PostAsJsonAsync("http://localhost:8080/", person);
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
Using the following csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<LangVersion>latest</LangVersion>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.4-preview1" />
</ItemGroup>
</Project>
Alright @khellang thanks for the correction
I doubt that these extension methods would ever be added directly to HttpClient
as that would require a dependency on some JSON serialization library. I think using Microsoft.AspNet.WebApi.Client
with the provided extension methods is a nice compromise 馃槃
@khellang Asp.Net Core already uses Newtonsoft.Json library for its JSON serialization if I am not wrong (I remember reading that in some of the v1.0 MSDN blog posts). So adding those methods directly shouldn't require adding a new dependency.
Edit: Just checked the MVC source, Newtonsoft.Json is used for handling JSON
Asp.Net Core already uses Newtonsoft.Json library for its JSON serialization
Yes, but that doesn't mean you can just add JSON methods to HttpClient
. HttpClient
has nothing to do with ASP.NET Core. It's a standalone HTTP client that can be used anywhere.
I understand that, but my concern is that as a user, I have to bring in all of Microsoft.AspNet.WebApi.Client just to have access to the HttpClient generic Json extension methods.
I'd be more worried by all the others that suddenly have to bring in Newtonsoft.Json
when using HttpClient
. There's definitely a lot of users not interested in that 馃槈
That's the beauty of layering; if you're not willing to pay the cost, you get the bare-bones experience. The more functionality you need, the more you layer on top. It's a convenience feature; if you're not willing to pay the cost of pulling in a library with some extension methods, you most likely don't need it enough 馃槃
Hey guys - I want to ask this question somewhere but I think it is pertinent here.
I am trying to use this in a .Net Standard library and it is kinda working... Except i am getting odd serialisation output that is screwing up binding.
This is what I boiled it down to (to rule out complexities around serialisation)
```c#
HttpClient _client = new HttpClient((HttpMessageHandler)new HttpClientHandler()
{UseDefaultCredentials = true })
{
BaseAddress = new Uri(@"http://verodev01/OliveWebApi/")
};
_client.DefaultRequestHeaders.Accept.Clear();
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
```
when I whack fiddler in I see the following
"
6
"test"
0
"
I've tested larger types and the first number seems to correlate to the payload size second number is always 0. When using . net you don't get the leading and trailing integers and it is this that is screwing up binding!
Any help??
@jonathh21 I think you want to read up on chunked encoding:
Data is sent in a series of chunks. The Content-Length header is omitted in this case and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format, followed by '\r\n' and then the chunk itself, followed by another '\r\n'. The terminating chunk is a regular chunk, with the exception that its length is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of entity header fields.
I don't think that should affect any deserialization though.
That looks like the kiddy! It is preventing binding in my case.. maybe as the server isn't expecting it??
Anyway... Thank you so very much!!
That looks like the kiddy! It is preventing binding in my case.. maybe as the server isn't expecting it??
Anyway... Thank you so very much!!
Anyone know how to send via none - chunked? my identical 4.6.1 code doesn't go down this route and like i say it is screwing up the binding on the ASP.Net WebAPI side.
Facing the same issue as @jonathh21. Just migrated to core from 461 and PostAsJsonAsync is not picking up the content length and being sent as chunked which is causing a 500 error on the api it is calling. The json string itself is tiny. I have had to switch to using string content to get it working.
@bronumski, @jonathh21 I had a similar issue updating from 4.6.1 to 4.6.2. It seems the problem is related to the System.Net.Http library. The 4.0.0.0 version I have in the GAC seems to work just fine, but in updating components nuget pulled in 4.3.2 of System.Net.Http which started sending requests using chunk encoding. I just updated to 4.3.3 of System.Net.Http and it seems to be back to not chunking requests. I was also able to use assembly binding redirection to downgrade to the 4.0.0.0 version, but that did not seem like a good long term solution.
@shaneholder System.Net.Http package reships same code which is in .NET Framework starting with System.Net.Http 4.3.1 (assembly version 4.1.1.0). And we didn't touch it since then. 4.3.1-4.3.3 nuget versions should behave exactly the same (I think that even the binaries are exactly the same).
@karelz thanks for the quick reply, especially on the weekend. To be clear, I'm not using .Net Core. My issue is in a .Net Framework console app. I just caught this thread when searching for my problem. Also, I was incorrect about the version that this started in, its 4.3.0 installing 4.3.1 with Nuget works just fine.
@shaneholder yep, understood that it is on .NET Framework - as I said, it is something we fixed (i.e. rolled back) in dotnet/runtime#18280.
The code for out-of-band packages lives in CoreFX repo.
@karelz thanks for the pointer to the issue, sounds like I got lucky by waiting to upgrade until a fix was ready.
When targeting netcoreapp2.1 and using Microsoft.AspNet.WebApi.Client 5.2.6, PostAsJsonAsync is setting Content-Length: 0
. In the following code, TestClient1 fails, but TestClient2 succeeds; the endpoint being called is a .NET Framework 4.6.2 WebApi. If this isn't the right place to raise this issue, please point me to the right repo.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="xunit" Version="2.3.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
</ItemGroup>
</Project>```
```c#
[Fact]
public async void TestClient1()
{
var client = new HttpClient();
var response = await client.PostAsJsonAsync("http://localhost:62847/api/FundStructures", new[] {43658, 43661});
response.EnsureSuccessStatusCode(); // Fails
}
[Fact]
public async void TestClient2()
{
var client = new HttpClient();
var message = new HttpRequestMessage
{
RequestUri = new Uri("http://localhost:62847/api/FundStructures"),
Method = HttpMethod.Post,
Content = new StringContent(JsonConvert.SerializeObject(new[] {43658, 43661}), null, "application/json")
};
var response = await client.SendAsync(message);
response.EnsureSuccessStatusCode(); // Succeeds
}
@kayjtea I encountered the same issue, and rolled back to this syntax to make it work:
await Client.PostAsync("api/Connect", new StringContent(JsonConvert.SerializeObject(webUser), Encoding.UTF8, "application/json"))
You can add your own extension methods in your application or class library I did it for PostAsJsonAsync
```c#
///
/// Extentions for Http Client
///
public static class HttpClientExtensions
{
public static Task
this HttpClient httpClient, string url, T data)
{
var dataAsString = JsonConvert.SerializeObject(data);
var content = new StringContent(dataAsString);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return httpClient.PostAsync(url, content);
}
public static async Task<T> ReadAsJsonAsync<T>(this HttpContent content)
{
var dataAsString = await content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<T>(dataAsString);
}
}
```
This issue (or at least some comments) should be moved to https://github.com/aspnet/AspNetWebStack as it's about System.Net.Http.Formatting
.
I will hide the comments which are unrelated to this issue. Please file separate bug per suggestion above.
It is 2018, and i still write/copy-paste my api clients again and again? OMG! It is so obviously neede feature
When targeting netcoreapp2.1 and using Microsoft.AspNet.WebApi.Client 5.2.6, PostAsJsonAsync is setting
Content-Length: 0
. In the following code, TestClient1 fails, but TestClient2 succeeds; the endpoint being called is a .NET Framework 4.6.2 WebApi. If this isn't the right place to raise this issue, please point me to the right repo.<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> <IsPackable>false</IsPackable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.6" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> <PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> </ItemGroup> </Project>``` ```c# [Fact] public async void TestClient1() { var client = new HttpClient(); var response = await client.PostAsJsonAsync("http://localhost:62847/api/FundStructures", new[] {43658, 43661}); response.EnsureSuccessStatusCode(); // Fails } [Fact] public async void TestClient2() { var client = new HttpClient(); var message = new HttpRequestMessage { RequestUri = new Uri("http://localhost:62847/api/FundStructures"), Method = HttpMethod.Post, Content = new StringContent(JsonConvert.SerializeObject(new[] {43658, 43661}), null, "application/json") }; var response = await client.SendAsync(message); response.EnsureSuccessStatusCode(); // Succeeds }
Are there any solutions for this bug? The PostAsJsonAsync extension method is still setting Content-Length to 0 in .NET Core 2.1 with any versions of System.Net.Http and System.Net.Http.Formatting.
I've opened an issue, please reply: https://github.com/dotnet/corefx/issues/39627
Cant agree more on @doboczyakos , It's a critical bug !
That's not in corefx. It's tracked by https://github.com/aspnet/AspNetWebStack/issues/252.
Most helpful comment
When targeting netcoreapp2.1 and using Microsoft.AspNet.WebApi.Client 5.2.6, PostAsJsonAsync is setting
Content-Length: 0
. In the following code, TestClient1 fails, but TestClient2 succeeds; the endpoint being called is a .NET Framework 4.6.2 WebApi. If this isn't the right place to raise this issue, please point me to the right repo.