First published on TECHNET on Oct 16, 2016
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(xmlExpirationForm...
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");