Completely non-blocking HTTP request C# ASP.NET - c#

During my application's Application_Start() event I want to fire off a HTTP request to an address. I absolutely do not want any cost incurred by Application_Start() and for App Start to be delayed in any fashion. I do not care about the response from the request.
What is the most correct method for firing this request in a completely non-blocking fashion?

I would do something like this:
Task.Run(() =>
{
using (var httpClient = new HttpClient())
{
httpClient.BaseAddress = new Uri("https://something.com/");
var content = new StringContent("content");
var result = httpClient.PostAsync("path/to/Service" , content);
result.Wait();
}
});

I would recommend just firing the request asynchronously
using(var client = new HttpClient())
{
client.PostAsJsonAsync("{url}",content)
}
for example will fire the request and continue

You can use WebClient.UploadStringAsync Method for this purpose
This method does not block the calling thread.
It can throw
ArgumentNullException
WebException
use it in this way
var client = new WebClient();
//remove comment from next line to execute some code after UploadString complete
//client.UploadStringCompleted += new UploadStringCompletedEventHandler(function name to execute when finish);
var data = "data to send";
client.Headers.Add("Content-Type", "content type here");
client.UploadStringAsync(new Uri("http://www.yourDomain.com"), data);

Related

How do I return the HTTP status code when I'm making a JSON post in C#?

I don't understand the variable types and how i can utilize client to retrieve the http Status code.
The client variable is a standard HttpClient object.
The attached picture is the function I'm trying to retrieve the status code during. Any help would be greatly appreciated.
[1]: https://i.stack.imgur.com/9iR3g.png
It should be easy as
var client = new HttpClient();
var results = await client.GetAsync("https://stackoverflow.com");
Console.WriteLine(results.StatusCode);
Your issue is that you're not getting response object. You are getting the content of the body of the response.
Here is a sample code:
void SimpleApiCall()
{
Uri endpoint = new Uri("https://www.7timer.info/bin/");
using var client = new HttpClient();
client.BaseAddress = endpoint;
// Get the response only here, and then get the content
// I'm using GetAwaiter().GetResult() because client.GetAsync() returns a Task and you're not using the async await since this is a button click event
var response = client.GetAsync("astro.php?lon=113.2&lat=23.1&ac=0&unit=metric&output=json&tzshift=0").GetAwaiter().GetResult();
// Status code will be available in the response
Console.WriteLine($"Status code: {response.StatusCode}");
// For the Reason phrase, it will be Ok for 200, Not Found for a 404 response...
Console.WriteLine($"Reason Phrase: {response.ReasonPhrase}");
// read the content of the response without the await keyword, use the .GetAwaiter().GetResult()
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
Console.WriteLine("Content:");
Console.WriteLine(content);
}
Same goes for PostAsync and all the other operations...

Close console app after calling webapi without waiting for result

I'm trying to call a webapi from a console application (which is triggered by windows task scheduler). I don't want my console app to wait for the result from api.I just want to call api and initiate it and exit the console application.
My console application code is
public static void InvokeSisService(string feature)
{
var serviceurl = ConfigurationManager.AppSettings["AppServiceURL"];
var controllerPath= ConfigurationManager.AppSettings["ControllerPath"];
var client = new HttpClient { BaseAddress = new Uri(serviceurl) };
controllerPath= controllerPath+ "?feature=" + feature;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
//client.PostAsync(smsservicepath, null);
// var temp=client.GetAsync(smsservicepath).Result;
var response = Task.Run(() => client.GetAsync(controllerPath)).Result;
}
My webapi is being called but it was waiting for the output.How do i exit console app after calling api.
Webapi code
[HttpGet]
[Route("ProcessService")]
public HttpResponseMessage ProcessService([FromUri] string feature)
{
}
I'm sure you want to make sure the response was received, so change
var response = Task.Run(() => client.GetAsync(controllerPath)).Result;
To:
using (var response = await client.GetAsync(controllerPath, HttpCompletionOption.ResponseHeadersRead))
This will drop after the response headers have been received. This does NOT include error handling - you should probably add error handling to the mix to make sure you are getting a proper response code before moving on - but that's up to you.
var response = Task.Run(() =>
client.GetAsync(controllerPath)).Result;
with the property "Result" you are waiting for the Response.

How to call web API from an http client using a small timeout

