Невозможно удалить пользовательскую главную страницу программно во время дезактивации на 2013 год

sharepoint.stackexchange https://sharepoint.stackexchange.com/questions/100677

Вопрос

У меня в настоящее время есть пользовательская главная страница, которая развернута на площадке сайта. После развертывания и функция активирована, она делает главной страницей доступной для использования. Я могу активировать функцию и установить главную страницу на сайтах, а субзимы наследовать главную страницу правильно.

Проблема возникает, когда я пытаюсь деактивировать функцию.

После деактивации у меня есть приемник событий, который находит все сайты, которые имеют главная страница объекта, и устанавливает ее обратно на главную страницу по умолчанию. Это также включает в себя настройку главной страницы на наследственных участках.

Это работает нормально, но после того, как это завершило, я пытаюсь удалить главную страницу с главной страницы галереи, и она ошибками, указав, что она все еще используется. Когда я проверяю сайты через графический интерфейс, они все были отправлены в Сиэтл, и наследование сайтов по-прежнему наследует от родителя, поэтому все выглядит хорошо на этом конце.

Когда я вхожу в CONTENT и структуру сбора сайта и посмотрите на главную страницу страницы, связанные с страницами, что все еще есть отношения с _devicechannelmappings.aspx страницы для всех Сайты, которые наследуют свою главную страницу от родителя. См. Ниже:

Отношения главной страницы

Я не смог найти способом программно, чтобы удалить эти отношения и из-за того, что я не могу удалить главную страницу из библиотеки каталогов.

Если я вручную перейдем к коллекции корневой площадки в графическом интерфейсе, и проверьте сброс всех подведений, чтобы наследовать этот сайт Master Page Настройка страницы Использование Masterpage Seattle Отношения будут уходить и файл быть удаленным.

Любая помощь будет оценена. Вот мой текущий код для дезактивации функции:

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
    {
        using (SPSite siteCollection = (SPSite)properties.Feature.Parent)
        {
            string defaultMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl.EndsWith("/") ? siteCollection.ServerRelativeUrl : siteCollection.ServerRelativeUrl + "/" , "_catalogs/masterpage/seattle.master");
            string pulseMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl.EndsWith("/") ? siteCollection.ServerRelativeUrl : siteCollection.ServerRelativeUrl + "/" , "_catalogs/masterpage/pulse.v01.master");
            foreach (SPWeb web in siteCollection.AllWebs)
            {
                Hashtable hash = web.AllProperties;
                if (hash["__InheritsMasterUrl"].ToString() == "True" && !web.IsRootWeb)
                {
                    web.MasterUrl = web.ParentWeb.MasterUrl;
                    web.Update();
                }
                else if (web.MasterUrl == pulseMasterUrl)
                {
                    web.MasterUrl = defaultMasterUrl;
                    web.Update();
                }

                if (hash["__InheritsCustomMasterUrl"].ToString() == "True" && !web.IsRootWeb)
                {
                    web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
                    web.Update();
                }
                else if (web.CustomMasterUrl == pulseMasterUrl)
                {
                    web.CustomMasterUrl = defaultMasterUrl;
                    web.Update();
                }
            }

            foreach (SPWeb web in siteCollection.AllWebs)
            {
                try
                {
                    SPFile file = web.GetFile(pulseMasterUrl);
                    if (file.Exists)
                    {
                        file.Delete();
                    }
                    file.Update();
                }
                catch (Exception ex)
                {
                }
            }
        }
    }
.

Это было полезно?

Решение 2

Я не знаю, есть ли это лучший способ исправить эту проблему, но я смог решить проблему путем вручную редактирования __ DeviceChannelmapputions.aspx на дезактивации Это выпустит сопоставления на пользовательскую главную страницу и позволить ему быть удаленным.

Вот последний код:

