I have a form that runs code and sends messages based on starting, stopping and exit or exception to a Teams WebHook.
I can get everything working except the application exit or form closed event handlers, my httpClient always wants to convert the methods to async tasks and thus they don't work if I do that. When I exit, the message is not sent on form closed or application exit.
How can I solve that? Can I use non async instead to send the message to the Teams WebHook?
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
try
{
if (finished == "finished")
{
//Teams Bot Exit
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "myURLhere"))
{
request.Content = new StringContent("{'text':'" + CusMovexNum + " Database Cleanup Tool exited.'}");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request); //doesn't like this
}
}
}
if (finished == "")
{
//Teams Bot Exit
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("POST"), "myURLhere"))
{
request.Content = new StringContent("{'text':'" + CusMovexNum + " Database Cleanup tool exited before finishing!'}");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request); //doesn't like this
}
}
}
}
catch { }
}
If you don't need (or in this case don't want) the operations to run asynchronously, simply use the synchronous versions instead. This means that, instead of:
var response = await httpClient.SendAsync(request);
you'd use:
var response = httpClient.Send(request);
It means the form close will 'hang' for a bit (as long as the web call takes to complete), but at least it will complete, which is what you're wanting to happen.
Related
I have an issue in an app developed for Windows Phone 8.1, where its working just fine, but in Windows Mobile 10 it gets stuck on GetAsync. It doesn't throw an exception or anything, just gets stuck there waiting endlessly. The content-length of the response is 22014030 bytes.
using (HttpClient client = new HttpClient())
{
using (HttpResponseMessage response = await client.GetAsync(url))
{
response.EnsureSuccessStatusCode();
using (HttpContent content = response.Content)
{
return await content.ReadAsStringAsync();
}
}
}
I have also tried reading it as a stream, but as soon as i try to read the content body nothing happens anymore.
The code that calls this function is declared as:
public async Task<List<APIJsonObject>> DownloadJsonObjectAsync()
{
string jsonObjectString = await DownloadStringAsync(Constants.URL);
if (jsonObjectString != null && jsonObjectString.Length >= 50)
{
List<APIJsonObject> result = await Task.Run<List<APIJsonObject>>(() => JsonConvert.DeserializeObject<List<APIJsonObject>>(jsonObjectString));
return result;
}
return null;
}
The reason it is blocking is because you are getting a huge response (20.9MB) which the HttpClient will try to download before giving you a result.
However, you can tell the HttpClient to return a result as soon as the response headers are read from the server, which means you get a HttpResponseMessage faster. To do this, you will need to pass HttpCompletionOption.ResponseHeadersRead as a parameter to the SendRequestAsync method of the HttpClient
Here is how:
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("GET"), url))
{
using (var response = await client.SendRequestAsync(request, HttpCompletionOption.ResponseHeadersRead)
{
//Read the response here using a stream for example if you are downloading a file
//get the stream to download the file using: response.Content.ReadAsInputStreamAsync()
}
}
}
I'm creating an application with Xamarin.Forms which consume from SOAP services using POST method; I have a bunch of services that work correctly, indeed, one of these methods is used to send information in multiple cases and my problem is related with this.
I have the following HttpClient method, but sometimes doesn't work... unfortunately I don't have access to back-end code and they are not for the labour of help me with that.
Any idea about how to improve my method or get any approach to the real error? I'm stuck here, since I send the same fields each time.
public async Task<string> InvokeAsync (string uri, string xmlSOAP) {
try {
using (var handler = new HttpClientHandler () { UseCookies = false })
using (var client = new HttpClient (new NativeMessageHandler ())) {
client.DefaultRequestHeaders.Accept.Add (new MediaTypeWithQualityHeaderValue ("application/xml"));
client.DefaultRequestHeaders.Add ("Cache-Control", "no-cache, no-store, must-revalidate");
client.DefaultRequestHeaders.Add ("Pragma", "no-cache");
client.Timeout = TimeSpan.FromSeconds (timeout);
client.DefaultRequestHeaders.CacheControl.NoCache = true;
var req = new HttpRequestMessage (HttpMethod.Post, uri)
{
Content = new StringContent (xmlSOAP, Encoding.UTF8)
};
req.Content.Headers.ContentType = MediaTypeHeaderValue.Parse ("text/xml; charset=utf-8");
if (uri.ToLowerInvariant ().Equals (jsessionUrlCheck)) {
if (jsession != null && jsession.Count > 0) {
foreach (var cookie in jsession) {
req.Headers.Add ("JSESSIONID", cookie);
}
}
jsession = null;
}
HttpResponseMessage response = await client.SendAsync (req);
string responseBodyAsText = response.IsSuccessStatusCode ? await response.Content.ReadAsStringAsync () : string.Empty;
if (!string.IsNullOrEmpty (responseBodyAsText))
{
return responseBodyAsText;
}
return null;
}
} catch (Exception e) {
Debug.WriteLine ("========= InvokeAsync Exception =========");
Debug.WriteLine ("Error: " + e.Message);
return null;
}}
Any idea about how to [...] get any approach to the real error?
It sounds like you don't really know what exactly happens when it "doesn't work". The way you approach the real error is by finding out what exactly happens in this code when it is reported not to work.
Do you have logs? Check the logs. If the exception is there, that should point you in the right direction. Exception not there? Maybe start logging the data received too. No logs? Start logging; there's no better way to handle intermittent failures that you can't reproduce on demand.
Currently working with the outlook api, even tough I usually work with the outlook library acquired via Nuget; I have reached a limitation where I am not able to accept event invitations. So I proceeded in making a a restful call out to the the outlook api. However, when I am making the call I am getting the following message {"error":{"code":"InvalidMethod","message":"An action can only be invoked as a 'POST' request."}} when executing the call.
Bad Code
class Program
{
static void Main(string[] args)
{
var testAccept = ExecuteClientCall.AcceptEvent().Result;
}
public static async Task<bool> AcceptEvent()
{
AuthenticationContext authenticationContext = new AuthenticationContext(CrmPrototype.Helpers.AuthHelper.devTenant);
try
{
var token = await GetTokenHelperAsync(authenticationContext, CrmPrototype.Helpers.AuthHelper.OutlookAuthenticationEndpoint);
string requestUrl = "https://outlook.office.com/api/v2.0/Users/***#nowwhere.com/events('AAQkAGZiNDQxZTVkLWQzZjEtNDdjNy04OTc4LTM4NmNjM2JiOTRjNAAQAFpV0CnWR0FIpWFYRtszPHU=')/accept";
HttpClient hc = new HttpClient();
hc.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, requestUrl)
{
Content = new StringContent("{SendResponse: true}", Encoding.UTF8, "application/json")
};
HttpResponseMessage hrm = await hc.GetAsync(requestUrl);
if (hrm.IsSuccessStatusCode)
{
string jsonresult = await hrm.Content.ReadAsStringAsync();
var stophere = 0;
}
else
{
return false;
}
return true;
}
catch (Exception ex)
{
throw;
}
}
}
Maybe the reason is that you called
hc.GetAsync(requestUrl);
The doc said that this method:
Sends a GET request to the specified Uri as an asynchronous operation.
Try:
PostAsync(Uri, HttpContent)
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.118).aspx
Hope this help you.
Your variable request contains an HttpRequestMessage object that you have created, but your code presently doesn't do anything with it.
Try replacing the line
HttpResponseMessage hrm = await hc.GetAsync(requestUrl);
(which, as pointed out by the other answer, makes a GET request), with
HttpResponseMessage hrm = await hc.SendAsync(request);
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.
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);