I'm working with two web API projects that get communicated. The first web API calls the second one using an HttpClient class.
What I would like to do is to set a short timeout (500 ms) when I call the second web API, and if I don't get response in that time, just to skip the next lines that process the result in the client, but continue processing the request at server side(second API).
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = this.Timeout; // (500ms)
HttpResponseMessage response = client.PostAsJsonAsync(EndPoint, PostData).Result;
if (response.IsSuccessStatusCode)
{
return response.Content.ReadAsAsync<T>().Result;
}
else
{
throw new CustomException()
}
}
It works in the first API side, however in the second API(server), I get the following exceptions:
"A task was canceled."
"The operation was cancelled."
at System.Threading.CancellationToken.ThrowOperationCanceledException()
at System.Threading.CancellationToken.ThrowIfCancellationRequested()
I think it is caused by the small timeout of the call, that ends when the second API is still processing the result.
How could I avoid this behaviour in the second API and continue processing the request ?
Thanks in advance.
That is the expected behavior. When you set a timeout and the call does not respond in that amount of time, the task is canceled and that exception is thrown.
And by the way, do not use .Result. That will cause blocking. Mark your method async and use await.
The whole thing should look something like this:
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Clear();
client.Timeout = this.Timeout; // (500ms)
try
{
HttpResponseMessage response = await client.PostAsJsonAsync(EndPoint, PostData);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsAsync<T>();
}
else
{
throw new CustomException()
}
}
catch (TaskCanceledException)
{
// request did not complete in 500ms.
return null; // or something else to indicate no data, move on
}
}

Get application to wait until Variables are updated

I am working with OAuth at the moment. The problem with the current code is it doesn't wait until the user allows the application on the site and gets the proper key and secret. I was using a threading type wait but, sometimes it not long enough...some users are slower then others. I have attached a snippet of my code. What I would like to know is where to insert a while statement, or should I even use that ?
public OAuthToken GetRequestToken(Uri baseUri, string consumerKey, string consumerSecret)
{
var uri = new Uri(baseUri, "oauth/request_token");
uri = SignRequest(uri, consumerKey, consumerSecret);
var request = (HttpWebRequest) WebRequest.Create(uri);
request.Method = WebRequestMethods.Http.Get;
var response = request.GetResponse();
var queryString = new StreamReader(response.GetResponseStream()).ReadToEnd();
var parts = queryString.Split('&');
var token = parts[1].Substring(parts[1].IndexOf('=') + 1);
var secret = parts[0].Substring(parts[0].IndexOf('=') + 1);
return new OAuthToken(token, secret);
}
You should switch over to the newer System.Net.Http and System.Net.Http.WebRequest libraries that come with .NET now. These all use the new async programming stuff that is available with .NET 4.5.
You can call a request (returning you a task object that you can wait on) and automatically pause the thread for the response. The UI won't respond, as normal. That is probably the easiest thing to do if you don't understand how the new async and await keywords work. For more information on them, see http://msdn.microsoft.com/en-us/library/hh191443.aspx
Here is your code doing things with the new libraries:
using System.Net.Http;
public OAuthToken GetRequestToken(Uri baseUri, string consumerKey, string consumerSecret)
{
var uri = new Uri(baseUri, "oauth/request_token");
uri = SignRequest(uri, consumerKey, consumerSecret);
var message = new HttpRequestMessage(new HttpMethod("GET"), uri);
var handler = new WebRequestHandler();
var client = new HttpClient(handler);
// Use the http client to send the request to the server.
Task<HttpResponseMessage> responseTask = client.SendAsync(message);
// The responseTask object is like a wrapper for the other task thread.
// We can tell this task object that we want to pause our current thread
// and wait for the client.SendAsync call to finish.
responseTask.Wait();
// - Once that thread finishes, and the code continues on, we need to
// tell it to read out the response data from the backing objects.
// - The responseTask.Result property represents the object the async task
// was wrapping, we want to pull it out, then use it and get the content
// (body of the response) back.
// - Getting the response actually creates another async task (the
// .ReadAsStringAsync() call) but by accessing the .Result
// property, it is as if we called .ReadAsStringAsync().Wait(); Except that
// by using Result directly, we not only call Wait() but we get the resulting,
// wrapped object back. Hope that didn't confuse you much :)
var queryString = responseTask.Result.Content.ReadAsStringAsync().Result;
// And all your other normal code continues.
var parts = queryString.Split('&');
var token = parts[1].Substring(parts[1].IndexOf('=') + 1);
var secret = parts[0].Substring(parts[0].IndexOf('=') + 1);
return new OAuthToken(token, secret);
}
Why Not use a modal pop up and then call the authentication class on the submit button

WinRt C# HttpClient SendAsync does not return

I am creating a Metro App that makes a HTTP Post request to a webserver to obtain JSON data. Initially I use the same code to logon to the web server and the HTTP Post request returns fine. It is only later that I run into an issue where the code hangs when I call the SendAsync() method.
I used wireshark to view the network traffic and I did see the server returning a response. So I am not sure why the call is not completing. Anyone have any ideas?
Here is the code I am using:
var httpHandler = new HttpClientHandler();
httpHandler.CookieContainer = __CookieJar;
var httpClient = new HttpClient(httpHandler);
UserAgentDetails userAgent = UserAgentDetails.GetInstance();
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent.UserAgentString);
foreach (string key in __colHeaders)
httpClient.DefaultRequestHeaders.Add(key, __colHeaders[key]);
var content = new StringContent(postData);
if (contentType != null && contentType.Length > 0)
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
var requestMsg = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
requestMsg.Content = content;
requestMsg.Headers.TransferEncodingChunked = true;
var responseMsg = await httpClient.SendAsync(requestMsg);
// no return from method after logon

Categories

Resources