{"id":5096,"date":"2018-03-01T16:37:01","date_gmt":"2018-03-01T15:37:01","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=5096"},"modified":"2023-09-11T09:31:31","modified_gmt":"2023-09-11T07:31:31","slug":"sharepoint-retention-policies","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/sharepoint-retention-policies\/","title":{"rendered":"SharePoint Retention Policies"},"content":{"rendered":"\n<p>W rozwi\u0105zaniach SharePoint zosta\u0142o wbudowanych wiele mechanizm\u00f3w, kt\u00f3re z za\u0142o\u017cenia maj\u0105 u\u0142atwia\u0107 zarz\u0105dzanie informacj\u0105. Jednym z tych mechanizm\u00f3w jest \u201eSharePoint Retention Policies\u201d. W artykule zosta\u0142 opisany spos\u00f3b jego konfiguracji z poziomu u\u017cytkownika (za pomoc\u0105 przegl\u0105darki), jak r\u00f3wnie\u017c z kodu serwerowego z wykorzystaniem API SharePointa. Ponadto zosta\u0142o r\u00f3wnie\u017c om\u00f3wione, jak z kodu utworzy\u0107 w\u0142asne zdarzenie i akcje w Retention Policies.<\/p>\n\n\n\n<p>Zasady zarz\u0105dzania informacj\u0105 (SharePoint Retention Policies) umo\u017cliwiaj\u0105 planowanie tego, co ma si\u0119 wydarzy\u0107 z elementami listy b\u0105d\u017a dokumentami po spe\u0142nieniu ustalonych uprzednio warunk\u00f3w &#8211; zdarze\u0144. Dla lepszego zrozumienia tematu, jako przyk\u0142ad, mo\u017cemy wskaza\u0107 potrzeb\u0119 utworzenia regu\u0142y, kt\u00f3ra definiuje, \u017ce wszystkie dokumenty po 2 latach od ich utworzenia nale\u017cy przenie\u015b\u0107 do innej lokalizacji.<br>Dzi\u0119ki wykorzystaniu \u201eZasad zarz\u0105dzania informacj\u0105\u201d mo\u017cemy w \u0142atwy spos\u00f3b wyegzekwowa\u0107 zgodno\u015bci naszego \u015brodowiska z prawem lub wewn\u0119trznymi procesami biznesowymi.<\/p>\n\n\n\n<p>Standardowo wyzwalaczami akcji, definiowanej przez polityk\u0119, jest przekroczenie daty, kt\u00f3ra jest tworzona z daty pobieranej z jednego z p\u00f3l elementu do kt\u00f3rej jest dodawana okre\u015blona liczba dni, miesi\u0119cy albo lat. Pole, kt\u00f3re mo\u017cna wykorzysta\u0107 do tworzenia takiej daty, mo\u017ce by\u0107 dowolnym polem typu \u201eDateTime\u201d.<br>Opr\u00f3cz opisanego powy\u017cej sposobu definiowania wyzwalacza akcji mo\u017cna programistycznie utworzy\u0107 w\u0142asny warunek (opisany w dalszej cz\u0119\u015bci artyku\u0142u), w kt\u00f3rym mo\u017cemy zdefiniowa\u0107 w\u0142asn\u0105 logik\u0119 dzia\u0142ania.<br>Weryfikacja, czy dla danego elementu zosta\u0142y spe\u0142nione warunki uruchomienia regu\u0142y, odbywa si\u0119 przez zadanie o nazwie \u201eExpiration policy\u201d. Zadanie to jest standardowo uruchamiane raz w tygodniu.<br>Standardowe akcje, kt\u00f3re s\u0105 dost\u0119pne podczas tworzenia polityki to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Move to Recyle Bin<\/li>\n\n\n\n<li>Permanently Delete<\/li>\n\n\n\n<li>Transfer to another location<\/li>\n\n\n\n<li>Start a workflow<\/li>\n\n\n\n<li>Skip to next stage<\/li>\n\n\n\n<li>Delete previous drafts<\/li>\n\n\n\n<li>Delete all previous versions<\/li>\n<\/ul>\n\n\n\n<p>Istnieje r\u00f3wnie\u017c mo\u017cliwo\u015b\u0107 programistycznego utworzenia w\u0142asnej akcji (zostanie to opisane w dalszej cz\u0119\u015bci artyku\u0142u).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Konfiguracja Polityki zarz\u0105dzania za pomoc\u0105 Interfejsu przegl\u0105darkowego<\/h2>\n\n\n\n<p>Warunkiem koniecznym do tego by mo\u017cna by\u0142o korzysta\u0107 z \u201eSharePoint Retention Policies\u201d jest w\u0142\u0105czony na poziomie kolekcji witryn Feature o nazwie: \u201eSite Policy\u201d.<br>Polityk\u0119 zarz\u0105dzania informacj\u0105 mo\u017cna skonfigurowa\u0107 na trzy poni\u017csze sposoby:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Utworzenie polityki w kolekcji polityk (na poziomie kolekcji witryn) &#8211; W celu utworzenia takiej policy nale\u017cy z ustawie\u0144 g\u0142\u00f3wnej witryny wybra\u0107 \u201eContent Type Policy Templates\u201d, kt\u00f3ry to link powinien nas przenie\u015b\u0107 do strony o wygl\u0105dzie jak na poni\u017cszym rysunku.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Polices.png\"><img decoding=\"async\" width=\"840\" height=\"271\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Polices.png\" alt=\"Policies\" class=\"wp-image-23984\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Polices.png 840w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Polices-300x97.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/Polices-768x248.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure>\n\n\n\n<p>Na powy\u017cszej stronie s\u0105 wy\u015bwietlone utworzone ju\u017c polityki, jak r\u00f3wnie\u017c istnieje mo\u017cliwo\u015b\u0107 utworzenia nowej (link \u201eCreate\u201d). Utworzon\u0105 w tym miejscu polityk\u0119 b\u0119dzie mo\u017cna wykorzysta\u0107 w dowolnym \u201eContent Type\u201d lub bezpo\u015brednio u\u017cy\u0107 w konfiguracji polityk dla bibliotek b\u0105d\u017a list.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Utworzenie polityki dla danego kontent typu &#8211; Aby utworzy\u0107\/pod\u0142\u0105czy\u0107 polityk\u0119 do Content Type nale\u017cy otworzy\u0107 stron\u0119 ustawie\u0144 Content Typu. Z tej strony nale\u017cy przej\u015b\u0107 do linku \u201eInformation managment policy setting\u201d &#8211; powinna otworzy\u0107 si\u0119 strona jak poni\u017csza.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/PolicySettings.png\"><img decoding=\"async\" width=\"840\" height=\"269\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/PolicySettings.png\" alt=\"Information Management Policy Settings\" class=\"wp-image-23988\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/PolicySettings.png 840w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/PolicySettings-300x96.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2023\/09\/PolicySettings-768x246.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure>\n\n\n\n<p>Na powy\u017cszej stronie mo\u017cna wybra\u0107 jedn\u0105 z wcze\u015bniej zdefiniowanych polityk (opcja \u201eUse a site collection policy\u201d) albo utworzy\u0107 now\u0105 polityk\u0119, kt\u00f3ra b\u0119dzie wykorzystywana tylko przez ten Content Type (opcja \u201eDefine a policy\u2026\u201d). Wybranie opcji \u201eDefine a policy\u2026\u201d spowoduje otworzenie strony z definicj\u0105 nowej polityki.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Utworzenie polityki dla listy b\u0105d\u017a biblioteki &#8211; W celu skonfigurowania polityki bezpo\u015brednio dla listy\/biblioteki nale\u017cy przej\u015b\u0107 na stron\u0119 ustawie\u0144 listy i wybra\u0107 link \u201eInformation management policy settings\u201d, powinna wy\u015bwietli\u0107 si\u0119 strona z kt\u00f3rej wybieramy, czy chcemy definiowa\u0107 polityk\u0119 dla element\u00f3w (Item) czy dla folder\u00f3w (Folder), tak jak na poni\u017cszym rysunku.<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/03\/PolicyLibrarySetting.png\"><img decoding=\"async\" width=\"840\" height=\"269\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/03\/PolicyLibrarySetting.png\" alt=\"Settings\" class=\"wp-image-23986\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/03\/PolicyLibrarySetting.png 840w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/03\/PolicyLibrarySetting-300x96.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/03\/PolicyLibrarySetting-768x246.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure>\n\n\n\n<p>Po wybraniu jednej z opcji istnieje, tak jak w przypadku konfiguracji polityki Content Type, mo\u017cliwo\u015b\u0107 utworzenia nowej polityki (opcja \u201eDefine a policy\u2026\u201d) albo pod\u0142\u0105czenia do jednej z ju\u017c istniej\u0105cych (opcja \u201eUse a site collection policy\u201d)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utworzenie polityki z API serwerowego SharePoint<\/h2>\n\n\n\n<p>Polityk\u0119 Zarz\u0105dzania Informacj\u0105, opr\u00f3cz sposobu tworzenia przez przegl\u0105dark\u0119 (opisanego w punkcie 2) mo\u017cna r\u00f3wnie\u017c utworzy\u0107 z kodu serwerowego. W celu zobrazowania tej metody poni\u017cej zosta\u0142 pokazany kod, kt\u00f3ry tworzy polityk\u0119 dla Content Type o nazwie &#8222;ContentName&#8221;.<br>W pierwszej kolejno\u015bci powinni\u015bmy pobra\u0107 polityk\u0119 dla danego Content Typu.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nSPContentType ct = web.ContentTypes&#x5B;\"ContentName\"];\nPolicy policy = Policy.GetPolicy(ct);\n<\/pre><\/div>\n\n\n<p>W przypadku gdy do Content Typu nie jest pod\u0142\u0105czona \u017cadna polityka, nale\u017cy j\u0105 utworzy\u0107.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nPolicy.CreatePolicy(ct,null);\nct.Update();\npolicy = Policy.GetPolicy(ct);\npolicy.Statement = \"to jest opis\";\npolicy.Update();\n<\/pre><\/div>\n\n\n<p>Po pobraniu polityki, mo\u017cna do niej doda\u0107 zdarzenie i akcje, kt\u00f3re maj\u0105 by\u0107 przez ni\u0105 wykorzystywane. Definicja polityki jest konfigurowalna za pomoc\u0105 XML, tak jak w poni\u017cszym kodzie.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\n&quot;&lt;Schedules nextStageId \\&quot;2\\&quot;&gt;\n   &lt;Schedule type=\\&quot;Default\\&quot;&gt;\n      &lt;stages&gt;\n         &lt;data stageId=\\&quot;1\\&quot;&gt;\n            &lt;formula id=\\&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn\\&quot;&gt;\n               &lt;number&gt;36&lt;\/number&gt;\n               &lt;property&gt;Created&lt;\/property&gt;\n               &lt;propertyId&gt;8c06beca-0777-48f7-91c7-6da68bc07b69&lt;\/propertyId&gt;\n               &lt;period&gt;days&lt;\/period&gt;\n            &lt;\/formula&gt;\n            &lt;action type=\\&quot;action\\&quot; id=\\&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.MoveToRecycleBin\\&quot; \/&gt;\n         &lt;\/data&gt;\n      &lt;\/stages&gt;\n   &lt;\/Schedule&gt;\n&lt;\/Schedules&gt;&quot;;\n<\/pre><\/div>\n\n\n<p>Powy\u017cszy kod definiuje polityk\u0119, kt\u00f3ra uruchomi si\u0119 36 dni po utworzeniu elementu i wykona akcj\u0119 polegaj\u0105c\u0105 na przeniesieniu elementu do kosza. Ca\u0142o\u015b\u0107 kodu tworz\u0105ca now\u0105 polityk\u0119 zosta\u0142a zebrana poni\u017cej.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nusing Microsoft.SharePoint;\nusing Microsoft.SharePoint.Administration;\nusing Microsoft.Office.RecordsManagement.InformationPolicy;\n...\n   using (SPSite site = new SPSite(&quot;http:\/\/siteUrl&quot;))\n   {\n      using (SPWeb web = site.OpenWeb(&quot;&quot;))\n      {\n         SPContentType ct = web.ContentTypes&#x5B;&quot;ContentName&quot;];\n         Policy policy = Policy.GetPolicy(ct);\n         if (policy==null)\n         {\n            Policy.CreatePolicy(ct,null);\n            ct.Update();\n            policy = Policy.GetPolicy(ct);\n            policy.Statement = &quot;to jest opis&quot;;\n            policy.Update();\n         }\n         string policyCustomData= &quot;&lt;Schedules nextStageId \\&quot;2\\&quot;&gt;\n         &lt;Schedule type=\\&quot;Default\\&quot;&gt;\n            &lt;stages&gt;\n            &lt;data stageId=\\&quot;1\\&quot;&gt;\n                  &lt;formula id=\\&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Formula.BuiltIn\\&quot;&gt;\n                     &lt;number&gt;36&lt;\/number&gt;\n                     &lt;property&gt;Created&lt;\/property&gt;\n                     &lt;propertyId&gt;8c06beca-0777-48f7-91c7-6da68bc07b69&lt;\/propertyId&gt;\n                     &lt;period&gt;days&lt;\/period&gt;\n                  &lt;\/formula&gt;\n                  &lt;action type=\\&quot;action\\&quot; id=\\&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration.Action.MoveToRecycleBin\\&quot; \/&gt;\n               &lt;\/data&gt;\n            &lt;\/stages&gt;\n         &lt;\/Schedule&gt;\n      &lt;\/Schedules&gt;&quot;;\n      policy.Items.Add(&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration&quot;, policyCustomData);\n      policy.Update(); }\n    }\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Utworzenie w\u0142asnego zdarzenia polityki (API serwera SharePoint)<\/h2>\n\n\n\n<p>W celu utworzenia w\u0142asnego zdarzenia polityki nale\u017cy z pomoc\u0105 Visual Studio utworzy\u0107 nowy pusty projekt SharePointowy, w kt\u00f3rym \u201eTrust Level\u201d zosta\u0142 ustawiony jako \u201eDeploy as a farm solution\u201d. Do projektu nale\u017cy doda\u0107 referencje &#8222;Microsoft.Office.Policy&#8221;.<br>W projekcie nale\u017cy utworzy\u0107 klas\u0119, kt\u00f3ra b\u0119dzie odpowiedzialna za implementacje metody sprawdzenia i wywo\u0142ania zdarzenia, w naszym przyk\u0142adzie b\u0119dzie to klasa o nazwie \u201eCustomExpiration\u201d. Do klasy nale\u017cy doda\u0107 przestrze\u0144 nazw <em>Microsoft.Office.RecordsManagement.PolicyFeatures<\/em>. Klasa musi implementowa\u0107 interfejs IExpirationFormula, kt\u00f3ry wymusza implementacje metody ComputeExpireDate. Metoda ComputeExpireDate powinna zwraca\u0107 dat\u0119 w przypadku gdy zdarzenie ma zosta\u0107 wygenerowane, w przeciwnym przypadku powinna zwraca\u0107 null. W poni\u017cszym kodzie zosta\u0142a zaimplementowana logika, kt\u00f3ry sprawdza czy pole o nazwie \u201eStatus\u201d ma warto\u015b\u0107 \u201eDelete\u201d, je\u015bli tak to zdarzenie jest generowane. Poni\u017cej kod klasy wraz z metod\u0105 ComputeExpireDate.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nnamespace CustomExpiration\n{\n   class MyCustomExpiration: IExpirationFormula\n   {\n      public Nullable&lt;DateTime&gt; ComputeExpireDate(SPListItem item, System.Xml.XmlNode parametersData)\n      {\n         DateTime? expirationStatus = null;\n         if (item&#x5B;&quot;Status&quot;] != null &amp;&amp; (!string.IsNullOrEmpty(item&#x5B;&quot;Status&quot;].ToString())))\n         {\n            if (item&#x5B;&quot;Status&quot;].ToString() == &quot;Delete&quot;)\n               expirationStatus = DateTime.Now;\n         }\n         return expirationStatus;\n      }\n   }\n}\n<\/pre><\/div>\n\n\n<p>Po utworzeniu klasy implementuj\u0105cej interfejs IExpirationFormula nale\u017cy zarejestrowa\u0107 nowe zdarzenie w PolicyResourceCollection. Do tego celu, mo\u017cemy wykorzysta\u0107 Feature ze Scope ustawionym na poziomie farmy. W feature tym nale\u017cy zdefiniowa\u0107 Event Receiver, kt\u00f3ry powinien implementowa\u0107 zdarzenie FeatureActivated tak jak w poni\u017cszym kodzie.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\npublic override void FeatureActivated(SPFeatureReceiverProperties properties)\n{\n   string expirationFormulaID = &quot;CustomExpirationFormula&quot;;\n   string expirationFormulaName = &quot;Moja formula wygasania&quot;;\n   string expirationFormulaDesc = &quot;Moja formula wygasania&quot;;\n   string xmlExpirationFormula = &quot;&lt;PolicyResource xmlns=\\&quot;urn:schemas-microsoft-com:office:server:policy\\&quot;&quot; + &quot; id = \\&quot;&quot; + expirationFormulaID + &quot;\\&quot;&quot; + &quot; featureId=\\&quot;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration\\&quot;&quot; + &quot; type = \\&quot;DateCalculator\\&quot;&gt;\n      &quot;&lt;Name&gt;&quot; + (expirationFormulaName) + &quot;&lt;\/Name&gt;&quot; +\n      &quot;&lt;Description&gt;&quot; + (expirationFormulaDesc) + &quot;&lt;\/Description&gt;&quot; +\n      &quot;&lt;AssemblyName&gt;CustomExpiration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=88bf3ea84224a2b8&lt;\/AssemblyName&gt;&quot; +\n      &quot;&lt;ClassName&gt;CustomExpiration.MyCustomExpiration&lt;\/ClassName&gt;&quot; +\n   &quot;&lt;\/PolicyResource&gt;&quot;;\n   try\n   {\n      PolicyResourceCollection.Delete(expirationFormulaID);\n   }\n   catch (Exception ex)\n   {\n   }\n   PolicyResource.ValidateManifest(xmlExpirationFormula);\n   PolicyResourceCollection.Add(xmlExpirationFormula);\n}\n<\/pre><\/div>\n\n\n<p>Nale\u017cy zwr\u00f3ci\u0107 uwag\u0119 na prawid\u0142ow\u0105 warto\u015b\u0107 tag\u00f3w AssemblyName oraz ClassName, kt\u00f3re b\u0119d\u0105 inne ni\u017c w przyk\u0142adowym kodzie.<br>Po skompilowaniu projektu i jego wdro\u017ceniu powinni\u015bmy mie\u0107 mo\u017cliwo\u015b\u0107 skorzystania z nowego zdarzenia. Zdarzenie b\u0119dzie si\u0119 uruchamia\u0142o, gdy element na kt\u00f3rym jest zdefiniowana polityka b\u0119dzie posiada\u0142 pole o nazwie \u201eStatus\u201d i to pole b\u0119dzie mia\u0142o przypisan\u0105 warto\u015b\u0107 \u201eDelete\u201d.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Utworzenie w\u0142asnej akcji polityki (API serwera SharePoint)<\/h2>\n\n\n\n<p>W celu utworzenia w\u0142asnej akcji polityki wykorzystamy utworzony w poprzednim punkcie projekt SharePointowy. Do projektu nale\u017cy doda\u0107 klas\u0119, kt\u00f3ra w naszym przyk\u0142adzie b\u0119dzie mia\u0142a nazw\u0119 CustomExpirationAction. Klasa powinna implementowa\u0107 interfejs IExpirationAction, kt\u00f3ry posiada metod\u0119 OnExpiration. W naszym przyk\u0142adzie utworzymy prost\u0105 akcj\u0119, kt\u00f3ra b\u0119dzie przypisywa\u0142a do pola \u201eTitle\u201d dat\u0119 wyst\u0105pienia zdarzenia. Metoda powinna mie\u0107 wi\u0119c nast\u0119puj\u0105c\u0105 tre\u015b\u0107:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\npublic void OnExpiration(SPListItem item, XmlNode parametersData, DateTime expiredDate)\n{\n   item&#x5B;\"Title\"] = expiredDate.ToString();\n   item.Update();\n}\n<\/pre><\/div>\n\n\n<p>Gdy mamy ju\u017c utworzon\u0105 klas\u0119, odpowiedzialn\u0105 za wykonanie akcji, nale\u017cy akcj\u0119 doda\u0107 do kolekcji PolicyResourceCollection, w kt\u00f3rej s\u0105 przechowywane zdarzenia i akcje.<br>Czynno\u015b\u0107 t\u0119 mo\u017cna wykona\u0107 w analogiczny spos\u00f3b jak w przypadku rejestracji zdarzenia. Kod rejestracji akcji nale\u017cy wi\u0119c doda\u0107 do Event Receiver Featura (po kodzie rejestruj\u0105cym zdarzenie).<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: xml; title: ; notranslate\" title=\"\">\nstring expirationActionFormulaID = &quot;CustomExpirationAction&quot;;\nstring expirationActionFormulaName = &quot;Moja akcja name&quot;;\nstring expirationActionFormulaDesc = &quot;Moja akcja desc&quot;;\nstring xmlManifestAction = &quot;&lt;PolicyResource xmlns=&#039;urn:schemas-microsoft-com:office:server:policy&#039;&quot; + &quot; id = \\&quot;&quot; + expirationActionFormulaID + &quot;\\&quot;&quot; + &quot; featureId=&#039;Microsoft.Office.RecordsManagement.PolicyFeatures.Expiration&#039;&quot; + &quot; type=&#039;Action&#039;&gt;&quot; +\n      &quot;&lt;Name&gt;&quot; + (expirationActionFormulaName) + &quot;&lt;\/Name&gt;&quot; +\n      &quot;&lt;Description&gt;&quot; + (expirationActionFormulaDesc) + &quot;&lt;\/Description&gt;&quot; +\n      &quot;&lt;AssemblyName&gt;CustomExpiration, Version=1.0.0.0, Culture=neutral, PublicKeyToken=88bf3ea84224a2b8&lt;\/AssemblyName&gt;&quot; +\n      &quot;&lt;ClassName&gt;CustomExpiration.CustomExpirationAction&lt;\/ClassName&gt;&quot; +\n   &quot;&lt;\/PolicyResource&gt;&quot;;\ntry\n{\n   PolicyResourceCollection.Delete(expirationActionFormulaID);\n}\ncatch (Exception ex)\n{\n}\nPolicyResource.ValidateManifest(xmlManifestAction);\nPolicyResourceCollection.Add(xmlManifestAction);\n<\/pre><\/div>\n\n\n<p>Nale\u017cy zwr\u00f3ci\u0107 uwag\u0119 na prawid\u0142ow\u0105 warto\u015b\u0107 tag\u00f3w AssemblyName oraz ClassName, kt\u00f3re b\u0119d\u0105 inne ni\u017c w przyk\u0142adowym kodzie.<br>Po skompilowaniu projektu i wdro\u017ceniu rozwi\u0105zania mo\u017cna ju\u017c korzysta\u0107 z nowo dodanej akcji.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie<\/h2>\n\n\n\n<p>Mechanizm \u201eSharePoint Retention Policies\u201d jest elastycznym rozwi\u0105zaniem umo\u017cliwiaj\u0105cym egzekwowanie regu\u0142 dotycz\u0105cych przechowywanych informacji w SharePoint. Wbudowane zdarzenia i akcje umo\u017cliwiaj\u0105 tworzenie polityk, kt\u00f3re powinny sprosta\u0107 wi\u0119kszo\u015bci wymaga\u0144. Jednak w przypadku potrzeb, kt\u00f3re wykraczaj\u0105 poza wbudowane elementy, istniej prosta mo\u017cliwo\u015b\u0107 tworzenia nowych zdarze\u0144 (wyzwalaczy) i akcji.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;5096&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;2&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.5&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.5\\\/5 ( votes: 2)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;SharePoint Retention Policies&quot;,&quot;width&quot;:&quot;125&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 125px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.5\/5 ( votes: 2)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>W rozwi\u0105zaniach SharePoint zosta\u0142o wbudowanych wiele mechanizm\u00f3w, kt\u00f3re z za\u0142o\u017cenia maj\u0105 u\u0142atwia\u0107 zarz\u0105dzanie informacj\u0105. Jednym z tych mechanizm\u00f3w jest \u201eSharePoint &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/sharepoint-retention-policies\/\">Continued<\/a><\/p>\n","protected":false},"author":150,"featured_media":5138,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[56],"class_list":["post-5096","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-sharepoint"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2018\/02\/Rules.png","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/5096"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/150"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=5096"}],"version-history":[{"count":2,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/5096\/revisions"}],"predecessor-version":[{"id":23990,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/5096\/revisions\/23990"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/5138"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=5096"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=5096"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=5096"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}