Inhaltstypen gehören zu den wohl interessantesten Elementen in der SharePoint-Entwicklung. Wie oft ist es Ihnen schon passiert, dass Sie einen Inhaltstypen ausgerollt haben, der Kunde zufrieden war und er dann in der nächsten Version gerne noch weitere Felder am Inhaltstypen haben möchte. Der alte Inhaltstyp läuft natürlich schon produktiv.

Abhilfe schafft hier die Aktualisierung einer Solution. Was sich bei anderen Elementen wie WebParts sehr einfach verhält, ist bei Inhaltstypen allerdings eine ganz andere Schwierigkeitsstufe. Denn hier müssen mehrere Fälle betrachtet werden.

Fall A: Aktualisierung des bestehenden Inhaltstypen auf einer Site

Fall B: Der Inhaltstyp muss auch auf Sites funktionieren in denen er bisher noch nicht vorhanden war

Fall C: Der Inhaltstyp muss zusätzlich in allen Listen aktualisiert werden

Zusatz: Natürlich wäre es schön, dass wenn man das neue Wsp in eine neue Farm installiert der Inhaltstyp komplett vorhanden ist und nicht erst alle Upgrades durchgeführt werden müssen.

Ich habe mich dabei auf folgenden Artikel gestützt, der eine gute Übersicht bietet: http://charliedigital.com/2011/05/03/sharepoint-content-type-lifecycle-management/

Aber am besten das Ganze an einem Beispiel.

Ich habe einen Inhaltstypen und möchte zwei neue Felder hinzufügen. Der Inhaltstyp wird schon produktiv genutzt. Ich muss also alle obigen Fälle mit einbeziehen.

Laut MSDN (http://msdn.microsoft.com/en-us/library/gg604045.aspx)  muss

  1. Der Lösung muss eine neue Element-Datei hinzugefügt werden. In dieser Datei werden die neuen Felder definiert.
  2. In der Template.xml muss eine UpgradeAction des Features erstellt werden. Diese muss ApplyFeatureManifest und AddContentTypeField enthalten. Mit diesem und dem ersten Schritt wird Fall A abgedeckt.
  3. Die existierende Element-Datei des Inhaltstypen muss angepasst werden. Damit wird Fall B abgedeckt.

Klingt gut! Aber leider wird nun Fall C nicht mehr abgedeckt, da die zusätzlichen Felder nicht an die Liste übertragen werden, wenn sie in beiden Element-Dateien hinzugefügt werden. Also haben sie die Wahl zwischen Keine Aktualisierung der Listen oder sie lassen Schritt 3 weg und können damit Fall C abdecken. Dann entsteht aber der Nachteil das der Fall unter Zusatz nicht abgedeckt wird.

Die Lösung ist im obigen Artikel beschrieben. Man erstelle für die UpgradeAction einen Eventreceiver, welcher die Listen aktualisiert.

Hier nun Schritt für Schritt:

Schritt 1: Die neue Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements Id="…" xmlns="http://schemas.microsoft.com/sharepoint/">
  <!-- Fields for Content Type Version 1.0.0.1 -->
  <Field ID="{GuidFieldA}" Type="Text" Group="…." Name="FieldA" 
         DisplayName="…" 
         StaticName="…" Hidden="FALSE" ReadOnly="TRUE" Overwrite="TRUE" OverwriteInChildScopes="TRUE" />
  <Field ID="{GuidFieldB}" Type="Text" Group="…" Name="FieldB" 
         DisplayName="…" 
         StaticName="…" Hidden="FALSE" ReadOnly="TRUE" Overwrite="TRUE" OverwriteInChildScopes="TRUE" />
</Elements>

Schritt 2: Die UpgradeAction in der Template.xml

Sollten Sie in Ihrem bestehenden Feature keine Version angegeben haben, können Sie das Attribut für BeginVersion auch weglassen. Die Parameter werden für den Eventreceiver benötigt. Hier übergebe ich die Guid vom Inhaltstypen und die Guid von dem neuen Feld.

<UpgradeActions ReceiverAssembly="HanseVision.Asklepios.SharePoint…., Version=1.0.0.0, Culture=neutral, PublicKeyToken=…" ReceiverClass="HanseVision.Asklepios.SharePoint..Receiver.ContentTypeUpgrader"> <VersionRange BeginVersion="1.0.0.0" EndVersion="1.0.0.1"> <ApplyElementManifests> <ElementManifest Location="FolderName\Elements_1.0.0.1.xml"/> </ApplyElementManifests> <AddContentTypeField ContentTypeId="GuidContentType" FieldId="{GuidFieldA}" PushDown="TRUE"/> <AddContentTypeField ContentTypeId="GuidContentType" FieldId="{GuidFieldB}" PushDown="TRUE"/> <CustomUpgradeAction Name="AddFields"> <Parameters> <Parameter Name="add.field.1">GuidContentType,{GuidFieldA}</Parameter> <Parameter Name="add.field.2">GuidContentType,{GuidFieldB}</Parameter> </Parameters> </CustomUpgradeAction> </VersionRange> </UpgradeActions>

Schritt 3: Bitte fügen Sie das Feld in den Inhaltstypen ein.

Schritt 4: Eventreceiver für die UpgradeAction

public class ContentTypeUpgrader : SPFeatureReceiver { public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, IDictionary&lt;string, string&gt; parameters) { if (upgradeActionName.ToUpperInvariant() != "ADDFIELDS") { base.FeatureUpgrading(properties, upgradeActionName, parameters); return; } try { SPSite site = properties.Feature.Parent as SPSite; using (SPWeb web = site.RootWeb) { web.AllowUnsafeUpdates = true; foreach (string key in parameters.Keys) { // Iterate and split each content type, field value. string value = parameters[key]; string[] parts = value.Split(','); SPContentTypeId contentTypeId = new SPContentTypeId(parts[0]); Guid fieldId = new Guid(parts[1]); SPField field = web.Fields[fieldId]; SPFieldLink fieldLink = new SPFieldLink(field); SPContentType contentType = web.ContentTypes[contentTypeId]; LoggingService.LogDebug(String.Format("Adding field \"{0}\" to content type \"{1}\".", field.Title, contentType.Name)); contentType.FieldLinks.Delete(fieldId); contentType.Update(true); contentType.FieldLinks.Add(fieldLink); contentType.Update(true); } web.AllowUnsafeUpdates = false; } } catch (Exception ex) { LoggingService.LogError(ex); } base.FeatureUpgrading(properties, upgradeActionName, parameters); } }

Nachdem Sie dies in Ihre Lösung integriert haben, müssen Sie beim Bereitstellen der Lösung zunächst ein UpgradeSolution (Powershell)  oder ein Update über stsadm machen. Anschließend sollten Sie ein Upgrade des Features durchführen. Hierzu können Sie folgendes Powershellskript benutzen:

    "Start UpgradeActions in Features"
    $featureGuid = New-Object System.Guid($featureId) 

    $webApp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($webAppUrl)
    $features = $webApp.QueryFeatures($featureGuid, $true) 

    foreach($feature in $features)
    {  
        Write-Host ("Updgrading feature " + $feature.Definition.Name + " in " + $feature.Parent.Url)  
        $feature.Upgrade($true)
    }

Wenn Sie diese Schritte befolgen, werden Sie Ihren Inhaltstypen erfolgreich aktualisieren können.

1 Comments

  1. Pingback: Aus der Praxis – Sie wollen einen Inhaltstypen aktualisieren - SharePoint Blogs in German - Bamboo Nation

Leave a comment

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload the CAPTCHA.