public class PulseMasterPageEventReceiver : SPFeatureReceiver
{
    public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
    {
        using (SPSite siteCollection = (SPSite)properties.Feature.Parent)
        {
            string defaultMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl.EndsWith("/") ? siteCollection.ServerRelativeUrl : siteCollection.ServerRelativeUrl + "/" , "_catalogs/masterpage/seattle.master");
            string pulseMasterUrl = SPUrlUtility.CombineUrl(siteCollection.ServerRelativeUrl.EndsWith("/") ? siteCollection.ServerRelativeUrl : siteCollection.ServerRelativeUrl + "/" , "_catalogs/masterpage/pulse.v01.master");

            foreach (SPWeb web in siteCollection.AllWebs)
            {
                web.AllowUnsafeUpdates = true;
                Hashtable hash = web.AllProperties;
                if (hash["__InheritsMasterUrl"].ToString() == "True" && !web.IsRootWeb)
                {
                    web.MasterUrl = web.ParentWeb.MasterUrl;
                    web.Update();
                }
                else if (web.MasterUrl == pulseMasterUrl)
                {
                    web.MasterUrl = defaultMasterUrl;
                    web.Update();
                }

                if (hash["__InheritsCustomMasterUrl"].ToString() == "True" && !web.IsRootWeb)
                {
                    web.CustomMasterUrl = web.ParentWeb.CustomMasterUrl;
                    web.Update();
                }
                else if (web.CustomMasterUrl == pulseMasterUrl)
                {
                    web.CustomMasterUrl = defaultMasterUrl;
                    web.Update();
                }
                web.AllowUnsafeUpdates = false;
            }

            foreach (SPWeb web in siteCollection.AllWebs)
            {
                string deviceChannelMappings = SPUrlUtility.CombineUrl(web.Url.EndsWith("/") ? web.Url : web.Url + "/", "_catalogs/masterpage/__devicechannelmappings.aspx");
                SPFile dcmFile = web.GetFile(deviceChannelMappings);
                Stream dcmFileStream = dcmFile.OpenBinaryStream();
                Stream dcmFileWrite = new MemoryStream();

                using (StreamWriter sw = new StreamWriter(dcmFileWrite))
                using (StreamReader sr = new StreamReader(dcmFileStream))
                {
                    string line;
                    bool foundCorrection = false;
                    while ((line = sr.ReadLine()) != null)
                    {
                        if (line.Contains("pulse.v01.master"))
                        {
                            foundCorrection = true;
                            line = line.Replace("pulse.v01.master", "seattle.master");
                        }
                        sw.WriteLine(line);
                    }
                    sw.Flush();
                    if (foundCorrection)
                    {
                        if (dcmFile.CheckOutType != SPFile.SPCheckOutType.None)
                            dcmFile.UndoCheckOut();
                        if (dcmFile.RequiresCheckout)
                        {
                            dcmFile.CheckOut();
                            dcmFile.SaveBinary(dcmFileWrite);
                            dcmFile.CheckIn("Updated master page references to default.");
                        }
                        else
                        {
                            dcmFile.SaveBinary(dcmFileWrite);
                        }
                        if (dcmFile.Level == SPFileLevel.Draft)
                        {
                            dcmFile.Publish("Updated master page references to default.");
                        }
                        dcmFile.Update();
                    }
                }
            }

            foreach (SPWeb web in siteCollection.AllWebs)
            {
                try
                {
                    SPFile file = web.GetFile(pulseMasterUrl);
                    if (file.Exists)
                    {
                        file.Delete();
                    }
                    file.Update();
                }
                catch (Exception ex)
                {
                }
            }
        }
    }
.

Другие советы

