Невозможно удалить пользовательскую главную страницу программно во время дезактивации на 2013 год
Вопрос
Проблема возникает, когда я пытаюсь деактивировать функцию.
После деактивации у меня есть приемник событий, который находит все сайты, которые имеют главная страница объекта, и устанавливает ее обратно на главную страницу по умолчанию. Это также включает в себя настройку главной страницы на наследственных участках.
Это работает нормально, но после того, как это завершило, я пытаюсь удалить главную страницу с главной страницы галереи, и она ошибками, указав, что она все еще используется. Когда я проверяю сайты через графический интерфейс, они все были отправлены в Сиэтл, и наследование сайтов по-прежнему наследует от родителя, поэтому все выглядит хорошо на этом конце.
Когда я вхожу в
Я не смог найти способом программно, чтобы удалить эти отношения и из-за того, что я не могу удалить главную страницу из библиотеки каталогов.
Если я вручную перейдем к коллекции корневой площадки в графическом интерфейсе, и проверьте сброс всех подведений, чтобы наследовать этот сайт 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
Я не знаю, есть ли это лучший способ исправить эту проблему, но я смог решить проблему путем вручную редактирования
Вот последний код:
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();
}
}
}
.
С этими двумя образцами вы должны иметь то, что вам нужно, чтобы получить каналы устройства для каждого сайта, и убедитесь, что они не используют свою главную страницу.