Partilhar via


Substituir arquivos do SharePoint implantados usando módulos em soluções de farm

Se você implantou arquivos declarativamente usando módulos em soluções farm, saiba como transformá-los em novas soluções que atualizam referências a arquivos e fornecem funcionalidade semelhante usando o modelo de objeto cliente (CSOM). No passado, os módulos eram usados para implantar arquivos como master páginas e layouts de página.

Importante

As soluções farm não podem ser migradas para o SharePoint Online. Aplicando as técnicas e o código descritos neste artigo, você pode criar uma nova solução com funcionalidades semelhantes que suas soluções de farm fornecem, atualizar referências aos arquivos e, em seguida, a nova solução pode ser implantada no SharePoint Online. Em seguida, você pode desabilitar o recurso e retrair a solução farm anterior.

O código neste artigo requer código adicional para fornecer uma solução totalmente funcional. Por exemplo, este artigo não discute como autenticar com Office 365, como implementar o tratamento de exceção necessário e assim por diante. Para obter exemplos de código adicionais, consulte o projeto padrões e práticas do desenvolvedor Office 365.

Observação

The code in this article is provided as-is, without warranty of any kind, either express or implied, including any implied warranties of fitness for a particular purpose, merchantability, or non-infringement.

Este artigo descreve como usar o processo de transformação para:

  • Referências de carregamento e atualização para páginas de master
  • Fazer upload e atualizar referências aos layouts de página

Use esse processo de transformação quando:

  • Suas soluções de farm existentes usavam módulos para implantar arquivos.
  • Você deseja substituir master páginas e layouts de página em soluções de farm por novas páginas master e layouts de página para que possam ser migrados para o SharePoint Online.
  • Você definiu tipos de conteúdo de documento em master páginas ou layouts de página em sua solução farm declarativamente.

Antes de começar

Idealmente, você deve examinar suas soluções farm existentes, aprender sobre as técnicas descritas neste artigo e planejar como aplicar essas técnicas aos seus cenários. Se você não está familiarizado com soluções farm ou não tem uma solução farm existente para trabalhar, pode ser útil para você aprender sobre soluções farm.

Para obter mais informações, consulte Criar soluções de farm no SharePoint.

Habilitar os recursos de publicação no conjunto de sites e no site

Antes de executar seu exemplo de código, habilite os recursos de publicação no conjunto de sites e no site com os procedimentos a seguir.

Para habilitar o recurso de Infraestrutura de Publicação do SharePoint Server na coleção de sites

  1. Abra seu site do SharePoint e vá para Configurações>do Site Configurações.

  2. Na Administração de Coleção de Sites, escolha Recursos de coleção de sites.

  3. Na infraestrutura de publicação do SharePoint Server, escolha Ativar.

Para habilitar o recurso Publicação do SharePoint Server no site

  1. Abra seu site do SharePoint e vá para Configurações>do Site Configurações.

  2. Em Ações do Site, escolha Gerenciar recursos do site.

  3. Na Publicação do SharePoint Server, escolha Ativar.

Configurar seu projeto do Visual Studio

  1. Baixe o projeto de exemplo. Escolha Exibir Bruto para começar a baixar o projeto de exemplo, extrair os arquivos do arquivo zip e, em seguida, navegar até a pasta Module9/ModuleReplacement.

  2. Abra ModuleReplacement.sln.

  3. Abra settings.xml. Examine e atualize os seguintes atributos para atender aos seus requisitos:

    • Elemento masterPage – usa o atributo de arquivo para especificar a nova página master para implantar na Galeria de Página Mestra e o atributo substitui para especificar a página de master existente na Galeria de Página Mestra.

    • Elemento pageLayout - Usa o atributo de arquivo para especificar o novo arquivo de layout de página, o atributo substitui para especificar o arquivo de layout de página existente e vários outros atributos para especificar informações adicionais de layout de página.

     	<?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>
    
    
  4. Em MasterPageGalleryFiles.cs, as classes MasterPageGalleryFile e LayoutFile definem objetos de negócios que armazenam informações sobre as novas páginas master e layouts de página a serem carregados no SharePoint.

Referências de carregamento e atualização para páginas de master

