I'm working on an MVC .Net web application. I have a database in which i have a table called Tasks, every task is associated to one user and every task has a delay. I want to send emails automatically to the user to whom the task is associated before two days (for example) from its expiration date.
You can use Windows Service to send email automatically.
Please refer below link
http://www.dotnetfunda.com/articles/article931-how-to-send-mail-automatically-for-every-five-minutes-using-csharp.aspx
You can set the timer for 2 days with your logic.
You could write a Windows Service application or a Console application that will be scheduled to run at regular intervals using the Windows Scheduler (for example once a day), it will query your database, extract the records matching the required criteria and, yeah, SmtpClient.
The reason I am saying this is because this task should not be done by your web application. It should be performed by a separate application. Recurring background tasks such as the one you need to perform is a no-no in a web application. The Haacked discussed why this is a very bad idea: http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx
Little mock up example:
DateTime today = DateTime.Now;
TimeSpan diff = user.Tasks.ExpirationDate.Subtract(today);
int dateDiff = Convert.ToInt32(diff.TotalDays);
if (dateDiff == 2)
{
//Send Email
}
You could then place this in a Services/Email folder in your mvc app and create a separate console app to request the page everyday, therefore running the query, e.g:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("YOUR PAGE");
string response = new System.IO.StreamReader(req.GetResponse()
.GetResponseStream()).ReadToEnd();
You would use Windows Task Scheduler to run the console app every day which would start the console app > console app requests page > page checks expiration date on tasks > sends emails
Related
I want to create some functions in ASP.NET Web API, which should be executed daily at specific time and do specific task like update statuses/Records/Generating Emails, SMS.
Should i create a TaskService in Code
using System;
using Microsoft.Win32.TaskScheduler;
class Program
{
static void Main(string[] args)
{
// Get the service on the local machine
using (TaskService ts = new TaskService())
{
// Create a new task definition and assign properties
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = "Does something";
// Create a trigger that will fire the task at this time every other day
td.Triggers.Add(new DailyTrigger { DaysInterval = 2 });
// Create an action that will launch Notepad whenever the trigger fires
td.Actions.Add(new ExecAction("notepad.exe", "c:\\test.log", null));
// Register the task in the root folder
ts.RootFolder.RegisterTaskDefinition(#"Test", td);
// Remove the task we just created
ts.RootFolder.DeleteTask("Test");
}
}
}
or should i create a .bat file and create a new task in Task Scheduler.
As you have mentioned in the question, you need to do the specific tasks like update statuses/Records/Generating Emails, SMS etc.
So database access comes into the scenario and on the other hand, you will have to send emails and SMS's which may require third party libraries or other configuration setting access.
Thus, to do all this it will be better to go with code implementation via which you can maintain your changes and requirements well enough.
About the ".bat file and windows scheduler", you need to have great skills using the limited batch commands available to fulfill your requirement.
So, my suggestion is code, .exe and windows scheduler task.
Also, this should be a separate application, don't mix it up with Web API code. You can always create a new project in the web API solution with web API project and reuse whatever code is possible.
You should do this outside your web code. This is because your webapp should have no access to the task system or web service. By default IIS 7.5+ runs app's in their own limited user account (https://www.iis.net/learn/manage/configuring-security/application-pool-identities).
If you want to have a reliable tasks scheduling wherein you can apply time interval depend on your choice, I recommend [quartz]: https://www.quartz-scheduler.net/. Quartz allow to add/edit/delete/etc a scheduled task easily, manageable and no CPU overhead.
Moreover Quartz is an open source job scheduling system that can be used from smallest apps to large scale enterprise systems.
I recommend you to try Hangfire. It's free and you can use it for free in commercial app. Ducumentation you can find here.
I want to trigger an Azure Webjob 24Hours after I have added a record to a database using .NET . Obviously there will be multiple tasks for the Webjob to handle, all at their designated time. Is there a way ( in the Azure Library for .NET) in which i can schedule this tasks ?
I am free to use Message Queues , but I want to try and avoid the unnecessary polling of the WebJob for new messages.
If you want to trigger the execution of a WebJob 24 hours after a record insertion in a SQL database I would definitely use Azure Queues for this. So after you insert the record, just add a message to the queue.
In order to do this you can easily leverage the initialVisibilityDelay property that can be passed to the CloudQueue.AddMessage() method. This will make the message invisible for 24 hours in your case, and then it will appear to be processed by your Webjob. You don't have to schedule anything, just have a Continuous WebJob listening to a queue running.
Here's some sample code:
public void AddMessage(T message, TimeSpan visibilityDelay)
{
var serializedMessage = JsonConvert.SerializeObject(message);
var queue = GetQueueReference(message);
queue.AddMessage(new CloudQueueMessage(serializedMessage), null, visibilityDelay);
}
private static CloudQueue GetQueueReference(T message)
{
var storageAccount = CloudStorageAccount.Parse("Insert connection string");
var queueClient = storageAccount.CreateCloudQueueClient();
var queueReference = queueClient.GetQueueReference("Insert Queue Name");
queueReference.CreateIfNotExists();
return queueReference;
}
Hope this helps
Since the event of adding a record to the database is the trigger here, You can use Azure Management Libraries to create a Azure Scheduler Job to execute after 24hrs from the time the db record is inserted. Azure Scheduler Jobs can do only 3 things : make HTTP/HTTPS requests or Put Message in Queue. Since you do not want to poll queues, here are two options
Deploy the existing Web Job as Wep API where each task is reachable by unique URLs, so that the scheduler task can execute the right HTTP/HTTPS request
Create a new WebAPI/Wep API which takes accepts request (like a man in the middle) and pro-grammatically run the existing web job on demand, again using Azure management libraries.
Please let me know if any of these strategies help.
To invoke a WebJob from your Website,is not good idea rather than you can add the WebJob code inside your Website and simply call that code. you can still easily use the WebJob SDK from inside your Website.
https://github.com/Azure/azure-webjobs-sdk-samples
we wouldn't recommend to invoke the WebJob from your Website is that the invocation contains a secret you rather not store on your Website (deployment credentials).
Recommendation:
To separate WebJob and Website code, the best thing to do is to communicate using a queue, the WebJob listens on the queue and the Website pushes the request to the queue.
I have web project that created in Visual Studio 2010 and use SQL Server 2008 R2 for database,
Commonly i use SQL Server Agent to send report (from SQL database) to my client email, and now i want to move my application to other web hosting. My question is there any method to generate report and send to email automatically by schedule in web hosting?
Thank you for your suggestion.
Scheduling tasks in a web project is possible using the Revalee open source project.
Revalee is a service that allows you to schedule web callbacks to your web application. In your case, you would schedule a callback that would generate your report and send emails automatically. Revalee works very well with tasks that are discrete transactional actions, like updating a database value or sending an automated email message (read: not long running). The code to generate your report and send the emails would reside within your web app. More specifically, on a target web page that Revalee would call at your scheduled time. When your application launches for the very first time, then you would schedule the first web callback. When your application is called back to generate the report, then you would schedule the next callback.
To use Revalee, you would:
Install the Revalee Service, a Windows Service, on your server. The Windows Service is available in the source code (which you would compile yourself) or in a precompiled version available at the Revalee website (above).
Use the Revalee client library in your Visual Studio project. The client library is available in the source code (which, again, you would compile yourself) or in a precompiled version available via NuGet.
You would register a future callback (for example, at a specific time) when your application launches via the ScheduleMidnightCallback() method (see below).
private DateTimeOffet? previousCallbackTime = null;
private void ScheduleMidnightCallback()
{
// Schedule your callback for midnight tomorrow
var tomorrow = DateTimeOffset.Now.AddDays(1.0);
var callbackTime = new DateTimeOffset(tomorrow.Year,
tomorrow.Month,
tomorrow.Day,
0, // Hour
0, // Minute
0, // Second
tomorrow.Offset);
// Your web service's Uri, including any query string parameters your app might need
Uri callbackUrl = new Uri("http://yourwebapp.com/Callback.aspx");
// Register the callback request with the Revalee service
RevaleeRegistrar.ScheduleCallback(callbackTime, callbackUrl);
previousCallbackTime = callbackTime;
}
When the web scheduled task activates and calls your application back, you perform whatever action you need to do at midnight and you schedule the next callback too. You do this by adding the following method call (CallbackMonitor()) to your Callback.aspx page handler.
private DateTimeOffset? mostRecentCallback = null;
private void CallbackMonitor()
{
var midnight = new DateTimeOffset(DateTimeOffset.Now.Year,
DateTimeOffset.Now.Month,
DateTimeOffset.Now.Day,
0, // Hour
0, // Minute
0, // Second
DateTimeOffset.Now.Offset);
if (!mostRecentCallback.HasValue
|| mostRecentCallback.Value < midnight)
{
mostRecentCallback = midnight;
// Perform your report generation & send email-related tasks
// ...do your work here...
// Schedule subsequent callback
ScheduleMidnightCallback();
}
}
I hope this helps.
One last thing: Revalee does have an ASP.NET MVC specific library as well, in case you are migrating your web application from ASP.NET to ASP.NET MVC.
Disclaimer: I was one of the developers involved with the Revalee project. To be clear, however, Revalee is free, open source software. The source code is available on GitHub.
In our application we are having monthly subscription so on last date of the month amount should transfer from UserAccount to CompanyAccount?
How to do this after equal frequency?Like Mothly,Quaterly etc.
Please Help US.........
You can use Windows task scheduler to call specific web page or exe which will do transfer.
Set up one task scheduler to call transfer monthly and second to call quarterly.
in my web-application I want to send mail for users according to pre selected periods by themselves. for example: 1 HTML Mail Per 3days to user 01 and 1 HTML Mail Per 20days to user 02
how can I perform that? any resources? I can send mail by my app from My Gmail Account to any mail addresses in my tables but i dont know how to send it automatically in a period of time.(i use C# and SQL Express)
Help me out!
I found the Solution. according to my search we have 3 ways to handle that:
working with SQL Server to send mail notification in periods of time.(or this)
using Windows service and Creating Timer object and checking the time with it.
but in ways 1 and 2 we should access to server and we need dedicated hosting server to for example installing WinService on it. so it does not work in a sharing Host space we usually use. So I Found the best way as you see:
3. Simulating Windows Services Using ASP.NET Caching For Scheduled Jobs.
the link above is a terrific solution. So there is no need to work out-side of our web application.
You will need something which can periodically run jobs for you, like a cron daemon or windows task scheduler.
Essentially you have the periodic job kick off and do whatever mail handling you need.
You can also do this from code if you can create a windows service to basically sleep until the next batch of mails needs to be sent.
The easiest is to write the task scheduler or cron job to run periodically. In that way you just need a small piece of code to handle the mail sending portion and then you just schedule it to run once an hour or day or whatever needed.
Hai,
Have a look at quartz.net
Quartz.NET is a full-featured, open source job scheduling system that can be used from smallest apps to large scale enterprise systems.
Quartz.NET is a port of very propular open source Java job scheduling framework, Quartz. Quartz.NET supports clustering and database persistence out-of-the-box and has powerful means to schedule jobs using cron like expressions, interval triggers and exclusion advices.
The great thing about IIS hosted ASP.NET is that IIS will (by default) periodically recycle your application pool according to the settings on the app pool itself.
When your application pool is starting (which could be at least once a day especially if it's allowed to idle i.e. a business app where most activity is 9-5) the Application_Start event-handler in Global.asax is fired. This could be used for your recurring task.
Now you don't necessarily want to run this email send synchronously within that Application_Start handler because to me it seems this messaging functionality is not core to the startup but by all means use this event-handler as an easy way to periodically do your housekeeping.
To send async you should use async delegates for example.
i think there a solution:
1- you have to add 2 column in the user table in your sql db if you have a user table and in the first column add the date of the last email sent to the user and the second column has the period for sending the email for that user for ex:
LastEmailSentDate datetime
SendEmailPeriod int
2- in your application code write a function that compare the last date of the last sent email with the period of the sending the email.
// here the funciton code
public void CompareLastSentDate()
{
// lets assume that you bring the data for the db using Sqdatareader reader
//get the field from the LastEmailSentDate field in the database as i mention before
DateTime LastEmailSentDate = Convert.ToDate(reader["DatePeriod"])
// get the field from the SendEmailPeriod of the user field from database
int sendEmailPeriod = Convert.Toint32(reader["SendEmailPeriod"])
// now you have the date before the period of day ex: before 3 days depend on user
DateTime DatePeriod = new DateTime(DateTime.Now.Year, DateTime.Now.Month, (DateTime.Now.Day - sendEmailPeriod ));
// if the last email send is before period of day that mean u have to send an email again
if(LastEmailSentDate.Day <= DatePeriod.Day)
{
// sent the email to the user
}
}
note: now u can loop among the users and sent the email
you can call this function once in a day by calling it from ur app home page Page_Load event and after the first call of the day add an application["LastFunctionCallDate"] = DateTime.Now flag so in the next you can check this flag if its == today and if not call it again