January 07, 2009

How to create a custom expiration formula and deploy it through a SharePoint solution

In this tutorial, we start from a SharePoint site based on the Team Site template.



We will apply the custom expiration formula to the out-of-the-box Shared Documents documents library. Our formula will check if the Title of the item starts with underscore and if it's the case, it will set the item expiration date to today.



To set an expiration policy, you have to click on the Information management policy settings in the Documents Library Settings.



After, you have to select Define a policy... and click on OK.



In the Edit Policy page, you have to check Enable Expiration and you will see a dropdown list with the custom expiration formula installed on the server (highlighted section).



So, let's open Visual Studio 2008 (with WSS Extensions 1.2.)...



First, you have to create a new Empty SharePoint project.





Now, he have to add 2 references to the project:
- Microsoft Office Server DLC Component (Microsoft.Office.Policy.dll)
- Windows SharePoint Service (Microsoft.SharePoint.dll)






The next step is to add the class which will contain the code for the custom expiration formula. For that, you have to add a new class to the project. In this example, I call it TitleStartingWithUnderscoreExpirationFormula.



You have to remove all the namespaces except the System one and to add the Microsoft.SharePoint and Microsoft.Office.RecordsManagement.PolicyFeatures ones. You also have to put the class as public and to implement the IExpirationFormula interface. Implementing this interface involves to write the ComputeExpireDate method which takes 2 parameters (SPListItem and XmlNode) and returns a nullable DateTime object. In this method, we have to check if the Title property of the SPListItem passed as paremeter begins with '_'. If it's the case, the method must return the today. Otherwise, it must return a null value.

using Microsoft.Office.RecordsManagement.PolicyFeatures;
using System;
using Microsoft.SharePoint;
 
namespace UnderscoreInTitlePolicy
{
    public class TitleStartingWithUnderscoreExpirationFormula : IExpirationFormula
    {
        public Nullable<DateTime> ComputeExpireDate(SPListItem item, System.Xml.XmlNode parametersData)
        {
            DateTime? expirationDate = null;
 
            if (item.Title.StartsWith("_"))
            {
                expirationDate = DateTime.Today;
            }
            return expirationDate;
        }
    }
}

To deploy our formula through a feature, we have to create a class inheriting from the SPFeatureReceiver class and to override the FeatureActivated and the FeatureDeactivating methods.
In the FeatureActivated method, we have to put the code to register our new custom formula. For that, we have to create a manifest (built using a StringBuilder object) which is a xml containing a PolicyResource node having three attributes:
- id (UnderscoreInTitlePolicy.TitleStartingWithUnderscoreExpirationFormula)
- featureId (Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration)
- type (DateCalculator)
The PolicyResource node has also 4 elements (Name, Description, AssemblyName and ClassName). To finish, we have to validate the manifest (ValidateManifest method of the PolicyResource class) and to add it the the policy resource collection (Add method of the PolicyResourceColletion class).
In the FeatureDeactivating method, we simplly have to delete the manifest from the policy resource collection (Delete method of the PolicyResourceColletion class).



using System;
using Microsoft.SharePoint;
using Microsoft.Office.RecordsManagement.InformationPolicy;
using System.Text;
 
namespace UnderscoreInTitlePolicy
{
    public class UnderscoreInTitlePolicyFeatureReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("<PolicyResource xmlns='urn:schemas-microsoft-com:office:server:policy' ");
            sb.Append("  id = 'UnderscoreInTitlePolicy.TitleStartingWithUnderscoreExpirationFormula' ");
            sb.Append("  featureId='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration' ");
            sb.Append("  type = 'DateCalculator'>");
            sb.Append("<Name>Title Starting With Underscore Expiration</Name>");
            sb.Append("<Description>Set the expiration date to today for items having the title starting with underscore</Description>");
            sb.Append("<AssemblyName>UnderscoreInTitlePolicy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5</AssemblyName>");
            sb.Append("<ClassName>UnderscoreInTitlePolicy.TitleStartingWithUnderscoreExpirationFormula</ClassName>");
            sb.Append("</PolicyResource>");
            try
            {
                PolicyResource.ValidateManifest(sb.ToString());
                PolicyResourceCollection.Add(sb.ToString());
            }
            catch { }
        }
 
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            try
            {
                PolicyResourceCollection.Delete("UnderscoreInTitlePolicy.TitleStartingWithUnderscoreExpirationFormula");
            }
            catch { }
        }
 
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
            // No operation
        }
 
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
            // No operation
        }
    }
}

The next step is to create the feature itself, for that we have to leave the Solution Explorer and switch in the WSP View.



You have to click on the new button (blank document icon). You will see that a feature (Feature 1) will be added to the solution. You have to edit the feature.xml file to set the scope of the feature to Farm and to add and specify the AssemblyReceiver and ClassReceiver attributes.



<?xml version="1.0" encoding="utf-8"?>
<Feature 
  Id="0925412d-5ac9-4acc-987e-5cec1d814d7f" 
  Title="Underscore In Title Policy Feature" 
  Scope="Farm" 
  Version="1.0.0.0" 
  Hidden="FALSE" 
  DefaultResourceFile="core" 
  xmlns="http://schemas.microsoft.com/sharepoint/"
  ReceiverAssembly="UnderscoreInTitlePolicy, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5"
  ReceiverClass="UnderscoreInTitlePolicy.UnderscoreInTitlePolicyFeatureReceiver"/>

To finish, you have to rebuild the solution and to deploy it. Visual Studio automatically deploys the SharePoint solution and activate the Feature. You will see that our formula is now available in Expiration section of the Edit Policy page of your document library.







Download the project: Here

MSDN Links:
Creating a Custom Expiration Formula Based on Metadata in SharePoint Server 2007 (Part 1 of 2)
Creating a Custom Expiration Formula Based on Metadata in SharePoint Server 2007 (Part 2 of 2)

5 comments:

Unknown said...

This blog is really useful, actually i was looking for something different like a guide and i think a reached now in this blog. Honestly after to read this blog, i have too much knowledge than before. thanks.

buy viagra

Unknown said...

Awesome! Thanks!

mrbhuiya said...

nice!!

Anonymous said...

Interesting article! Keep sharing more in the future nice blog.
Crack Software

Rohit said...

how is PublicKeyToken=9f4da00116c3 calculated?