Para carregar e atualizar referências para as novas páginas de master em seu site do SharePoint:

  1. Em Program.cs, adicione a instrução de uso a seguir.

     	using System.Security;
    
  2. Em Program.cs, adicione os seguintes métodos para executar a autenticação ao 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;
      }
  1. Em Program.cs, adicione o seguinte código ao método Main , que executa as seguintes tarefas:

    1. Carrega o arquivo settings.xml.

    2. Obtém uma referência à Galeria de Página Mestra usando GetCatalog (116).

      As páginas mestras são carregadas na Galeria de Páginas Mestras. O identificador do modelo de lista da Galeria de Páginas Mestras é 116. Para obter mais informações, consulte Elemento ListTemplate (Site). Outros detalhes sobre a Galeria de Páginas Mestras são carregados, incluindo o uso de List.ContentTypes para obter os tipos de conteúdo associados à Galeria de Página Mestra.

    3. Carrega propriedades do objeto Web, incluindo Web.ContentTypes, Web.MasterUrl e Web.CustomMasterUrl.

    4. Define parentMasterPageContentTypeId como a ID do tipo de conteúdo de master páginas. Para obter mais informações, consulte Hierarquia de Tipo de Conteúdo Base.

    5. Obtém o tipo de conteúdo de master páginas da Galeria de Páginas Mestras. Esse tipo de conteúdo é usado para definir o tipo de conteúdo da nova página master posteriormente neste artigo.

       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);
      
       		}
      
       	}
      
  2. Em Program.cs, adicione o método UploadAndSetMasterPages , que cria uma lista de objetos de negócios MasterPageGalleryFile por:

    1. Lendo todos os elementos masterPage definidos em settings.xml.

    2. Para cada elemento masterPage, que especifica uma página master para carregar no SharePoint, carregando os valores de atributo em um objeto comercial MasterPageGalleryFile.

    3. Para cada objeto comercial MasterPageGalleryFile na lista, faça uma chamada para 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);
       	}
       }
      
  3. Em Program.cs, adicione o método UploadAndSetMasterPage , que executa as seguintes tarefas:

    1. Verifica a página master.

    2. Carrega o novo arquivo usando FileCreationInformation.

    3. Obtém o item de lista associado ao arquivo recém-carregado.

    4. Define várias propriedades no item da lista, incluindo a configuração da ID do tipo de conteúdo do item de lista para a ID do tipo de conteúdo da página master.

    5. Faz check-in, publica e aprova a nova página master.

    6. Se a página master do site atual ou a URL da página de master personalizada estiver definida como a página antiga do master, atualizará Web.MasterUrl ouWeb.CustomMasterUrl para usar a URL da página master recém-carregada.

       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();
       	}
       }
      

Fazer upload e atualizar referências aos layouts de página

Observação

Os exemplos de código nesta seção se baseiam nos exemplos de código na seção anterior deste artigo.

Para substituir layouts de página que foram implantados usando módulos em soluções farm e para carregar e atualizar referências para usar os novos arquivos de layout de página:

  1. Atualize o método Main com o código a seguir. Este código contém etapas adicionais para carregar e atualizar referências para arquivos de layout de página, incluindo:

    1. Definindo parentPageLayoutContentTypeId para a ID do tipo de conteúdo do layout da página.

    2. Obter um tipo de conteúdo que corresponda ao parentPageLayoutContentTypeId da Galeria de Páginas Mestras.

    3. Chamando 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);
       		}
      
       	}
      
  2. Em Program.cs, adicione o método UploadPageLayoutsAndUpdateReferences , que executa as seguintes etapas:

    1. Lê as informações de substituição do layout da página lendo os elementos pagelayout do settings.xml, armazenando as informações de substituição do layout da página em objetos comerciais layoutFile e adicionando todos os objetos de negócios a uma lista.

    2. Para que cada layout de página substitua:

      • Consulta os tipos de conteúdo do site usando Web.ContentTypes para encontrar um tipo de conteúdo correspondente em que o nome do tipo de conteúdo do site é igual ao associadoContentTypeName especificado em settings.xml para o novo layout da página.

      • Chama UploadPageLayout.

      • Chama UpdatePages para atualizar páginas existentes para usar os novos layouts de página.

           		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 &amp;&amp; (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);
           		}
        
        
  3. Em Program.cs, adicione o método UploadPageLayout , que executa as seguintes tarefas:

    1. Verifica o arquivo de layout da página.

    2. Carrega o novo arquivo usando FileCreationInformation.

    3. Obtém o item de lista associado ao arquivo recém-carregado.

    4. Define várias propriedades no item da lista, incluindo ContentTypeId e PublishingAssociatedContentType.

    5. Faz check-in, publica e aprova o novo arquivo de layout de página.

    6. Para remover referências ao arquivo de layout de página antiga, chama PublishingHelper.UpdateAvailablePageLayouts para atualizar o XML armazenado na propriedade PageLayouts no site atual.

    7. Se o valor de atributo defaultLayout do arquivo de layout de página recém-carregado do settings.xml for definido como true, usará PublishingHelper.SetDefaultPageLayout para atualizar o XML armazenado na propriedade DefaultPageLayout no site atual.

       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);
       		}
       	}
       }
      
  4. Em Program.cs, adicione o método UpdatePages , que executa as seguintes tarefas:

    1. Obtém a biblioteca Páginas e, em seguida, obtém todos os itens de lista na biblioteca Páginas .

    2. Para cada item de lista, usa o campo PublishingPageLayout do item de lista para encontrar um layout de página correspondente para atualizar, que foi especificado em settings.xml e agora está armazenado em pagelayouts . Se o campo PublishingPageLayout do item de lista precisar ser atualizado para consultar o layout da nova página:

      • Verifica o arquivo do item de lista usando PublishingHelper.CheckOutFile.

      • Atualizações a URL do layout da página para consultar o novo arquivo de layout de página e, em seguida, atualiza o campo PublishingPageLayout do item de lista.

      • Verifica, publica e aprova o arquivo referenciado pelo item de lista.

           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);
           			}
           		}
           	}
           }
        

Confira também