深入解析SharePoint Content Deployment and Migration API 之三

提供一些真实的import的例子

==========================

我们第二部分了解了export之后, 我们现在来集中注意力到import的部分. 实际上Import有两种不同的工作方式:

  • Import对象并保存对象的identity和location

  • Import对象, 但不保存对象的identity

第一种方式被用在管理中心站点页面的Content Deployment功能中. 第二种方式是用在STSADM -o import 中的, 还用在Site Manager中的Copy/Move 操作里.

第一种方式与在CMS2002中使用的import方法一样: import 的对象会拥有与在源系统中一样的GUID.

第二种方式, 从另一方面, 允许我们import到site collection hierarchy的不同地方, 所以可以用在copy操作上.

 

为了论证Content Deployment and Migration API是多么强大, 在这里我会再一次地提供一些例子:

  1. 保留对象identity的import

  2. 在import的过程中修改掉imported对象的parent.

下面的例子假设目标站点集在相同服务器的2001端口上.

 

1) Import with preserving the object identity

----------------------------------------------------------

这个方法的一个预备条件是, 所有imported对象的parents需要已经在目标数据库中已经存在了. 所以不可能使用这个方法把对象import到一个具有不同结构的站点中. 通常, 它意味着你可以使用经典的staging secnarios, 在那里你有一个authoring farm, 一个staging farm, 和一个production farm. 内容已经初始地在authoring farm中创建了, 并已经被部署到了staging farm. 

 

对于这种方法, package是仅包含一个单独的列表项, 还是一个站点, 或者市一个整个的站点集都无所谓. 是否是使用incremental deployment 还是full deployment也无关紧要. 因为所有package中的对象的parents都已经在目标数据库中存在了, import 引擎会正确地import这些items.

 

如果你有不同的站点集, 并且需要在他们之间交换数据(比方说, 从一个站点集http://www.company1.com/中拷贝一个文档库, 到站点集http://www.company2.com/中, 那么你需要使用不保存对象identity的方法)

SPImportSettings settings = new SPImportSettings();
settings.SiteUrl = "http://localhost:2001";
settings.FileLocation = @"c:\export";
settings.FileCompression = false;
settings.RetainObjectIdentity = true;

SPImport import = new SPImport(settings);

import.Run();  

 

跟export过程相似, 我们首先创建一个对象, 并配置import. 这可以通过SPImportSettings 来完成.

 

下面是关于我在import中使用的配置的简短解释:=

  • SiteUrl - 这就是Import过程要使用的目的站点集的URL地址.

  • FileLocation - 这就是保存需要被import的数据的文件夹的位置.

  • FileCompression - 这个属性定义了exported的数据是否使用了压缩格式.

  • RetainObjectIdentity - 这个属性定义了是否在import的过程中要保存对象的identity. 如果这个值是true, 那么对象的identity就会被保留下来. 意味着imported的items的GUID和URL会和exporting server的是一样的. 注意, 这意味着所有imported的对象的parent objects必须已经在目标的数据库中存在并可用. 如果这个值是false, 那么对象们会在import的过程中得到一个新生成的Guid, 还有, 它还有可能在import过程中控制imported的root objects. 我们稍后讨论.

 

2) Change the Parent of the imported objects during Import

----------------------------------------------------------

让我们假设我们使用part 2中的第三点的方法, 从源站点集已经exported了一个列表. 现在我们想要import一个列表到目标站点集中的一个不同的站点上. 目标站点集是否与源站点集相同无关紧要, 目标站点集于源站点集是否是在同一个database中也不重要. 目标站点集是否与源站点集在同一个farm也不重要.

 

如果你从一个数据库中export了一个item(比方说一个列表), 而没export它的parent,  那么这个exported item就会在包中称为orphaned(孤儿). 一个包中可以包含多个不同的orphaned对象(比如说你export了多个不同的列表或者列表项).

 

Import方法允许我们为每一个export package中的orphaned的对象定义一个新的parent. 意味着如果你选择了export web A 和 web B, 其中B是A的子站点, 那么你仅能修改web A的parent. web B的parent永远都会是web A, 因为web B在export package中不是orphaned.

 

There are actually two methods that can be used to assign a new parent to orphaned objects:

实际上有两种方法可以用来assign新的parent给orphaned的对象:

 

第一种方法- 所有orphaned的对象都应该被import到相同的子站点下

 

如果所有的items都需要被添加到相同子站点的时候, 这种方法比较适合. 比如说: 如果你export了几个列表和文档库(或者是从其他源站点来的列表和文档库), 现在你想把它们添加到相同的子站点下.

SPImportSettings settings = new SPImportSettings();
settings.SiteUrl = "http://localhost:2001";
settings.WebUrl = "http://localhost:2001/MyDestWeb";
settings.FileLocation = @"c:\export";
settings.FileCompression = false;
settings.RetainObjectIdentity = false;

SPImport import = new SPImport(settings);
import.Run(); 

 

