Ersetzen von SharePoint-Dateien, die mithilfe von Modulen in Farmlösungen bereitgestellt wurden
Wenn Sie Dateien deklarativ mithilfe von Modulen in Farmlösungen bereitgestellt haben, erfahren Sie, wie Sie sie in neue Lösungen transformieren, die Verweise auf Dateien aktualisieren und ähnliche Funktionen mithilfe des Clientobjektmodells (CSOM) bereitstellen. In der Vergangenheit wurden Module verwendet, um Dateien wie master Seiten und Seitenlayouts bereitzustellen.
Wichtig
Farm-Lösungen können nicht zu SharePoint Online migriert werden. Durch Anwenden der in diesem Artikel beschriebenen Techniken und Code können Sie eine neue Lösung mit ähnlichen Funktionen wie ihre Farmlösungen erstellen, Verweise auf Dateien aktualisieren und dann die neue Lösung in SharePoint Online bereitstellen. Anschließend können Sie das Feature deaktivieren und die vorherige Farmlösung zurückziehen.
Der Code in diesem Artikel erfordert zusätzlichen Code für die Bereitstellung einer vollständig funktionierenden Lösung. In diesem Artikel wird beispielsweise nicht erläutert, wie die Authentifizierung bei Office 365 erfolgt, wie die erforderliche Ausnahmebehandlung implementiert wird usw. Weitere Codebeispiele, finden Sie unter Office 365 Developer Patterns and Practices Project.
Hinweis
Der Code in diesem Artikel wird wie besehen und ohne jegliche Garantie zur Verfügung gestellt, gleich ob ausdrücklich oder konkludent, einschließlich jedweder stillschweigenden Gewährleistung der Eignung für einen bestimmten Zweck, Marktgängigkeit oder Nichtverletzung von Rechten.
In diesem Artikel wird beschrieben, wie Sie den Transformationsprozess für Folgendes verwenden:
- Hochladen und Aktualisieren von Verweisen auf master Seiten
- Hochladen und Aktualisieren von Verweisen auf Seitenlayouts
Verwenden Sie diesen Transformationsprozess in folgenden Fällen:
- Ihre vorhandenen Farmlösungen verwendeten Module zum Bereitstellen von Dateien.
- Sie möchten master Seiten und Seitenlayouts in Farmlösungen durch neue master Seiten und Seitenlayouts ersetzen, damit sie zu SharePoint Online migriert werden können.
- Sie haben Dokumentinhaltstypen auf master Seiten oder Seitenlayouts in Ihrer Farmlösung deklarativ festgelegt.
Bevor Sie beginnen
Im Idealfall sollten Sie Ihre vorhandenen Farmlösungen überprüfen, sich über die in diesem Artikel beschriebenen Techniken informieren und dann planen, wie Sie diese Techniken auf Ihre Szenarien anwenden. Wenn Sie mit Farmlösungen nicht vertraut sind oder nicht über eine vorhandene Farmlösung verfügen, mit der Sie arbeiten können, kann es hilfreich sein, sich über Farmlösungen zu informieren.
Weitere Informationen finden Sie unter Erstellen von Farmlösungen in SharePoint.
Aktivieren der Veröffentlichungsfeatures für die Websitesammlung und website
Aktivieren Sie vor dem Ausführen des Codebeispiels die Veröffentlichungsfeatures für die Websitesammlung und website mit den folgenden Verfahren.
So aktivieren Sie das SharePoint Server-Veröffentlichungsinfrastrukturfeature für die Websitesammlung
Öffnen Sie Ihre SharePoint-Website, und wechseln Sie zu Einstellungen>Websiteeinstellungen.
Wählen Sie unter Websitesammlungsverwaltungdie Option Websitesammlungsfeatures aus.
Wählen Sie unter SharePoint Server-Veröffentlichungsinfrastrukturdie Option Aktivieren aus.
So aktivieren Sie das SharePoint Server-Veröffentlichungsfeature auf der Website
Öffnen Sie Ihre SharePoint-Website, und wechseln Sie zu Einstellungen>Websiteeinstellungen.
Wählen Sie unter Websiteaktionen die Option Websitefeatures verwalten aus.
Wählen Sie unter SharePoint Server-Veröffentlichung die Option Aktivieren aus.
Einrichten ihres Visual Studio-Projekts
Laden Sie das Beispielprojekt herunter. Wählen Sie Unformatiert anzeigen aus, um mit dem Herunterladen des Beispielprojekts zu beginnen, die Dateien aus der ZIP-Datei zu extrahieren und dann zum Ordner Module9/ModuleReplacement zu navigieren.
Öffnen Sie ModuleReplacement.sln.
Öffnen Sie settings.xml. Überprüfen und aktualisieren Sie die folgenden Attribute, um Ihre Anforderungen zu erfüllen:
masterPage-Element: Verwendet das datei-Attribut, um die neue master-Seite anzugeben, die im Gestaltungsvorlagenkatalog bereitgestellt werden soll, und das replaces-Attribut, um die vorhandene master Seite im Gestaltungsvorlagenkatalog anzugeben.
pageLayout-Element : Verwendet das File-Attribut , um die neue Seitenlayoutdatei anzugeben, das replaces-Attribut , um die vorhandene Seitenlayoutdatei anzugeben, und mehrere andere Attribute, um zusätzliche Seitenlayoutinformationen anzugeben.
<?xml version="1.0" encoding="utf-8" ?> <branding> <masterPages> <masterPage file="contoso_app.master" replaces="contoso.master"/> </masterPages> <pageLayouts> <pageLayout file="ContosoWelcomeLinksApp.aspx" replaces="ContosoWelcomeLinks.aspx" title="Contoso Welcome Links add-in" associatedContentTypeName="Contoso Web Page" defaultLayout="true" /> </pageLayouts> </branding>
In MasterPageGalleryFiles.cs definieren die Klassen MasterPageGalleryFile und LayoutFile Geschäftsobjekte, die Informationen zu den neuen master Seiten und Seitenlayouts speichern, die in SharePoint hochgeladen werden sollen.
Hochladen und Aktualisieren von Verweisen auf master Seiten
So laden Sie Verweise auf die neuen master-Seiten auf Ihrer SharePoint-Website hoch und aktualisieren sie:
Fügen Sie in Program.cs die folgende using-Anweisung hinzu.
using System.Security;
Fügen Sie in Program.cs die folgenden Methoden hinzu, um die Authentifizierung bei Office 365 durchzuführen.
static SecureString GetPassword()
{
SecureString sStrPwd = new SecureString();
try
{
Console.Write("Password: ");
for (ConsoleKeyInfo keyInfo = Console.ReadKey(true); keyInfo.Key != ConsoleKey.Enter; keyInfo = Console.ReadKey(true))
{
if (keyInfo.Key == ConsoleKey.Backspace)
{
if (sStrPwd.Length > 0)
{
sStrPwd.RemoveAt(sStrPwd.Length - 1);
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
Console.Write(" ");
Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
}
}
else if (keyInfo.Key != ConsoleKey.Enter)
{
Console.Write("*");
sStrPwd.AppendChar(keyInfo.KeyChar);
}
}
Console.WriteLine("");
}
catch (Exception e)
{
sStrPwd = null;
Console.WriteLine(e.Message);
}
return sStrPwd;
}
static string GetUserName()
{
string strUserName = string.Empty;
try
{
Console.Write("Username: ");
strUserName = Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
strUserName = string.Empty;
}
return strUserName;
}
Fügen Sie in Program.cs den folgenden Code zur Main-Methode hinzu, die die folgenden Aufgaben ausführt:
Lädt die settings.xml-Datei.
Ruft mithilfe von GetCatalog (116) einen Verweis auf den Gestaltungsvorlagenkatalog ab.
Gestaltungsvorlagen werden in den Gestaltungsvorlagenkatalog hochgeladen. Der Bezeichner der Listenvorlage des Gestaltungsvorlagenkatalogs ist 116. Weitere Informationen finden Sie unter ListTemplate-Element (Website).For more information, see ListTemplate Element (Site). Weitere Details zum Gestaltungsvorlagenkatalog werden geladen, einschließlich der Verwendung von List.ContentTypes zum Abrufen der Inhaltstypen, die dem Gestaltungsvorlagenkatalog zugeordnet sind.
Lädt Eigenschaften des Webobjekts, einschließlich Web.ContentTypes, Web.MasterUrl und Web.CustomMasterUrl.
Legt parentMasterPageContentTypeId auf die Inhaltstyp-ID master Seiten fest. Weitere Informationen finden Sie unter Basisinhaltstyphierarchie.
Ruft den Inhaltstyp master Seiten aus dem Gestaltungsvorlagenkatalog ab. Dieser Inhaltstyp wird verwendet, um den Inhaltstyp der neuen master Seite weiter unten in diesem Artikel festzulegen.
static void Main(string[] args) { string userName = GetUserName(); SecureString pwd = GetPassword(); // End program if no credentials were entered. if (string.IsNullOrEmpty(userName) || (pwd == null)) return; using (var clientContext = new ClientContext("http://sharepoint.contoso.com")) { clientContext.AuthenticationMode = ClientAuthenticationMode.Default; clientContext.Credentials = new SharePointOnlineCredentials(userName, pwd); XDocument settings = XDocument.Load("settings.xml"); // Get a reference to the Master Page Gallery which will be used to upload new master pages. Web web = clientContext.Web; List gallery = web.GetCatalog(116); Folder folder = gallery.RootFolder; // Load additional Master Page Gallery properties. clientContext.Load(folder); clientContext.Load(gallery, g => g.ContentTypes, g => g.RootFolder.ServerRelativeUrl); // Load the content types and master page information from the web. clientContext.Load(web, w => w.ContentTypes, w => w.MasterUrl, w => w.CustomMasterUrl); clientContext.ExecuteQuery(); // Get the content type for the master page from the Master Page Gallery using the content type ID for masterpages (0x010105). const string parentMasterPageContentTypeId = "0x010105"; ContentType masterPageContentType = gallery.ContentTypes.FirstOrDefault(ct => ct.StringId.StartsWith(parentMasterPageContentTypeId)); UploadAndSetMasterPages(web, folder, clientContext, settings, masterPageContentType.StringId); } }
Fügen Sie in Program.cs die UploadAndSetMasterPages-Methode hinzu, mit der eine Liste von MasterPageGalleryFile-Geschäftsobjekten erstellt wird:
Lesen aller in settings.xml definierten masterPage-Elemente .
Für jedes masterPage-Element, das eine master Seite angibt, die in SharePoint hochgeladen werden soll, laden Sie die Attributwerte in ein MasterPageGalleryFile-Geschäftsobjekt.
Führen Sie für jedes MasterPageGalleryFile-Geschäftsobjekt in der Liste einen Aufruf von UploadAndSetMasterPage durch.
private static void UploadAndSetMasterPages(Web web, Folder folder, ClientContext clientContext, XDocument settings, string contentTypeId) { IList<MasterPageGalleryFile> masterPages = (from m in settings.Descendants("masterPage") select new MasterPageGalleryFile { File = (string)m.Attribute("file"), Replaces = (string)m.Attribute("replaces"), ContentTypeId = contentTypeId }).ToList(); foreach (MasterPageGalleryFile masterPage in masterPages) { UploadAndSetMasterPage(web, folder, clientContext, masterPage); } }
Fügen Sie in Program.cs die UploadAndSetMasterPage-Methode hinzu, die die folgenden Aufgaben ausführt:
Checkt die Seite master aus.
Lädt die neue Datei mithilfe von FileCreationInformation hoch.
Ruft das Listenelement ab, das der neu hochgeladenen Datei zugeordnet ist.
Legt verschiedene Eigenschaften für das Listenelement fest, einschließlich des Festlegens der Inhaltstyp-ID des Listenelements auf die Inhaltstyp-ID der master Seite.
Checkt die neue seite master ein, veröffentlicht und genehmigt sie.
Wenn die master Seite oder benutzerdefinierte master Seiten-URL der aktuellen Website auf die alte master-Seite festgelegt ist, aktualisiert Web.MasterUrl oderWeb.CustomMasterUrl, um die neu hochgeladene master Seiten-URL zu verwenden.
private static void UploadAndSetMasterPage(Web web, Folder folder, ClientContext clientContext, MasterPageGalleryFile masterPage) { using (var fileReadingStream = System.IO.File.OpenRead(masterPage.File)) { // If necessary, ensure that the master page is checked out. PublishingHelper.CheckOutFile(web, masterPage.File, folder.ServerRelativeUrl); // Use the FileCreationInformation class to upload the new file. var fileInfo = new FileCreationInformation(); fileInfo.ContentStream = fileReadingStream; fileInfo.Overwrite = true; fileInfo.Url = masterPage.File; File file = folder.Files.Add(fileInfo); // Get the list item associated with the newly uploaded master page file. ListItem item = file.ListItemAllFields; clientContext.Load(file.ListItemAllFields); clientContext.Load(file, f => f.CheckOutType, f => f.Level, f => f.ServerRelativeUrl); clientContext.ExecuteQuery(); item["ContentTypeId"] = masterPage.ContentTypeId; item["UIVersion"] = Convert.ToString(15); item["MasterPageDescription"] = "Master Page Uploaded using CSOM"; item.Update(); clientContext.ExecuteQuery(); // If necessary, check in, publish, and approve the new master page file. PublishingHelper.CheckInPublishAndApproveFile(file); // On the current site, update the master page references to use the new master page. if (web.MasterUrl.EndsWith("/" + masterPage.Replaces)) { web.MasterUrl = file.ServerRelativeUrl; } if (web.CustomMasterUrl.EndsWith("/" + masterPage.Replaces)) { web.CustomMasterUrl = file.ServerRelativeUrl; } web.Update(); clientContext.ExecuteQuery(); } }
Hochladen und Aktualisieren von Verweisen auf Seitenlayouts
Hinweis
Die Codebeispiele in diesem Abschnitt bauen auf den Codebeispielen im vorherigen Abschnitt dieses Artikels auf.
So ersetzen Sie Seitenlayouts, die mithilfe von Modulen in Farmlösungen bereitgestellt wurden, und um Verweise hoch- und zu aktualisieren, um die neuen Seitenlayoutdateien zu verwenden:
Aktualisieren Sie die Main-Methode mit dem folgenden Code. Dieser Code enthält zusätzliche Schritte zum Hochladen und Aktualisieren von Verweisen auf Seitenlayoutdateien, einschließlich:
Festlegen von parentPageLayoutContentTypeId auf die Inhaltstyp-ID des Seitenlayouts.
Abrufen eines Inhaltstyps, der parentPageLayoutContentTypeId aus dem Gestaltungsvorlagenkatalog entspricht.
Aufrufen von UploadPageLayoutsAndUpdateReferences.
static void Main(string[] args) { string userName = GetUserName(); SecureString pwd = GetPassword(); // End program if no credentials were entered. if (string.IsNullOrEmpty(userName) || (pwd == null)) return; using (var clientContext = new ClientContext("http://sharepoint.contoso.com")) { clientContext.AuthenticationMode = ClientAuthenticationMode.Default; clientContext.Credentials = new SharePointOnlineCredentials(userName, pwd); XDocument settings = XDocument.Load("settings.xml"); // Get a reference to the Master Page Gallery, which will be used to upload new master pages. Web web = clientContext.Web; List gallery = web.GetCatalog(116); Folder folder = gallery.RootFolder; // Load additional Master Page Gallery properties. clientContext.Load(folder); clientContext.Load(gallery, g => g.ContentTypes, g => g.RootFolder.ServerRelativeUrl); // Load the content types and master page information from the web. clientContext.Load(web, w => w.ContentTypes, w => w.MasterUrl, w => w.CustomMasterUrl); clientContext.ExecuteQuery(); // Get the content type for the master page from the Master Page Gallery using the content type ID for masterpages (0x010105). const string parentMasterPageContentTypeId = "0x010105"; ContentType masterPageContentType = gallery.ContentTypes.FirstOrDefault(ct => ct.StringId.StartsWith(parentMasterPageContentTypeId)); UploadAndSetMasterPages(web, folder, clientContext, settings, masterPageContentType.StringId); // Get the content type ID for the page layout, and then update references to the page layouts. const string parentPageLayoutContentTypeId = "0x01010007FF3E057FA8AB4AA42FCB67B453FFC100E214EEE741181F4E9F7ACC43278EE811"; ContentType pageLayoutContentType = gallery.ContentTypes.FirstOrDefault(ct => ct.StringId.StartsWith(parentPageLayoutContentTypeId)); UploadPageLayoutsAndUpdateReferences(web, folder, clientContext, settings, pageLayoutContentType.StringId); } }
Fügen Sie in Program.cs die UploadPageLayoutsAndUpdateReferences-Methode hinzu, die die folgenden Schritte ausführt:
Liest die Informationen zum Ersetzen des Seitenlayouts, indem die Pagelayout-Elemente aus settings.xml gelesen, die Informationen zum Ersetzen des Seitenlayouts in LayoutFile-Geschäftsobjekten gespeichert und alle Geschäftsobjekte einer Liste hinzugefügt werden.
Für jedes zu ersetzende Seitenlayout:
Fragt die Inhaltstypen der Website mithilfe von Web.ContentTypes ab, um einen übereinstimmenden Inhaltstyp zu finden, bei dem der Name des Inhaltstyps der Website dem associatedContentTypeName entspricht, der in settings.xml für das neue Seitenlayout angegeben ist.
Ruft UploadPageLayout auf.
Ruft UpdatePages auf, um vorhandene Seiten für die Verwendung der neuen Seitenlayouts zu aktualisieren.
private static void UploadPageLayoutsAndUpdateReferences(Web web, Folder folder, ClientContext clientContext, XDocument settings, string contentTypeId) { // Read the replacement settings stored in pageLayout elements in settings.xml. IList<LayoutFile> pageLayouts = (from m in settings.Descendants("pageLayout") select new LayoutFile { File = (string)m.Attribute("file"), Replaces = (string)m.Attribute("replaces"), Title = (string)m.Attribute("title"), ContentTypeId = contentTypeId, AssociatedContentTypeName = (string)m.Attribute("associatedContentTypeName"), DefaultLayout = m.Attribute("defaultLayout") != null && (bool)m.Attribute("defaultLayout") }).ToList(); // Update the content type association. foreach (LayoutFile pageLayout in pageLayouts) { ContentType associatedContentType = web.ContentTypes.FirstOrDefault(ct => ct.Name == pageLayout.AssociatedContentTypeName); pageLayout.AssociatedContentTypeId = associatedContentType.StringId; UploadPageLayout(web, folder, clientContext, pageLayout); } UpdatePages(web, clientContext, pageLayouts); }
Fügen Sie in Program.cs die UploadPageLayout-Methode hinzu, die die folgenden Aufgaben ausführt:
Checkt die Seitenlayoutdatei aus.
Lädt die neue Datei mithilfe von FileCreationInformation hoch.
Ruft das Listenelement ab, das der neu hochgeladenen Datei zugeordnet ist.
Legt verschiedene Eigenschaften für das Listenelement fest, einschließlich ContentTypeId und PublishingAssociatedContentType.
Checkt die neue Seitenlayoutdatei ein, veröffentlicht und genehmigt sie.
Um Verweise auf die alte Seitenlayoutdatei zu entfernen, ruft PublishingHelper.UpdateAvailablePageLayouts auf, um den xml-Code zu aktualisieren, der in der PageLayouts-Eigenschaft auf der aktuellen Website gespeichert ist.
Wenn der defaultLayout-Attributwert der neu hochgeladenen Seitenlayoutdatei aus settings.xml auf true festgelegt ist, verwendet PublishingHelper.SetDefaultPageLayout , um den xml-Code zu aktualisieren, der in der DefaultPageLayout-Eigenschaft auf der aktuellen Website gespeichert ist.
private static void UploadPageLayout(Web web, Folder folder, ClientContext clientContext, LayoutFile pageLayout) { using (var fileReadingStream = System.IO.File.OpenRead(pageLayout.File)) { PublishingHelper.CheckOutFile(web, pageLayout.File, folder.ServerRelativeUrl); // Use FileCreationInformation to upload the new page layout file. var fileInfo = new FileCreationInformation(); fileInfo.ContentStream = fileReadingStream; fileInfo.Overwrite = true; fileInfo.Url = pageLayout.File; File file = folder.Files.Add(fileInfo); // Get the list item associated with the newly uploaded file. ListItem item = file.ListItemAllFields; clientContext.Load(file.ListItemAllFields); clientContext.Load(file, f => f.CheckOutType, f => f.Level, f => f.ServerRelativeUrl); clientContext.ExecuteQuery(); item["ContentTypeId"] = pageLayout.ContentTypeId; item["Title"] = pageLayout.Title; item["PublishingAssociatedContentType"] = string.Format(";#{0};#{1};#", pageLayout.AssociatedContentTypeName, pageLayout.AssociatedContentTypeId); item.Update(); clientContext.ExecuteQuery(); PublishingHelper.CheckInPublishAndApproveFile(file); PublishingHelper.UpdateAvailablePageLayouts(web, clientContext, pageLayout, file); if (pageLayout.DefaultLayout) { PublishingHelper.SetDefaultPageLayout(web, clientContext, file); } } }
Fügen Sie in Program.cs die UpdatePages-Methode hinzu, die die folgenden Aufgaben ausführt:
Ruft die Pages-Bibliothek und dann alle Listenelemente in der Pages-Bibliothek ab.
Verwendet für jedes Listenelement das Feld PublishingPageLayout des Listenelements, um nach einem übereinstimmenden zu aktualisierenden Seitenlayout zu suchen, das in settings.xml angegeben wurde und jetzt in pagelayouts gespeichert wird. Wenn das Feld PublishingPageLayout des Listenelements aktualisiert werden muss, um auf das neue Seitenlayout zu verweisen:
Checkt die Datei des Listenelements mithilfe von PublishingHelper.CheckOutFile aus.
Updates die URL des Seitenlayouts, um auf die neue Seitenlayoutdatei zu verweisen, und aktualisiert dann das Feld PublishingPageLayout des Listenelements.
Checkt die Datei ein, veröffentlicht und genehmigt die Datei, auf die vom Listenelement verwiesen wird.
private static void UpdatePages(Web web, ClientContext clientContext, IList<LayoutFile> pageLayouts) { // Get the Pages Library, and then get all the list items in it. List pagesList = web.Lists.GetByTitle("Pages"); var allItemsQuery = CamlQuery.CreateAllItemsQuery(); ListItemCollection items = pagesList.GetItems(allItemsQuery); clientContext.Load(items); clientContext.ExecuteQuery(); foreach (ListItem item in items) { // Only update those pages that are using a page layout which is being replaced. var pageLayout = item["PublishingPageLayout"] as FieldUrlValue; if (pageLayout != null) { LayoutFile matchingLayout = pageLayouts.FirstOrDefault(p => pageLayout.Url.EndsWith("/" + p.Replaces)); if (matchingLayout != null) { // Check out the page so that we can update the page layout. PublishingHelper.CheckOutFile(web, item); // Update the pageLayout reference. pageLayout.Url = pageLayout.Url.Replace(matchingLayout.Replaces, matchingLayout.File); item["PublishingPageLayout"] = pageLayout; item.Update(); File file = item.File; // Get the file and other attributes so that you can check in the file. clientContext.Load(file, f => f.Level, f => f.CheckOutType); clientContext.ExecuteQuery(); PublishingHelper.CheckInPublishAndApproveFile(file); } } } }