Setup custom retention policy with custom Expiration Formula for custom Document Content Types in individual webs.

This post is a contribution from Manish Joshi, an engineer with the SharePoint Developer Support team

Custom Formula is implemented with Class CustomFormula.cs, compiled to a custom assembly and consumed through the following method:

 Microsoft.Office.RecordsManagement.InformationPolicy.PolicyResourceCollection.Add(xmlExpirationFormula)

 

Following is sample code to install the custom formula

       string strExpirationFormulaID = "testCustomExpirationFormula";
            string strExpirationFormulaName = "testCustomExpirationFormula";
            string strExpirationFormulaDesc = "testCustomExpirationFormula";

            string xmlExpirationFormula = "<PolicyResource xmlns=\"urn:schemas-microsoft-com:office:server:policy\"" +
                                                         " id = \"" + strExpirationFormulaID + "\"" +
                                                         " featureId=\"Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration\"" +
                                                         " type = \"DateCalculator\"> <Name>" + (strExpirationFormulaName) + "</Name>" +
                                                         "<Description>" + (strExpirationFormulaDesc) + "</Description>" +
                                                         "<AssemblyName>RetentionPolicy, Version=1.0.0.0, Culture=neutral," +
                                                         "PublicKeyToken=f3ef95b35506e557</AssemblyName>" +
                                                         "<ClassName>RetentionPolicy.CustomFormula</ClassName>" +
                                                         "</PolicyResource>";
            try
            {
                
                PolicyResourceCollection.Delete(strExpirationFormulaID);
            }
            catch (Exception ex)
            {
                
               // ex.Message.ToString();
            }

            PolicyResource.ValidateManifest(xmlExpirationFormula);
            PolicyResourceCollection.Add(xmlExpirationFormula);

 

To set custom retention policy for a content type with above registered CustomExpirationFormula, the sample code is:

 private static string GeneratePolicyCustomData(string _strExpirationFormulaID)
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                sb.AppendLine("<Schedules nextStageId='3'>");
                sb.AppendLine("<Schedule type='Default'>");
                sb.AppendLine("<stages>");

                // Send Expiry Notification when Today = Near Expiry + 0 days
                sb.AppendLine("<data stageId='1'>");
                sb.AppendLine("<formula id='" + _strExpirationFormulaID + "'>");
              
                sb.AppendLine("</formula>");
                sb.AppendLine("<action type='action' id='Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.MoveToRecycleBin' />");
                sb.AppendLine("</data>");

                sb.AppendLine("</stages>");
                sb.AppendLine("</Schedule>");
                sb.AppendLine("</Schedules>");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return sb.ToString();
        }

private void SetPolicy(string contentTypeName, string strExpirationFormulaID)
        {
            using (SPSite site = new SPSite(SPContext.Current.Web.Url))
            using (SPWeb web = site.OpenWeb())
            {
                SPContentType contentType = web.ContentTypes.Cast<SPContentType>().Where(cty => cty.Name.Trim().ToLower() == contentTypeName.ToLower()).FirstOrDefault();
                if (contentType != null)
                {
                    try
                    {
                        if (Policy.GetPolicy(contentType) != null)
                        {
                            Policy.DeletePolicy(contentType);
                        }

                        Policy.CreatePolicy(contentType, null);
                        Policy policy = Policy.GetPolicy(contentType);

                        string policyCustomData = GeneratePolicyCustomData(strExpirationFormulaID);

                        policy.Items.Add("Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration", policyCustomData);
                        contentType.Update();
                        
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }//EndOfIf

            }
        }
            
  string strExpirationFormulaID = "testCustomExpirationFormula";
  string customCT1 = "CustomDocument1";   
  SetPolicy(customCT1, strExpirationFormulaID);

 

To set the custom retention policy at the web's content type level, use following code to create a child content type for a web.
Be sure to use a different content type name for the root web's content type though.

For root web,

       SPContentType sdFileContentType = new SPContentType(contentTypes["SecureDocFile"], contentTypes, "SecureDocFile_rootWeb");
            sdFileContentType.Group = "CentRic Portal Content Types";
            web.ContentTypes.Add(sdFileContentType);

            SPContentType sdMessageContentType = new SPContentType(contentTypes["SecureDocMessage"], contentTypes, "SecureDocMessage_rootWeb");

 

For non-root web:

          SPContentType sdFileContentType = new SPContentType(contentTypes["SecureDocFile"], contentTypes, "SecureDocFile_Web");
            sdFileContentType.Group = "CentRic Portal Content Types";
            web.ContentTypes.Add(sdFileContentType);

            SPContentType sdMessageContentType = new SPContentType(contentTypes["SecureDocMessage"], contentTypes, "SecureDocMessage_Web");