要使得这个可以正常工作, 需要两个非常重要的配置:

  • WebUrl - 这个属性定义了export package中的所有orphaned对象的parent web. 如果package中包含了orphaned的文档, 那么这个方法不能被使用, 因为站点不能作为文档的parent. 文档的parent要么应该是列表, 要么就应该是文件夹.

  • RetainObjectIdentity - 这个属性定义了是否要保存对象的identity. 如果值为false, 那么对象将会得到一个新生成的Guid, 并且他可以在为imported的orphaned的对象指定parent时使用.

第二种方法- 为每一个orphaned的对象指配一个单独的parent.

 

这个方法比第一个要灵活一些, 但是也需要更多的代码. 这里, 在import process已经从import package中收集好了orphaned的对象的列表之后, 它需要拦截住import的进程, 来指配一个新的parent给每一个orphaned的对象.

 

可以通过一个自定义的event handler来完成这一点:

static void OnImportStarted(object sender, SPDeploymentEventArgs args)
{
    SPSite site = new SPSite("http://localhost:2001");
    SPWeb web = site.RootWeb;

    SPImportObjectCollection rootObjects = args.RootObjects;
    foreach (SPImportObject io in rootObjects)
    {
        io.TargetParentUrl = web.Url;
    }

    web.dispose();
    site.dispose();
}  

上面的event handler为所有的orphaned的对象进行了一个"re-parenting"的工作, orphaned的对象是event参数中的RootObjects集合中的对象. 上面的例子中, 我们实际上做的与第一种方法中的事情是一样的, 我们为所有的对象指配了而一个固定的web作为parent. 但是, 你可以很容易地在event handler中扩展这个逻辑, 为不同类型的对象指配不同的parent:

static void OnImportStarted(object sender, SPDeploymentEventArgs args)
{
   SPSite site = new SPSite("http://localhost:2001");
   SPWeb web = site.RootWeb;
   SPList list = web.Lists["MyDocLib"];

   SPImportObjectCollection rootObjects = args.RootObjects;
   foreach (SPImportObject io in rootObjects)
   { 
      if (io.Type == SPDeploymentObjectType.ListItem)               
      {                                                             
         io.TargetParentUrl = list.RootFolder.ServerRelativeUrl;    
      }                                                             
      if (io.Type == SPDeploymentObjectType.List)                   
      {                                                             
         io.TargetParentUrl = web.Url;                              
      }                                                             
      ...                                                           
   }
 
   web.dispose();
   site.dispose();
}  

正如你看到的, eventhandler可以被很轻松地扩展. 除了看object type以外, 你还可以查看原始的TargetParentUrl 来确定原来是放在哪里的, 然后把这个信息融入到你的"分配"逻辑中去. 现在我们需要看一下如何能把这个event handler与import process 挂钩起来. 可以这样做:

static void ImportDocLibItem()
{
    SPImportSettings settings = new SPImportSettings();
    settings.SiteUrl = "http://localhost:2001";
    settings.FileLocation = @"c:\deployment5";
    settings.FileCompression = false;
    settings.RetainObjectIdentity = false;

    SPImport import = new SPImport(settings);

    EventHandler<SPDeploymentEventArgs> eventHandler = new EventHandler<SPDeploymentEventArgs>(OnImportStarted);
    import.Started += eventHandler;

    import.Run();
} 

正如你看到的, 你需要在开启import process之前, 注册event handler到import class上.

 

有好几个event handlers可以被注册到import上, MSDN上有更多更详细的信息:

http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.deployment.spimport_events.aspx

相似地, 如果需要的话一些event也可以被注册到export上:
http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.deployment.spexport_events.aspx


 

3) Importing using compression

--------------------------------------------------------

当使用压缩选项的时候, SPImportSettings 对象的一些其他设定需要跟随着进行调整:

SPExportSettings settings = new SPExportSettings();

settings.FileLocation = @"c:\export";
settings.FileCompression = true;
settings.BaseFileName = "ExportedItems.cmp";

 

这里是关于一些属性的解释:

  • FileCompression - 指定了内容是否是以压缩的CAB文件提供过的, 还是未压缩的.

  • FileLocation - 这个属性定义了在哪里存放export了的文件. 如果使用了压缩, 那么它就定义了生成的压缩的content migration pack(CMP)文件的包位置了.

  • BaseFileName - 这个属性仅在开启了压缩的时候才用得上. 它定义了压缩了的content migration pack 文件的名字. 默认的后缀(如果没有指定的话), 是"cmp". 如果超过了文件尺寸的最大值, 一个新的文件会在BaseFileName 的基础上生成, 后面带一个整形数值. 举个例子: 根据上面的配置, 下一个文件应该是ExportedItems1.cmp

第四部分将会介绍一些具体的secnarios, 在move的场景下调整链接啦. 比如说, 一个图片被移动到一个新位置, 你想要调整所有引用到这份图片的页面的链接.

 

摘译自:

Deep Dive into the SharePoint Content Deployment and Migration API - Part 4

http://blogs.technet.com/stefan_gossner/archive/2007/08/30/deep-dive-into-the-sharepoint-content-deployment-and-migration-api-part-4.aspx

原文地址:https://www.cnblogs.com/awpatp/p/1671584.html