Замена файлов SharePoint, развернутых с помощью модулей в решениях фермы
Если вы декларативно развертывали файлы с помощью модулей в решениях фермы, узнайте, как преобразовать их в новые решения, которые обновляют ссылки на файлы и предоставляют аналогичные функции с помощью клиентской объектной модели (CSOM). В прошлом модули использовались для развертывания таких файлов, как master страницы и макеты страниц.
Важно!
Решения фермы нельзя перенести в SharePoint Online. Применяя методы и код, описанные в этой статье, можно создать новое решение с аналогичными функциями, которые предоставляют решения фермы, обновить ссылки на файлы, а затем развернуть новое решение в SharePoint Online. Затем вы можете отключить эту функцию и отозвать предыдущее решение фермы.
Код, приведенный в этой статье, требует дополнительного кода, чтобы обеспечить полностью работающее решение. Например, в этой статье не рассматривается проверка подлинности с помощью Office 365, реализация необходимой обработки исключений и т. д. Дополнительные примеры кода см. в проекте шаблоны и методики разработчика Office 365.
Примечание.
Код, приведенный в этой статье, предоставляется "как есть" без какой-либо явной или подразумеваемой гарантии, включая подразумеваемые гарантии пригодности для какой-либо цели, для продажи или гарантии отсутствия нарушения прав иных правообладателей.
В этой статье описывается, как использовать процесс преобразования для:
- Отправка и обновление ссылок на страницы master
- Отправка и обновление ссылок на макеты страниц
Используйте этот процесс преобразования, если:
- Существующие решения фермы использовали модули для развертывания файлов.
- Вы хотите заменить master страницы и макеты страниц в решениях ферм новыми master страницами и макетами страниц, чтобы их можно было перенести в SharePoint Online.
- Вы декларативно настроили типы содержимого документов на master страницах или макетах страниц в решении фермы.
Подготовка к работе
В идеале следует просмотреть существующие решения фермы, узнать о методах, описанных в этой статье, а затем спланировать применение этих методов в своих сценариях. Если вы не знакомы с решениями фермы или у вас нет существующего решения фермы для работы, вам может быть полезно узнать о решениях фермы.
Дополнительные сведения см. в статье Создание решений фермы в SharePoint.
Включение функций публикации в семействе веб-сайтов и на сайте
Перед выполнением примера кода включите функции публикации в семействе веб-сайтов и на сайте, выполнив следующие процедуры.
Включение функции инфраструктуры публикации SharePoint Server в семействе веб-сайтов
Откройте сайт SharePoint и перейдите в раздел Параметры>Параметры сайта.
В разделе Администрирование семейства веб-сайтов выберите Функции семейства веб-сайтов.
На вкладке Инфраструктура публикации SharePoint Server выберите Активировать.
Включение функции публикации SharePoint Server на сайте
Откройте сайт SharePoint и перейдите в раздел Параметры>Параметры сайта.
В разделе Действия сайта выберите Управление функциями сайта.
В публикации SharePoint Server нажмите кнопку Активировать.
Настройка проекта Visual Studio
Скачайте пример проекта. Выберите Просмотр необработанного , чтобы начать загрузку примера проекта, извлечь файлы из ZIP-файла, а затем перейдите в папку Module9/ModuleReplacement.
Откройте ModuleReplacement.sln.
Откройте settings.xml. Просмотрите и обновите следующие атрибуты в соответствии со своими требованиями:
Элемент masterPage — использует атрибут file для указания новой страницы master для развертывания в коллекции главных страниц, а атрибут replaces — для указания существующей страницы master в коллекции главных страниц.
Элемент pageLayout — использует атрибут file для указания нового файла макета страницы, атрибут replaces для указания существующего файла макета страницы и несколько других атрибутов для указания дополнительных сведений о макете страницы.
<?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>
В файле MasterPageGalleryFiles.cs классы MasterPageGalleryFile и LayoutFile определяют бизнес-объекты, в которые хранятся сведения о новых master страницах и макетах страниц для отправки в SharePoint.
Отправка и обновление ссылок на страницы master
Чтобы отправить и обновить ссылки на новые страницы master на сайте SharePoint, выполните следующие действия:
В файле Program.cs добавьте следующую инструкцию using .
using System.Security;
В файле Program.cs добавьте следующие методы для выполнения проверки подлинности для Office 365.
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;
}
В Файле Program.cs добавьте следующий код в метод Main , который выполняет следующие задачи:
Загружает файл settings.xml.
Возвращает ссылку на коллекцию главных страниц с помощью GetCatalog (116).
Главные страницы отправляются в коллекцию главных страниц. Идентификатор шаблона списка коллекции главных страниц — 116. Дополнительные сведения см. в разделе Элемент ListTemplate (Site). Загружаются другие сведения о коллекции главных страниц, в том числе с помощью List.ContentTypes для получения типов контента, связанных с коллекцией эталонных страниц.
Загружает свойства веб-объекта, включая Web.ContentTypes, Web.MasterUrl и Web.CustomMasterUrl.
Задает parentMasterPageContentTypeId для идентификатора типа контента master страниц. Дополнительные сведения см. в статье Base Content Type Hierarchy.
Возвращает тип контента master страниц из коллекции главных страниц. Этот тип контента используется для задания типа контента новой страницы master далее в этой статье.
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); } }
В Program.cs добавьте метод UploadAndSetMasterPages , который создает список бизнес-объектов MasterPageGalleryFile , выполнив следующие действия:
Чтение всех элементов masterPage, определенных в settings.xml.
Для каждого элемента masterPage, который указывает master страницу для отправки в SharePoint, загрузив значения атрибутов в бизнес-объект MasterPageGalleryFile.
Для каждого бизнес-объекта MasterPageGalleryFile в списке, выполняя вызов UploadAndSetMasterPage.
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); } }
В Program.cs добавьте метод UploadAndSetMasterPage , который выполняет следующие задачи:
Извлекает страницу master.
Отправляет новый файл с помощью FileCreationInformation.
Возвращает элемент списка, связанный с только что отправленным файлом.
Задает различные свойства элемента списка, включая задание идентификатора типа контента элемента списка идентификатором типа контента master страницы.
Возвращает, публикует и утверждает новую страницу master.
Если для текущей страницы master сайта или URL-адреса настраиваемой master страницы задана старая master страница, обновите Web.MasterUrl илиWeb.CustomMasterUrl, чтобы использовать только что отправленный URL-адрес master страницы.
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(); } }
Отправка и обновление ссылок на макеты страниц
Примечание.
Примеры кода в этом разделе создаются на основе примеров кода, приведенных в предыдущем разделе этой статьи.
Чтобы заменить макеты страниц, развернутые с помощью модулей в решениях фермы, а также отправить и обновить ссылки для использования новых файлов макета страницы:
Обновите метод Main , используя следующий код. Этот код содержит дополнительные шаги для отправки и обновления ссылок на файлы макета страницы, в том числе:
Задав parentPageLayoutContentTypeId идентификатор типа контента макета страницы.
Получение типа контента, соответствующего parentPageLayoutContentTypeId из коллекции эталонных страниц.
Вызов 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); } }
В Файле Program.cs добавьте метод UploadPageLayoutsAndUpdateReferences , который выполняет следующие действия:
Считывает сведения о замене макета страницы, считывая элементы страницы из settings.xml, сохраняя сведения о замене макета страницы в бизнес-объектах LayoutFile и добавляя все бизнес-объекты в список.
Для замены каждого макета страницы:
Запрашивает типы контента сайта с помощью Web.ContentTypes для поиска соответствующего типа контента, в котором имя типа контента сайта равно свойству associatedContentTypeName , указанному в settings.xml для нового макета страницы.
Вызывает UploadPageLayout.
Вызывает UpdatePages для обновления существующих страниц, чтобы использовать новые макеты страниц.
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); }
В Program.cs добавьте метод UploadPageLayout , который выполняет следующие задачи:
Извлекает файл макета страницы.
Отправляет новый файл с помощью FileCreationInformation.
Возвращает элемент списка, связанный с только что отправленным файлом.
Задает различные свойства элемента списка, включая ContentTypeId и PublishingAssociatedContentType.
Возвращает, публикует и утверждает новый файл макета страницы.
Чтобы удалить ссылки на старый файл макета страницы, вызывает метод PublishingHelper.UpdateAvailablePageLayouts , чтобы обновить XML-файл, хранящийся в свойстве PageLayouts на текущем сайте.
Если значение атрибута defaultLayout недавно отправленного файла макета страницы из settings.xml имеет значение true, использует PublishingHelper.SetDefaultPageLayout для обновления XML-файла, хранящегося в свойстве DefaultPageLayout на текущем сайте.
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); } } }
В Program.cs добавьте метод UpdatePages , который выполняет следующие задачи:
Возвращает библиотеку Pages , а затем получает все элементы списка в библиотеке Pages .
Для каждого элемента списка использует поле PublishingPageLayout элемента списка, чтобы найти соответствующий макет страницы для обновления, который был указан в settings.xml и теперь хранится в страницах со страницами . Если необходимо обновить поле PublishingPageLayout элемента списка, чтобы сослаться на новый макет страницы:
Извлекает файл элемента списка с помощью PublishingHelper.CheckOutFile.
Обновления URL-адрес макета страницы для ссылки на новый файл макета страницы, а затем обновляет поле PublishingPageLayout элемента списка.
Возвращает, публикует и утверждает файл, на который ссылается элемент списка.
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); } } } }