How to Replace WebClient with HttpClient?
You can write the following code:
string url = 'some url';
// best practice to create one HttpClient per Application and inject it
HttpClient client = new HttpClient();
using (HttpResponseMessage response = client.GetAsync(url).Result)
{
using (HttpContent content = response.Content)
{
var json = content.ReadAsStringAsync().Result;
}
}
Update 1 :
if you want to replace the calling to Result
property with the await
Keyword, then this is possible, but you have to put this code in a method which marked as async
as following
public async Task AsyncMethod()
{
string url = 'some url';
// best practice to create one HttpClient per Application and inject it
HttpClient client = new HttpClient();
using (HttpResponseMessage response = await client.GetAsync(url))
{
using (HttpContent content = response.Content)
{
var json = await content.ReadAsStringAsync();
}
}
}
if you missed the async
keyword from the method, you could get a Compile-time error like the following
The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task<System.Threading.Tasks.Task>'.
Update 2 :
Responding to your original question about converting the 'WebClient' to 'WebRequest' this is the code that you could use, ... But Microsoft ( and me ) recommended you to use the first approach (by using the HttpClient).
string url = currentURL + "resources/" + ResourceID + "/accounts?AUTHTOKEN=" + pmtoken;
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.Method = "GET";
using (WebResponse response = httpWebRequest.GetResponse())
{
HttpWebResponse httpResponse = response as HttpWebResponse;
using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream()))
{
var json = reader.ReadToEnd();
}
}
if you use C# 8 and above, then you can write very elegant code
public async Task AsyncMethod()
{
string url = 'some url';
// best practice to create one HttpClient per Application and inject it
HttpClient client = new HttpClient();
using HttpResponseMessage response = await client.GetAsync(url);
using HttpContent content = response.Content;
var json = await content.ReadAsStringAsync();
} // dispose will be called here, when you exit of the method, be aware of that
Update 3
To know why is HttpClient
is more recommended than WebRequest
and WebClient
you can consult the following links.
Deciding between HttpClient and WebClient
http://www.diogonunes.com/blog/webclient-vs-httpclient-vs-httpwebrequest/
HttpClient vs HttpWebRequest
What difference is there between WebClient and HTTPWebRequest classes in .NET?
http://blogs.msdn.com/b/henrikn/archive/2012/02/11/httpclient-is-here.aspx
What difference is there between WebClient and HTTPWebRequest classes in .NET?
WebClient is a higher-level abstraction built on top of HttpWebRequest to simplify the most common tasks. For instance, if you want to get the content out of an HttpWebResponse, you have to read from the response stream:
var http = (HttpWebRequest)WebRequest.Create("http://example.com");
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
With WebClient, you just do DownloadString
:
var client = new WebClient();
var content = client.DownloadString("http://example.com");
Note: I left out the using
statements from both examples for brevity. You should definitely take care to dispose your web request objects properly.
In general, WebClient is good for quick and dirty simple requests and HttpWebRequest is good for when you need more control over the entire request.
Replacing WebClient with HttpClient
Well Is your method post or get??
Well anyway here is a better exmaple of how you could build POST and GET
private static readonly HttpClient client = new HttpClient();
// HttpGet
public static async Task<object> GetAsync(this string url, object parameter = null, Type castToType = null)
{
if (parameter is IDictionary)
{
if (parameter != null)
{
url += "?" + string.Join("&", (parameter as Dictionary<string, object>).Select(x => $"{x.Key}={x.Value ?? ""}"));
}
}
else
{
var props = parameter?.GetType().GetProperties();
if (props != null)
url += "?" + string.Join("&", props.Select(x => $"{x.Name}={x.GetValue(parameter)}"));
}
var responseString = await client.GetStringAsync(new Uri(url));
if (castToType != null)
{
if (!string.IsNullOrEmpty(responseString))
return JsonConvert.DeserializeObject(responseString, castToType);
}
return null;
}
// HTTPPost
public static async Task<object> PostAsync(this string url, object parameter, Type castToType = null)
{
if (parameter == null)
throw new Exception("POST operation need a parameters");
var values = new Dictionary<string, string>();
if (parameter is Dictionary<string, object>)
values = (parameter as Dictionary<string, object>).ToDictionary(x => x.Key, x => x.Value?.ToString());
else
{
values = parameter.GetType().GetProperties().ToDictionary(x => x.Name, x => x.GetValue(parameter)?.ToString());
}
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync(url, content);
var contents = await response.Content.ReadAsStringAsync();
if (castToType != null && !string.IsNullOrEmpty(contents))
return JsonConvert.DeserializeObject(contents, castToType);
return null;
}
And now you simply send your data
// if your method has return data you could set castToType to
// convert the return data to your desire output
await PostAsync(solrCoreConnection + "/update",new {commit= true, Id=5});
C# HttpClient or HttpWebRequest class
The advantage of HttpClient
is that it is simpler, and supported on most Portable Class Library profiles. The disadvantage is that it doesn't support non-http requests, which WebRequest
does. In other words HttpClient
is a replacement for HttpWebRequest
but there isn't afaik a replacement for FtpWebRequest
, etc.
Also see this post for more details: HttpClient vs HttpWebRequest
Migrate WebClient JSON-RPC calls to HttpClient in C#
using HttpClient client = new();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{username}:{password}")))
var json = "{\"jsonrpc\":\"2.0\",\"method\":\"GUI.ShowNotification\",\"params\":{\"title\":\"This is the title of the message\",\"message\":\"This is the body of the message\"},\"id\":1}";
var response = await client.PostAsync($"http://{server}:{port}/jsonrpc", new StringContent(json));
Related Topics
Setting the Default Json Serializer in ASP.NET MVC
Can You Overload Controller Methods in ASP.NET MVC
What Does Principal End of an Association Means in 1:1 Relationship in Entity Framework
The Foreach Identifier and Closures
Why Does the Ef 6 Tutorial Use Asynchronous Calls
Passing Arguments to C# Generic New() of Templated Type
Maximum Number of Threads in a .Net App
Use Linq to Xml With Xml Namespaces
How to Convert Byte Array to String
Find Control by Name from Windows Forms Controls
What Is the Simplest Method of Inter-Process Communication Between 2 C# Processes
Get String Between Two Strings in a String
Ef Core Returns Null Relations Until Direct Access
How to Retrieve Id of Inserted Entity Using Entity Framework