How to invoke Web API in console or service application?
-
I have a Web API to send SMS to customers. Web API is up and running 24/7/365. Web API is running fine without any issues. However, I am invoking the API everytime through PostMan tool. In order to avoid this manual intervention, I have written a console application, but that console application sometimes works, sometimes didn't. it stops abruptly without any reason, I tried to catch error, but no effect. The application has to run automatically with an interval of 5 minutes in day. Every 5 minute it has to run. If already previous task is running, then no need to start a new task. I have implemented this by using a ProcessMap table in Sql DB. So each time it starts, it checks if any sms task is running. if running,it will not start new, otherwise starts a new task. My question is , is this the correct way to invoke the API automatically or is there any other better way to do this? Kindly hep.
-
I have a Web API to send SMS to customers. Web API is up and running 24/7/365. Web API is running fine without any issues. However, I am invoking the API everytime through PostMan tool. In order to avoid this manual intervention, I have written a console application, but that console application sometimes works, sometimes didn't. it stops abruptly without any reason, I tried to catch error, but no effect. The application has to run automatically with an interval of 5 minutes in day. Every 5 minute it has to run. If already previous task is running, then no need to start a new task. I have implemented this by using a ProcessMap table in Sql DB. So each time it starts, it checks if any sms task is running. if running,it will not start new, otherwise starts a new task. My question is , is this the correct way to invoke the API automatically or is there any other better way to do this? Kindly hep.
Given your requirements, I'd be inclined to write a console application to call the API once and then exit. Then use the Windows Task Scheduler to schedule that application to run every five minutes. By default, if the task is already running, Task Scheduler won't start it again, so you shouldn't need any SQL tables or additional checks. As for fixing the crashes, you'll need to debug your application. If you want someone to help you fix the errors, we'll need to see the full error details, and the relevant parts of your code.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
Given your requirements, I'd be inclined to write a console application to call the API once and then exit. Then use the Windows Task Scheduler to schedule that application to run every five minutes. By default, if the task is already running, Task Scheduler won't start it again, so you shouldn't need any SQL tables or additional checks. As for fixing the crashes, you'll need to debug your application. If you want someone to help you fix the errors, we'll need to see the full error details, and the relevant parts of your code.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Thank you Richard. I think if you can clarify little bit on first portion of your reply, I will be able to fix my issue. In my console application, I have invoked the API as below:
class Program
{
static void Main(string[] args)
{RunAsync().GetAwaiter().GetResult(); Environment.Exit(0); }
static async Task RunAsync()
{
string httpReasonStatus = string.Empty;
int reasoncode;using (var client = new HttpClient()) { string baseURL = ConfigurationManager.AppSettings\["APIURL"\].ToString().Trim(); client.BaseAddress = new Uri(baseURL); //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth","xyz"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Console.WriteLine("Get"); HttpResponseMessage response = await client.GetAsync("/api/SendBulkSMS"); if (response.IsSuccessStatusCode) { reasoncode = (int)response.StatusCode; httpReasonStatus = response.ReasonPhrase; } else { reasoncode = 0; httpReasonStatus = "error"; } } } }
How would you call the Console application once, and then use the Windows Scheduler to schedule the application without using Sql tables. I am also not in favour of using Sql tables, and looking for any other better ways. Can you please provide any guide on this? Thanks a lot for the support.
-
Thank you Richard. I think if you can clarify little bit on first portion of your reply, I will be able to fix my issue. In my console application, I have invoked the API as below:
class Program
{
static void Main(string[] args)
{RunAsync().GetAwaiter().GetResult(); Environment.Exit(0); }
static async Task RunAsync()
{
string httpReasonStatus = string.Empty;
int reasoncode;using (var client = new HttpClient()) { string baseURL = ConfigurationManager.AppSettings\["APIURL"\].ToString().Trim(); client.BaseAddress = new Uri(baseURL); //client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("OAuth","xyz"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Console.WriteLine("Get"); HttpResponseMessage response = await client.GetAsync("/api/SendBulkSMS"); if (response.IsSuccessStatusCode) { reasoncode = (int)response.StatusCode; httpReasonStatus = response.ReasonPhrase; } else { reasoncode = 0; httpReasonStatus = "error"; } } } }
How would you call the Console application once, and then use the Windows Scheduler to schedule the application without using Sql tables. I am also not in favour of using Sql tables, and looking for any other better ways. Can you please provide any guide on this? Thanks a lot for the support.
That code is already doing what I expected - it calls the API once and then exits. There's no code to check a SQL table to try to enforce a single instance. The task scheduler hasn't changed very much since Vista. You just need to launch it and create a new task to run your console application: How to Automatically Run Programs and Set Reminders With the Windows Task Scheduler[^] NB: I'd be inclined to make a couple of changes to your code:
static class Program
{
static async Task<int> Main()
{
string baseURL = ConfigurationManager.AppSettings["APIURL"].Trim();
if (!Uri.TryCreate(baseURL, UriKind.Absolute, out var baseAddress))
{
Console.Error.WriteLine("Invalid API URL: '{0}'", baseURL);
return -1;
}using (var client = new HttpClient()) { client.BaseAddress = baseAddress; client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); Console.WriteLine("Get"); using (var response = await client.GetAsync("/api/SendBulkSMS")) { Console.WriteLine("{0}: {1}", response.StatusCode, response.ReasonPhrase); if (response.IsSuccessStatusCode) return 0; return (int)response.StatusCode; } } }
}
- Since C# 7.1, you can make the
Main
methodasync
. - You can return the exit code directly, rather than using
Environment.Exit
. - You should avoid throwing an exception if the URL in the config file is invalid.
- You should wrap the
HttpResponseMessage
in ausing
block. - There's no point in the
reasoncode
andhttpReasonStatus
variables, since you never use them. - Console applications should generally return
0
if they succeed, and non-zero if they fail. The non-successful HTTP status code looks like a good candidate here.
- Since C# 7.1, you can make the