Похоже, ваша главная страница используется каналами устройства на протяжении всех сайтов.Microsoft не предоставляет публичном API для просмотра или изменения настроенных главных страниц для канала устройства.С этим сказанным, в моей книге (SharePoint 2013 WCM Advanced Cookbook: http://tinyurl.com/lutktay ),У меня есть некоторые образцы о том, как просмотреть и изменить настроенные главные страницы для каналов устройств.

Вот код образца C # для просмотра каналов устройства:

namespace Code6587EN.Ch02.GetDeviceChannelMaps
{
    using Microsoft.SharePoint;
    using System;
    using System.Collections;
    using System.Reflection;

    /// <summary>
    /// Console Application to get the Device Channel mappings for each
    /// Site in a Site Collection
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            // Get the Site Collection in a Using statement
            using (var site = new SPSite("http://sharepoint/sitecollection"))
            {
                // Get the Mappings File type and constructor
                var typeMappingFile = Type.GetType("Microsoft.SharePoint.Publishing.Mobile.MasterPageMappingsFile, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");                
                var consMappingFile = typeMappingFile.GetConstructor(new Type[] {typeof(SPWeb), typeof(bool), typeof(SPWeb)});

                // Iterate through each Site in the Site Collection
                foreach (SPWeb web in site.AllWebs)
                {
                    // Ensure the Site exists
                    if (web.Exists)
                    {
                        // Get the Mapping File for the Site
                        var mappingFile = consMappingFile.Invoke(new object[] { web, false, null });

                        // Output the Default channel details
                        Console.WriteLine("");
                        Console.WriteLine("Site: " + web.Url);
                        Console.WriteLine("Device Channel: Default");
                        Console.WriteLine("Master Page: " + web.CustomMasterUrl);

                        // Get the mappings field from the Mapping File and cast as the IDictionary interface
                        var mappings = (IDictionary)typeMappingFile.GetField("mappings", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(mappingFile);

                        // Iterate through each key in the IDictionary
                        foreach (var key in mappings.Keys)
                        {
                            // Get the Master Page Url property from the mapping object
                            var mappingObject = mappings[key];
                            var masterUrl = (string)mappingObject.GetType().GetProperty("MasterPageUrl", BindingFlags.Instance | BindingFlags.Public).GetValue(mappingObject, null);

                            // Output the Channel details
                            Console.WriteLine("");
                            Console.WriteLine("Site: " + web.Url);
                            Console.WriteLine("Device Channel: " + key);
                            Console.WriteLine("Master Page: " + masterUrl);
                        }

                        // Dispose the Site object
                        web.Dispose();
                    }
                }
            }

            // Wait for a key to be pressed before closing the application
            Console.WriteLine("Press Any Key to Continue...");
            Console.Read();
        }
    }
}
.

А вот код пример C # для настройки каналов устройства:

namespace Code6587EN.Ch02.ApplyMasterToChannel
{
    using Microsoft.SharePoint;
    using System;
    using System.Collections;
    using System.Reflection;

    /// <summary>
    /// Console Application to apply a Master Page to a Device Channel
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            // Get the Site Collection in a Using statement
            using (var site = new SPSite("http://sharepoint/sitecollection"))
            {
                // Get the Mappings File type and constructor
                var typeMappingFile = Type.GetType("Microsoft.SharePoint.Publishing.Mobile.MasterPageMappingsFile, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");                
                var consMappingFile = typeMappingFile.GetConstructor(new Type[] {typeof(SPWeb), typeof(bool), typeof(SPWeb)});

                // Get the root Site in a Using statement
                using (var web = site.RootWeb)
                {                   
                    // Get the Mapping File
                    var mappingFile = consMappingFile.Invoke(new object[] { web, false, null });

                    // Get the Mappings and cast to an IDictionary
                    var mappings = (IDictionary)typeMappingFile.GetField("mappings", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(mappingFile);

                    // Set the Master Page Url of the mapping object 
                    mappings["PowerShell"].GetType().GetProperty("MasterPageUrl", BindingFlags.Instance | BindingFlags.Public).SetValue(mappings["PowerShell"], "/_catalogs/masterpage/seattle.master", null);

                    // Set the updated Mappings on the Mappings file
                    typeMappingFile.GetField("mappings", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(mappingFile, mappings);

                    // Get and invoke the Update Single Channel method
                    var updateMethod = typeMappingFile.GetMethod("UpdateSingleChannel", BindingFlags.Instance | BindingFlags.Public, null, new Type[] { typeof(string) }, null);
                    updateMethod.Invoke(mappingFile, new object[] { "PowerShell" });
                }
            }

            // Wait for a key to be pressed before closing the application
            Console.WriteLine("Press Any Key to Continue...");
            Console.Read();
        }
    }
}
.

С этими двумя образцами вы должны иметь то, что вам нужно, чтобы получить каналы устройства для каждого сайта, и убедитесь, что они не используют свою главную страницу.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с sharepoint.stackexchange
scroll top