Job Requirement:
Create one Announcements list, and add some announcements to this list. These announcements are having the details like title, body, and expires columns by default. When announcements will expire, automatically timer job should delete the items from the list.
Solution:
Create an Announcement list and name it as "TestAnnouncements"
Step1: Creating the SharePoint project
- Open visual studio 2010.
- Select a new “Empty SharePoint project”, enter name and select location. (In my case I given name as “TimerJobExample”)
- When you click “OK” button and in the next page select the option “Deploy as farm solution” and then “Finish”
- When you open solution explorer, it is showing like the below picture.
Step 2: Creating the Job Definition class
- Right click on the solution, click on “Add” and click on “New item”
- To create a custom timer job, first add a class to your SharePoint project and inherit from SPJobDefinition.
Under C# category select Code tab, select Class and give the class name. In my case I given class name as “TestTimer”
- Add these two namespaces to your class file.
using Microsoft.SharePoint;
//This namespace is used for the SPJobDefinition class
using Microsoft.SharePoint.Administration;
- Your class must be public and inherit from SPJobDefinition class. The class file looking like this
- You must implement all three constructors.
public TestTimer(): base()
{
}
public TestTimer(string jobName, SPService service, SPServer server, SPJobLockType targetType):base(jobName, service, server, targetType)
{
}
Public TestTimer(string jobName, SPWebApplication webApplication)
:base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
{
//Set the title of the job, which will be shown in the Central Admin UI
this.Title = "Simple Example for Timer Job";
}
- You must override the Execute method.
public override void Execute(Guid targetInstanceId)
{
}
Whenever timer job executes, it will run the code what we written inside Execute() method.
- Class file is looking like this
write the following code in Execute method.
public override void Execute(Guid targetInstanceId)
{
//Get the Web Application in which this Timer Job runs
SPWebApplication webApp = this.Parent as SPWebApplication;
//Get the site collection
SPSiteCollection timerSiteCollection = webApp.ContentDatabases[targetInstanceId].Sites;
DateTime todaydate = DateTime.Now;
//Get the Announcements list in the RootWeb of each SPSite
foreach (SPSite site in timerSiteCollection)
{
//site.AllowUnsafeUpdates = true;
SPList listTestAnnouncement = site.RootWeb.Lists.TryGetList("TestAnnouncements");
if (listTestAnnouncement != null)
{
SPListItemCollection itemcoll = listTestAnnouncement.GetItems();
if (itemcoll != null)
{
if (itemcoll.Count > 0)
{
for (int i = listTestAnnouncement.Items.Count - 1; i >= 0; i--)
{
SPListItem item = listTestAnnouncement.Items[i];
DateTime dt = Convert.ToDateTime(item["Expires"]);
TimeSpan DateDiff = todaydate - dt;
int days = DateDiff.Days;
if (days > 0)
{
//deleting item from list and storing in recycle bin
item.Recycle();
//if we want to delete permanently from list and recycle bin
//item.Delete();
}
}
}
}
}
//site.AllowUnsafeUpdates = false;
}
}
Step 3: Creating a feature to register the timer job:
To register a timer job, create a feature and use the event receiver to register the timer job.
- Right click on the Features folder, and click on “Add feature”.
- Change the feature name as “CustomTimerJobFeature”.
- Change the scope to “Web application”.
- Right click on your “CustomTimerJobFeature”, and click on “Add event receiver”. Our solution is looks like
- Click on “CustomTimerJobFeature.EventReceiver.cs” and add the below name space
using Microsoft.SharePoint.Administration;
- Declare the string variable in class as shown in the below.
- Uncomment the below two methods shown below.
// Uncomment the method below to handle the event raised after a feature has been activated.
public override void FeatureActivated(SPFeatureReceiverPropertiesproperties)
{
}
// Uncomment the method below to handle the event raised before afeature is deactivated.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
}
- Write the following code in the above two methods.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//In this event we create and install the timer job
//Start by finding the SPSite.
SPSite site = (SPSite)properties.Feature.Parent;
//Make sure the timer job isn't already registered
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == TIMER_JOB_NAME)
{
job.Delete();
}
}
//Create a new Timer job
TimerJobExample.TestTimer newTimerJob = new TimerJobExample.TestTimer(TIMER_JOB_NAME, site.WebApplication);
SPDailySchedule jobSchedule = new SPDailySchedule();
jobSchedule.BeginHour = 9;
jobSchedule.BeginMinute = 30;
jobSchedule.BeginSecond = 0;
jobSchedule.EndSecond = 0;
jobSchedule.EndMinute = 35;
jobSchedule.EndHour = 9;
newTimerJob.Schedule = jobSchedule;
newTimerJob.Update();
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//In this event we must clean up by deleting the timer job
SPSite site = properties.Feature.Parent as SPSite;
//Locate the right timer job
foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
{
if (job.Name == TIMER_JOB_NAME)
{
//This one is the right job. Delete it.
job.Delete();
}
}
}
- Thats it, and execute your timer job code. This timer job will run automatically every day at what time we mentioned in code. In my case it will execute every day in between 09:30AM to 09:35AM. This timer job will connect to "TestAnnouncements" list daily and checks the expires date. If the expires date is less than Today's date, it will remove announcement items from the list automatically.
Note: While deleting list items programatically, never use foreach loop. It will throw you an error, instead you can use for loop as i shown in the my code(in Execute method).
(In the next post i will explain how to debug timer jobs)