“Learn SharePoint from SharePoint” is the principal theme of learning SharePoint
for me because what SharePoint says us to do for creating any SharePoint artifact,
SharePoint itself does same too. Just have a detailed look at SharePointRoot (14,
12) folder and you will find many working examples there…
Nowadays, I am using Visual Studio 2010 and its development capabilities to facilitate
my learning. I will showcase it in this post. Role of Visual Studio in SharePoint
development is sadly decreasing. Sometimes it’s not needed to open VS for days or
even whole week to complete my development activities. I am not a techie coder but
I love VS and it saddens me seeing my beloved VS loosening its hold in SharePoint
development. I just can hope Microsoft not eliminating VS as a development tool
in future SharePoint versions. I do not want something I love to go away again….nobody
will…
In my attempts to give me chance to open VS, I decided to write some code to create
custom Information Management Policies for the content type/ list. As usual I started
reading the blogs about creating custom retention/ expiration policies, custom policy
formula, custom policy actions. I found two excellent code examples at below links
I also recommend to go through the MSDN documentation on Information Management
Policy.
In SharePoint, I always try to accomplish things declaratively rather than programmatically.
However, I was wondering whether there is any way to create a custom retention policy
declaratively rather than programmatically. I didn't find any declarative example
in my extensive googling. Hence I decided to give a try myself and to my surprise
I was successful too….all credits to reverse engineering capabilities of VS 2010.
Here are the steps.
1.
Create a Custom content type named as
ItemWithPolicy.
2.
Using browser, create a retention policy for
ItemWithPolicy content type as shown in figure 2 by clicking on Information
Management Policy Settings link.
3.
Save the site as site template with name
OOBPolicyExport.wsp and (make sure that Publishing features are deactivated.
Otherwise, you won’t find save as site template link in Site Settings page)
4.
Download the site template wsp from Solution gallery and store it in file
system.
5.
Create a new VS 2010 project named CreateCustomPolicy
using Import SharePoint Solution Package
project template. See the figure below.
6.
In project creation wizard, in Specify
the project source step, select the OOBPolicyExport.wsp
from file system and click Next
button.
7.
In Select items to import step,
first deselect all items and then select the
ItemWithPolicy content type item. Click
Finish and then No button.
8.
Visual studio will create the definition for ItemWithPolicy content type
as shown below. It contains declarative policy too.
<?xml version="1.0"
encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType ID="0x0100ED6AA2E224D2E849AC3315D40378E039"
Name="ItemWithPolicy"
Group="SharePoint
Custom Development"
Overwrite="TRUE" xmlns="http://schemas.microsoft.com/sharepoint/">
<Folder TargetName="_cts/ItemWithPolicy"
/>
<FieldRefs>
<FieldRef ID="{c042a256-787d-4a6f-8a8a-cf6ab767f12d}"
Name="ContentType" />
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}"
Name="Title"
Required="TRUE" ShowInNewForm="TRUE"
ShowInEditForm="TRUE" />
<FieldRef ID="{b0227f1a-b179-4d45-855b-a18f03706bcb}"
Name="_dlc_Exempt" Hidden="TRUE" />
<FieldRef ID="{74e6ae8a-0e3e-4dcb-bbff-b5a016d74d64}"
Name="_dlc_ExpireDateSaved"
Hidden="TRUE" />
<FieldRef ID="{acd16fdf-052f-40f7-bb7e-564c269c9fbc}"
Name="_dlc_ExpireDate" />
</FieldRefs>
<XmlDocuments>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/events">
<spe:Receivers xmlns:spe="http://schemas.microsoft.com/sharepoint/events">
<Receiver>
<Name>Microsoft.Office.RecordsManagement.PolicyFeatures.ExpirationEventReceiver</Name>
<Synchronization>Synchronous</Synchronization>
<Type>10001</Type>
<SequenceNumber>101</SequenceNumber>
<Assembly>Microsoft.Office.Policy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Class>Microsoft.Office.RecordsManagement.Internal.UpdateExpireDate</Class>
<Data />
<Filter />
</Receiver>
<Receiver>
<Name>Microsoft.Office.RecordsManagement.PolicyFeatures.ExpirationEventReceiver</Name>
<Synchronization>Synchronous</Synchronization>
<Type>10002</Type>
<SequenceNumber>102</SequenceNumber>
<Assembly>Microsoft.Office.Policy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Class>Microsoft.Office.RecordsManagement.Internal.UpdateExpireDate</Class>
<Data />
<Filter />
</Receiver>
<Receiver>
<Name>Microsoft.Office.RecordsManagement.PolicyFeatures.ExpirationEventReceiver</Name>
<Synchronization>Synchronous</Synchronization>
<Type>10004</Type>
<SequenceNumber>103</SequenceNumber>
<Assembly>Microsoft.Office.Policy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Class>Microsoft.Office.RecordsManagement.Internal.UpdateExpireDate</Class>
<Data />
<Filter />
</Receiver>
<Receiver>
<Name>Microsoft.Office.RecordsManagement.PolicyFeatures.ExpirationEventReceiver</Name>
<Synchronization>Synchronous</Synchronization>
<Type>10006</Type>
<SequenceNumber>104</SequenceNumber>
<Assembly>Microsoft.Office.Policy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Class>Microsoft.Office.RecordsManagement.Internal.UpdateExpireDate</Class>
<Data />
<Filter />
</Receiver>
<Receiver>
<Name>Microsoft.Office.RecordsManagement.PolicyFeatures.ExpirationEventReceiver</Name>
<Synchronization>Synchronous</Synchronization>
<Type>10009</Type>
<SequenceNumber>105</SequenceNumber>
<Assembly>Microsoft.Office.Policy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c</Assembly>
<Class>Microsoft.Office.RecordsManagement.Internal.UpdateExpireDate</Class>
<Data />
<Filter />
</Receiver>
</spe:Receivers>
</XmlDocument>
<XmlDocument NamespaceURI="office.server.policy">
<p:Policy xmlns:p="office.server.policy" id="" local="true">
<p:Name>ItemWithPolicy</p:Name>
<p:Description />
<p:Statement />
<p:PolicyItems>
<p:PolicyItem featureId="Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration" staticId="0x0100ED6AA2E224D2E849AC3315D40378E039|-1459032695" UniqueId="9c73ec8f-1cee-49d1-8604-558c24093f57">
<p:Name>Retention</p:Name>
<p:Description>Automatic scheduling of content for processing, and performing
a retention action on content that has reached its due date.</p:Description>
<p:CustomData>
<Schedules nextStageId="2">
<Schedule type="Default">
<stages>
<data stageId="1">
<formula id="Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn">
<number>1</number>
<property>Created</property>
<propertyId>8c06beca-0777-48f7-91c7-6da68bc07b69</propertyId>
<period>years</period>
</formula>
<action type="action"
id="Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.MoveToRecycleBin" />
</data>
</stages>
</Schedule>
</Schedules>
</p:CustomData>
</p:PolicyItem>
</p:PolicyItems>
</p:Policy>
</XmlDocument>
<XmlDocument NamespaceURI="microsoft.office.server.policy.changes">
<PolicyDirtyBag xmlns="microsoft.office.server.policy.changes">
<Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration op="Change" />
</PolicyDirtyBag>
</XmlDocument>
<XmlDocument NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<FormTemplates xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<Display>ListForm</Display>
<Edit>ListForm</Edit>
<New>ListForm</New>
</FormTemplates>
</XmlDocument>
</XmlDocuments>
</ContentType>
</Elements>
|
9.
Delete the ItemWithPolicy content
type from Site Content Type gallery
created through browser.
10. Add
a new List definition with content type
project item to project named Declarative Policy
Test List and select the ItemWithPolicy
content type as associated content type as shown in figure 4.
11. Change
the List Instance name as Declarative Policy
Test List Instance
12. Deploy
the VS project. It will create the list Declarative
Policy Test List with ItemWithPolicy
content type.
13. Go to
the Site content type gallery and check the Information Management Policy Settings
of ItemWithPolicy content type. It
should have a custom Retention policy created and it will be exactly same as that
of created in step 2.
Easy it is! I created multiple examples of this (multiple retention stages, policy
with schedule, auditing policy). They can be downloaded from here.
Important Notes:
1.
I was able to declaratively create custom policies for the Site Content types
only (content types present in Site Column gallery). Same was not true for the policies
created directly on List Content Types. Information management policy settings page
of such list content types gave me below error.
|
To me, this is a product bug. Even though I have not tried, I think creating List
content type based policies programmatically should be possible.
2.
Declaratively policies can be created when Source of Retention for a list
is set to Content Type (see figure 5).
You will need to programmatically create custom policies when retention source is
List or Folder. Declaratively there is no way. I am thinking that the reason is
Content type does have xmldocument
tag to declare custom policies but list schema does not have any such tags where
policies can be defined.
3.
This method also add event receivers and few columns to the content type. Do not remove them. I have seen SharePoint code (Mircosoft.Office.Policy.dll) in which I noticed that those columns are used. Same will be the case of event receivers.
That set! Hope this proves handy and a good read!
No comments:
Post a Comment