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");