Domanda

Attualmente ho una pagina master personalizzata che viene distribuita nell'ambito del sito. Una volta distribuito e la funzione è attivata rende la pagina master disponibile per l'uso. Sono in grado di attivare la funzione e impostare la pagina Master su siti e sottosezioni ereditano correttamente la pagina master.

Il problema si verifica quando tento di disattivare la funzione.

Una volta disattivato, ho un ricevitore evento che trova tutti i siti che hanno il set di pagine master della funzione e riporta la pagina Master predefinita. Questo include anche l'impostazione della pagina master sui siti ereditari.

Funziona bene, ma dopo aver completato questo tentativo di eliminare la pagina master dalla Galleria Pagina principale e gli errori IT affermando che è ancora in uso. Quando controllerò i siti attraverso la GUI sono stati tutti arrestiti in Seattle e i siti ereditari sono ancora ereditari dal genitore, quindi tutto sembra bene su quella fine.

Quando vado nel Contenuto e struttura della raccolta del sito e cerco le pagine correlate della Pagina principale è ancora una relazione con il _DeviceChannelMappings.aspx per tutti Siti che ereditano la sua Pagina principale dal genitore. Vedi sotto:

Master Page Relazioni

Non sono stato in grado di trovare un modo a livello programmatico per rimuovere questa relazione e, a causa di ciò non riesco a eliminare la pagina principale dalla libreria dei cataloghi.

Se andassi manualmente nella raccolta del sito root nella GUI e controlla il reset tutti i sottoseti per ereditare questa impostazione della pagina master del sito utilizzando la masterpage di Seattle, le relazioni andranno via e il file è quindi in grado essere cancellato.

Qualsiasi aiuto sarebbe apprezzato. Ecco il mio codice corrente per la disattivazione della funzione:

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)
                {
                }
            }
        }
    }
.

È stato utile?

Soluzione 2

Non so se questo è il modo migliore per risolvere questo problema, ma sono stato in grado di risolvere il problema modificando manualmente il __ DeviceChannelMappings.aspx sulla funzione Disattivazione della funzione .Ciò rilascerà i mappature alla pagina master personalizzata e consentirà che venga soppresso.

Ecco il codice finale:

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)
                {
                }
            }
        }
    }
.

Altri suggerimenti

Sembra che la tua Pagina master venga utilizzata dai canali del dispositivo in tutti i tuoi siti.Microsoft non fornisce un'API pubblica per la visualizzazione o la modifica delle pagine master configurate per un canale dispositivo.Con questo detto, nel mio libro (SharePoint 2013 WCM Advanced Cookbook: http://tinyurl.com/lutktay ),Ho alcuni campioni su come visualizzare e modificare le pagine master configurate per i canali del dispositivo.

Ecco il codice C # del codice per la visualizzazione dei canali del dispositivo:

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

Ed Ecco il codice C # per l'impostazione dei canali del dispositivo:

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

Con questi due campioni, dovresti avere ciò che è necessario ottenere i canali del dispositivo per ciascun sito e assicurati che non stiano usando la tua Pagina principale.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a sharepoint.stackexchange
scroll top