I have a simple GET request that returns .txt file's content. You can try it out using a browser or fiddler: http://134.17.24.10:8054/Documents/13f37b0c-4b04-42e1-a86b-3658a67770da/1.txt
The encoding of this file is cp-1251. When I try to get it, I see smth like this:
response text view
How can I modify HttpRequest in C# to get the text in the encoding that I want? Or just return only bytes in order to convert them manually. Is it possible with HttpClient?
Another attachment:
If you can't change the charset sent by the server, yes, you can still just request the bytes and then choose which encoding to apply:
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetByteArrayAsync(RequestUrl);
var responseString = Encoding.GetEncoding("windows-1251").GetString(response, 0, response.Length - 1);
Console.WriteLine(responseString);
}
References:
How to change the encoding of the HttpClient response
Encoding.GetEncoding can't work in UWP app
The .NET Framework Class Library provides one static property, CodePagesEncodingProvider.Instance, that returns an EncodingProvider object that makes the full set of encodings available on the desktop .NET Framework Class Library available to .NET Core applications.
https://learn.microsoft.com/en-us/dotnet/api/system.text.encodingprovider?redirectedfrom=MSDN&view=netcore-3.1
Examples exist to read data from an IAsyncEnumerator to the UI in a Blazor app using an internal service.
Examples also exist on how to send an IAsyncEnumerator as an output from a Web API Controller action.
I haven't seen any examples yet how to read an IAsyncEnumerator stream from an API using an HttpClient within a client like Blazor or Xamarin. Everything I've tried so far, only returns the HttpResponseMessage on the client after the async/await foreach loop on the API is done.
HttpResponseMessage response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
What should the content type be (Produces attribute) on the HttpGet action? What should the Accept value be on the request header from the HttpClient?
[HttpGet]
[Produces("application/json")]
public async IAsyncEnumerable<Data> Get(CancellationToken cancellationToken)
{
var dbSet = _dbContext.TableName.AsNoTracking().AsAsyncEnumerable().WithCancellation(cancellationToken).ConfigureAwait(false);
await foreach (var i in dbSet.ConfigureAwait(false))
{
var item = new Data
{
Id = i.Id,
Name = i.Name
};
yield return item;
}
}
You'd better not do it with raw http 1.1 request-response model, which is not designed for this, and streaming objects are different from downloading files.
With websocket or http2.0 that support multiplexing, you can serialize each elements produced by the IAsyncEnumerable and deserialize them in the client. But still this is manually controlled and not worth.
You could use gRPC which is officially supported by ASP.NET Core and supports object streaming. It also supports many more languages and has strongly typed interface definition in comparison with SignalR which supports JavaScript/.NET/Java only and .
I'm trying to do a HTTP Delete request from Unity and bump into the idea of use the HttpRequest class included in the System.Web namespace of .Net
How can I achieve this, I supose that some sort of import of that namespace must be done, but how?
Hope some one can give me some orientation
HttpClient is only available in 4.5 NET and above and Unity does not use that version. Unity uses about 3.5 .NET version.
If you are using Unity 5.3, UnityWebRequest.Delete can be used to make a Delete request. It can be found in the Experimental.Networking namespace. If you are using Unity 5.4 and above,UnityWebRequestcan be found in the UnityEngine.Networking; namespace.
Full working example:
IEnumerator makeRequest(string url)
{
UnityWebRequest delReq = UnityWebRequest.Delete(url);
yield return delReq.Send();
if (delReq.isError)
{
Debug.Log("Error: " + delReq.error);
}
else
{
Debug.Log("Received " + delReq.downloadHandler.text);
}
}
Usage:
StartCoroutine(makeRequest("http://www.example.com/whatever"));
Make sure to include using UnityEngine.Networking. You can find complete examples with it here.
EDIT (UPDATE)
Unity now supports .NET 4.5 so you can now use HttpClient if you wish. See this post for how to enable it.
After enabling it,
Go to <UnityInstallationDirectory>\Editor\Data\MonoBleedingEdge\lib\mono\4.5 or for example, C:\Program Files\Unity\Editor\Data\MonoBleedingEdge\lib\mono\4.5 on my computer.
Once in this directory, copy System.Net.Http.dll to your <ProjectName>\Assets directory and you should be able to use HttpClient after importing the System.Net.Http namespace. If there are some other error about missing dependencies, you can get the dlls from this path too and copy them to your <ProjectName>\Assets directory too.
In the current versions of Unity httpClient is supported out of the box even on .NET Standard 2.0 targets. Here is sample code on how I use it to access a REST api.
public static async Task<Resource> GetResource()
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri(URL);
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var response = await httpClient.GetAsync("api/session");
if (response.StatusCode != HttpStatusCode.OK)
return null;
var resourceJson = await response.Content.ReadAsStringAsync();
return JsonUtility.FromJson<Resource>(resourceJson);
}
}
Copy of my answer on https://forum.unity.com/threads/httpclient-on-net-standard-2-0.608800/
I have no problem deserializing an xml into my class while using the following code. I was wondering if it was possible to use the same code on a local file, as our source files are saved locally for archival purposes and are occasionally reprocessed.
This works for remote xml but not for local xml:
RestRequest request = new RestRequest();
var client = new RestClient();
//doesnt work
client.BaseUrl = directory;
request.Resource = file;
//works
client.BaseUrl = baseURL;
request.Resource = url2;
IRestResponse<T> response = client.Execute<T>(request);
return response.Data;
Is there a way to use RestSharp from a local file? I was going to try to use the same function regardless of whether the xml is local or remote and just pass it the location of the xml to read.
This is in fact possible using built in JsonDeserializer class as below. I have used this method to stub API response for testing.
// Read the file
string fileContents = string.Empty;
using (System.IO.StreamReader reader = new System.IO.StreamReader(#"C:\Path_to_File.txt"))
{
fileContents = rd.ReadToEnd();
}
// Deserialize
RestResponse<T> restResponse = new RestResponse<T>();
restResponse.Content = fileContents;
RestSharp.Deserializers.JsonDeserializer deserializer = new RestSharp.Deserializers.JsonDeserializer();
T deserializedObject = deserializer.Deserialize<T>(restResponse);
This is not possible with standard functionality. For example "file://" URLs do not work with RestSharp.
I would recommend using RestSharp do get the returned data from a Uri and having another function to deserialize this data into an object.
You can use the same funcion then to deserialize from file data.
RestSharp is a library to do REST calls, not to deserialize from arbitrary sources. Even if there is a possibility to make RestSharp believe it is talking to a website instead of a file, it would be a hack.
If you need it you could still use the XmlDeserializer from RestSharp. It expects a IRestResponse object, but it only uses the Content property from it, so it should be easy to create. It still feels like a hack though and there are more than enough other XmlSerializers out there that will do a great job
I am trying to call a web API from my web application. I am using .Net 4.5 and while writing the code I am getting the error HttpClient does not contain a definition PostAsJsonAsync method.
Below is the code:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:51093/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
var user = new Users();
user.AgentCode = 100;
user.Remarks = "Test";
user.CollectionDate = System.DateTime.Today;
user.RemittanceDate = System.DateTime.Today;
user.TotalAmount = 1000;
user.OrgBranchID = 101;
var response = client.PostAsJsonAsync("api/AgentCollection", user).Result;
and I am getting the error message:
Error: 'System.Net.Http.HttpClient' does not contain a definition for
'PostAsJsonAsync' and No extension method 'PostAsJsonAsync' accepting a first argument of
type 'System.Net.Http.HttpClient' could be found (are you missing
a using directive or an assembly reference?)
Please have a look and advice me.
Yes, you need to add a reference to
System.Net.Http.Formatting.dll
This can be found in the extensions assemblies area.
A good way of achieving this is by adding the NuGet package Microsoft.AspNet.WebApi.Client to your project.
PostAsJsonAsync is no longer in the System.Net.Http.dll (.NET 4.5.2). You can add a reference to System.Net.Http.Formatting.dll, but this actually belongs to an older version. I ran into problems with this on our TeamCity build server, these two wouldn't cooperate together.
Alternatively, you can replace PostAsJsonAsyncwith a PostAsync call, which is just part of new dll.
Replace
var response = client.PostAsJsonAsync("api/AgentCollection", user).Result;
With:
var response = client.PostAsync("api/AgentCollection", new StringContent(
new JavaScriptSerializer().Serialize(user), Encoding.UTF8, "application/json")).Result;
Note that JavaScriptSerializer is in the namespace: System.Web.Script.Serialization.
You will have to add an assembly reference in your csproj: System.Web.Extensions.dll
See https://code.msdn.microsoft.com/windowsapps/How-to-use-HttpClient-to-b9289836
The missing reference is the System.Net.Http.Formatting.dll. But the better solution is to add the NuGet package Microsoft.AspNet.WebApi.Client to ensure the version of the formatting dll worked with the .NET framework version of System.Net.Http in my project.
As already debatted, this method isn't available anymore since .NET 4.5.2. To expand on Jeroen K's answer you can make an extension method:
public static async Task<HttpResponseMessage> PostAsJsonAsync<TModel>(this HttpClient client, string requestUrl, TModel model)
{
var serializer = new JavaScriptSerializer();
var json = serializer.Serialize(model);
var stringContent = new StringContent(json, Encoding.UTF8, "application/json");
return await client.PostAsync(requestUrl, stringContent);
}
Now you are able to call client.PostAsJsonAsync("api/AgentCollection", user).
I had this issue too on a project I'd just checked out from source control.
The symptom was the error described above and a yellow warning triangle on a reference to System.Net.Http.Formatting
To fix this, I removed the broken reference and then used NuGet to install the latest version of Microsoft.AspNet.WebApi.Client.
I know this reply is too late, I had the same issue and i was adding the System.Net.Http.Formatting.Extension Nuget, after checking here and there I found that the Nuget is added but the System.Net.Http.Formatting.dll was not added to the references, I just reinstalled the Nuget
Try to install in your project the NuGet Package: Microsoft.AspNet.WebApi.Client:
Install-Package Microsoft.AspNet.WebApi.Client
Ok, it is apocalyptical 2020 now, and you can find these methods in NuGet package System.Net.Http.Json. But beware that it uses System.Text.Json internally.
And if you really need to find out which API resides where, just use https://apisof.net/
If you are already using Newtonsoft.Json try this:
// Alternative using WebApi.Client 5.2.7
////var response = await Client.PutAsJsonAsync(
//// "api/AgentCollection", user
//// requestListDto)
var response = await Client.PostAsync("api/AgentCollection", new StringContent(
JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json"));
Performance are better than JavaScriptSerializer. Take a look here https://www.newtonsoft.com/json/help/html/Introduction.htm
Instead of writing this amount of code to make a simple call, you could use one of the wrappers available over the internet.
I've written one called WebApiClient, available at NuGet... check it out!
https://www.nuget.org/packages/WebApiRestService.WebApiClient/
If you're playing around in Blazor and get the error, you need to add the package Microsoft.AspNetCore.Blazor.HttpClient.
Just expanding Jeroen's answer with the tips in comments:
var content = new StringContent(
JsonConvert.SerializeObject(user),
Encoding.UTF8,
MediaTypeNames.Application.Json);
var response = await client.PostAsync("api/AgentCollection", content);
For me I found the solution after a lot of try which is replacing
HttpClient
with
System.Net.Http.HttpClient
Based on the answers here talking about using Newtonsoft.Json, I created a helper class for this:
public class JsonContent : StringContent
{
public JsonContent(object model)
: base(JsonConvert.SerializeObject(model), Encoding.UTF8, "application/json")
{
}
}
Example usage:
using (var content = new JsonContent(user))
{
var response = client.PostAsync("api/AgentCollection", content).Result;
}
If you are using Blazor components and getting this error that means your component is not able to find the http client.
use this line on top on your blazor component.
#inject HttpClient Http
Make sure you have this line in your Program or startup file
builder.Services.AddScoped(sp =>
new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });