c# - 如何使用 c# 导入 SPWeb 以具有与 PowerShell 相同的行为?

标签 c# .net powershell sharepoint sharepoint-2013

我对 sharepoint.deployment.spimport 的行为有疑问。

我想像这样在同一个网站集中复制一个网站:

myserver/mysitecoll/website1

myserver/mysitecoll/website2

当我使用 PowerShell 命令执行它时,它完美地完成了,website2 与 website1 相同

 Export-SPWeb -Identity http://myserver/mysitecoll/website1 -Path D:\mybackups\mytestsave\mybackup.bak

Import-SPWeb -Identity http://myserver/mysitecoll/website2 -Path D:\mybackups\mytestsave\mybackup.bak

但是我需要对我使用的 c# 做同样的事情

    private void ExportSpWeb()
    {

        SPSite mySite = SPContext.Current.Site;
        SPWeb myWeb = SPContext.Current.Web;  
        SPExportObject exportObject = new SPExportObject();
        exportObject.Id = myWeb.ID;
        exportObject.ParentId = mySite.ID;
        exportObject.Type = SPDeploymentObjectType.Web;
        SPExportSettings settings = new SPExportSettings();
        settings.SiteUrl = mySite.Url;
        settings.ExportMethod = SPExportMethodType.ExportAll;
        settings.FileLocation = "D:\\mybackups\\mytestsave";
        settings.BaseFileName = "test.cab";
        settings.FileCompression = true;
        settings.ExcludeDependencies = true;
        settings.CommandLineVerbose = true;
        settings.ExportObjects.Add(exportObject);
        SPExport export = new SPExport(settings);
        export.Run();
    }
    private void importSpWeb()
    {
        SPSite mySite = SPContext.Current.Site;
        SPWeb myDestWeb = mySite.AllWebs["website2"];
        SPImportSettings impsettings = new SPImportSettings();
        impsettings.SiteUrl = mySite.Url;
        impsettings.LogFilePath = "D:\\mybackups\\mytestsave\\test.log";
        impsettings.WebUrl = myDestWeb.ServerRelativeUrl;
        impsettings.FileLocation = "D:\\mybackups\\mytestsave";
        impsettings.FileCompression = true;
        impsettings.BaseFileName = "test.cab";
        impsettings.RetainObjectIdentity = false;
        SPImport import = new SPImport(impsettings);
        import.Run();
    }

但该组件与 PowerShell 不同:它不是使用指定的 WebUrl 设置 ( http://myserver/mysitecoll/website2 ) 创建的,而是 导入的网站创建为具有路径的新子网站 http://myserver/mysitecoll/website2/website1

我应该如何编辑我的代码以获得与 PowerShell 相同的结果?

最佳答案

这个问题让我思考得很深,因为我和你一样碰壁了,但这让我想到了一个问题:Where is definition of sharepoint cmdlets and How to get their implementation?

因此,了解 Microsoft.SharePoint.PowerShell.dll 中的 Import-SPWeb 又名 SPCmdletImportWeb 在哪里,我检查了它是如何完成的。

棘手的部分是,出于某种原因 SPImportWeb 有一些奇怪的逻辑来修改 WebUrl 属性并始终将 / 添加到末尾。所以在 SPCmdletImportWeb 中,他们使用 SPImportCreated 事件来重置一些属性。

对于您的情况,当您导出和导入一个 SPWeb 对象时,您需要将以下代码添加到您的导入对象:

string webUrl = "website2";
// your stuff
SPImport import = new SPImport(impsettings);
import.Started += delegate(object sender, SPDeploymentEventArgs args)
{
    SPImportObjectCollection rootObjects = args.RootObjects;
    if (rootObjects[0].Type == SPDeploymentObjectType.Web)
    {
        rootObjects[0].TargetParentUrl = site.Url;
        rootObjects[0].TargetName = webUrl;
        return;
    }
};

要查找 SPCmdletImportWeb 的完整代码,请获取 ILSpy并在第一个 url 中按照我的迷你教程进行操作。

完整测试代码:

[TestMethod]
public void Test_ExportSpWeb()
{
    ExportSpWeb("http://lab/sites/custom-dev", "website1", @"C:\temp\bak\bak2.bak");
}

[TestMethod]
public void Test_ImportSpWeb()
{
    ImportSpWeb("http://lab/sites/custom-dev", "website2", @"C:\temp\bak\bak2.bak");
}

private void ImportSpWeb(string siteUrl, string webUrl, string path)
{
    using (SPSite site = new SPSite(siteUrl))
    using (SPWeb web = site.OpenWeb(webUrl))
    {
        SPImportSettings impsettings = new SPImportSettings();
        impsettings.SiteUrl = site.Url;
        impsettings.LogFilePath = path + ".log";
        impsettings.WebUrl = web.ServerRelativeUrl + "/" + webUrl;
        impsettings.FileLocation = Path.GetDirectoryName(path);
        impsettings.FileCompression = true;
        impsettings.CommandLineVerbose = true;
        impsettings.BaseFileName = Path.GetFileName(path);
        impsettings.RetainObjectIdentity = false;
        SPImport import = new SPImport(impsettings);
        import.Started += delegate(object sender, SPDeploymentEventArgs args)
        {
            SPImportObjectCollection rootObjects = args.RootObjects;
            if (rootObjects[0].Type == SPDeploymentObjectType.Web)
            {
                rootObjects[0].TargetParentUrl = site.Url;
                rootObjects[0].TargetName = webUrl;
                return;
            }
        };
        import.Run();
    }
}

private void ExportSpWeb(string siteUrl, string webUrl, string path)
{
    using (SPSite site = new SPSite(siteUrl))
    using (SPWeb web = site.OpenWeb(webUrl))
    {
        SPExportObject exportObject = new SPExportObject();
        exportObject.Id = web.ID;
        exportObject.ParentId = site.ID;                
        exportObject.Type = SPDeploymentObjectType.Web;
        SPExportSettings settings = new SPExportSettings();
        settings.SiteUrl = site.Url;
        settings.ExportMethod = SPExportMethodType.ExportAll;
        settings.FileLocation = Path.GetDirectoryName(path);
        settings.BaseFileName = Path.GetFileName(path);
        settings.LogFilePath = path + ".log";
        settings.FileCompression = true;
        settings.ExcludeDependencies = true;
        settings.CommandLineVerbose = true;
        settings.ExportObjects.Add(exportObject);
        SPExport export = new SPExport(settings);
        export.Run();
    }
}

关于c# - 如何使用 c# 导入 SPWeb 以具有与 PowerShell 相同的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44201669/

相关文章:

c# - 在标签之间查找文本并将其与标签一起替换

c# - 将自定义 header 添加到 .Net 中的所有 Swagger 响应

c# - 无法将字符串转换为 int。来自 XML 元素的数据。 C#

.net - 如何通过 SDK 将附件添加到工作项而不使用物理文件?

powershell - 由于脚本而退出时的 iTunes 警告消息

Powershell,用空格替换 DOT

c# - 使用 C# 在 SQL 中插入数据表

c# - 授权属性无法阻止 ASP.Net Core 3.0 Web API 中的请求

sql - 使用 PowerShell 检查 SQL Server 中的行是否存在

c# - LINQ 查询未提取所需的所有记录