使用 SharePoint API 自动部署 Web 应用程序

 SharePoint 部署基础知识

  部署自定义 Web 部件

  自定义站点标记

  部署列表、窗体和报告

  本文使用了以下技术:

  SharePoint

使用 SharePoint API 自动部署 Web 应用程序目录

  SharePoint 部署基础知识

  Web 应用程序置备和设置

  管理 Web.config

  自定义 Web 部件

  简化的站点标记

  设置列表

  窗体和报告部署

  下一步要做什么?

  在 2008 Office 系统 开发人员会议上,一位演示者通过形象的比喻描绘了 .NET 开发人员对 SharePoint® 的第一印象,他认为这就好像是一位有经验的登山者站在一堵 100 英尺高的平滑墙壁前试图找到正确的攀登方法。许多 Microsoft 产品都提供了一组多样的任务完成方法,部署自定义 SharePoint 应用程序就是这方面的一个典型示例。由于 SharePoint 是一个非常复杂的综合应用程序平台,因此对于从未使用过它的用户而言,部署时可能会遇到一些困难。

  在本文中,我们将为您演示如何利用 SharePoint API 来自动部署自定义 SharePoint 应用程序。通过这种方法,您可以不必创建和维护自定义站点的定义。您可以借助更具模块化的一组组件在源控制系统中进行部署和管理(源控制系统是连续集成工作不可或缺的一部分)。最后,您要使用一个 Microsoft 将在未来几年内不断改进的模型。

  我们将阐述如何利用 SharePoint 对象模型来自动化从 Web 应用程序创建到 Feature 激活等环节的部署。本文中包含的 Visual Studio® 代码工程提供了一些代码示例,它们展示了在自定义部署中自动化一些关键任务的方法。

  随后我们还将对 Microsoft 以及 SharePoint 开发人员社区的成员所提供的工具和技术进行探讨,我们发现这些工具和技术对您实现完全自动化的部署非常重要。

  SharePoint 部署基础知识

  解决方案和 Features

  解决方案打包框架可将用来扩展 WSS 的所有组件捆绑到一个新文件中,称为解决方案文件。解决方案文件是一个带有 .wsp 扩展名的 .cab 格式的文件,其中包含在 SharePoint 框架中部署各种解决方案部件的指令清单。

  这些解决方案将被添加到 SharePoint Web 场并部署到一个或多个 Web 应用程序中。此任务可通过 Stsadm 实用工具或 SharePoint 对象模型来完成。

  Features 是用来扩展 SharePoint 解决方案的基础组件。它们提供了在 SharePoint 中修改功能的方法,从向库中添加 Web 部件,到启用 Reporting Services 集成等。

  Features 针对单一作用域(场、Web 应用程序、站点集或站点等)进行激活。Feature 作用域由 Feature 元素的 Scope 属性进行设置。Features 只有在安装后才能激活,同时必须在针对某个作用域激活后才能使用它们。此外,在卸载 Features 前必须先将其停用,除非它们的作用域是 Web 应用程序或场。

  一个需要认真考虑的问题是对于本文所讨论的自动化任务,您打算在 Feature 内部如何限定其作用域。下图说明了各种自动化任务适用的作用域。

  从自动化部署角度看,了解如何通过编程方式来控制 Feature 的状态非常重要。您可以使用 Stsadm 来激活和停用 Feature,也可以通过编程方式实现此目的。通过以下代码可枚举场中的所有 Feature 并查看其显示名称和作用域:

foreach (SPFeatureDefinition definition in
 SPFarm.Local.FeatureDefinitions) {
 Console.WriteLine("Title: {0}, Scope: {1}",
  definition.DisplayName,
  definition.Scope.ToString());
}

  要通过编程方式激活 Feature,可将 Feature 添加到 Feature 集合中,添加级别应该是 Feature 在创建时所在的作用域,如下例所示:

SPSite site = new SPSite(http://msdn.fabrikam.com:45001);
SPFeatureDefinition definition =
 SPFarm.Local.FeatureDefinitions["MyFeature"];
if (definition != null &&
 definition.Scope == SPFeatureScope.Site) {
 site.Features.Add(definition.Id, true);
}

  自动化任务的范围

 

自动化任务参数名称是否创建解决方案?作用域
创建 Web 应用程序和根 WebCreateWebApp不适用
Web.config 管理AddVerifyElement、AddVerifyAttrib、RemoveTrackedItem(在 Feature 的 FeatureDeactivating 事件中)Web 应用程序
将主题应用到站点集合ApplyThemetoSiteCollection单个主题的站点或 Web
设置母版页和 cssSetMasterPageandCSS单个主题的站点或 Web
从导航中排除项目ExcludeSiteFromNavigation站点或 Web
创建 WebCreatePublishingWeb站点
创建页面CreatePublishingPageWeb
添加全局导航节点AddGlobalNavigationNodeWeb
将 Web 部件添加到页面AddListViewWebPartWeb
创建和修改列表CreateList、AddItems、CreateViewWeb

 

  从 Windows® SharePoint Services (WSS) 3.0 和 Microsoft® Office SharePoint Server (MOSS) 2007 版开始,Microsoft 对 SharePoint 部署基础结构做了重大改进。在这一部署基础结构中,主要组件都是来自 Microsoft.SharePoint.Administration 和 Microsoft.SharePoint 命名空间以及 SharePoint 解决方案部署框架中的类。

  Microsoft 还改进了站点定义和站点模板的工作原理及其自定义方式。乍看起来,似乎可以使用所有这些功能来支持您的部署,但仔细想想却并非如此。如果您打算以自动化的、集中的方式来部署高度自定义的门户应用程序,则应该摒弃站点模板,甚至应该重新考虑涉及自定义站点定义的部署策略。

  大多数有经验的 SharePoint 开发人员可能都会同意我们在站点模板自定义方面的观点。它们只适合一些简单的自定义,对重大的自定义它们并不适合,因为页面呈现性能可能会受到影响。模板自定义采用与发起站点定义不同的存储方式,在 SharePoint 数据库中以 .stp 文件的形式保留,而不是由文件系统提供。页面呈现出来以后,.stp 会在运行时与文件系统中的底层站点定义合并。

  更令有经验的 SharePoint 开发人员吃惊的可能是我们有关摒弃自定义站点定义的建议。出于多种原因,Microsoft 强烈建议开发人员不要自定义现成的站点定义。未来的 Service Pack 可能覆盖现有的站点定义,如果不舍弃这些自定义,届时可能无法迁移到下一版本的 SharePoint。

 

即使您遵循 Microsoft 的建议不采用现成的站点定义,还有其他一些原因促使您避免自定义站点定义。对于高度自定义的部署,站点定义可能会变得庞大且难于管理。完整的站点定义可包含多个 Web。在每个 Web 中都有一个或多个页面,这些页面中包含各种元素,例如 Web 部件区域、Web 部件、模块、列表定义和导航组件等。onet.xml 文件维护着与所有 Web 有关的配置信息。随着需求和配置的变化,此文件的维护工作很快就会成为您的梦魇。以我们的经验来看,为了容纳自定义信息,它需要包含 300 到 600 行的 XML。如果您的站点定义中包含五个自定义 Web,则您要维护的 XML 行数将猛增到 1,500 到 3,000 个。

  SharePoint API 和解决方案部署框架对此提供了一个更好的答案。解决方案是 SharePoint 的部署包,它们几乎可以涵盖部署到 SharePoint 所需的全部信息。解决方案的一个重要部分被称为 Feature(尽管从技术角度来说并非所有实例都需要)。解决方案是一个可部署的软件包,而 Feature 定义了软件包的各个方面,这将允许它使用 SharePoint 对象模型和其他托管代码,并使其自身在 SharePoint 层次结构(场、Web 应用程序、站点集合或 Web 级别)中突显出来。

  Microsoft 提供了一个用来自动化 SharePoint 初始安装的模型。请注意,配置 SharePoint 实例或场的任务通常由管理员来完成。下一步是为自定义门户应用程序创建 Web 应用程序和站点。

  这些任务可以通过使用 SharePoint 管理中心来完成,但也可以通过 Microsoft.SharePoint.Administration 命名空间中的 SPWebApplicationBuilder 和 SPWebApplication 类来自动化它们。默认情况下,SharePoint 命令行管理工具 (Stsadm) 不支持 Web 应用程序创建。通过自动化这些任务,不仅可以加快它们的完成速度,还可以确保单个服务器或场实施在自定义解决方案从开发向生产过渡时保持一致。

  当 SharePoint 创建 Web 应用程序及生成顶级站点集合和根 Web 时,在后台需要执行大量的工作。创建典型 Web 应用程序时,SharePoint 执行以下操作:

  在 SharePoint 配置数据库中为 Web 应用程序创建一个唯一条目并为该条目指定一个 GUID

  在 IIS 中创建和配置 Web 应用程序

  创建用于存储 Web 应用程序页面和相关资源的根文件夹

  创建和配置 IIS 应用程序池

  配置身份验证协议和加密设置

  为 Web 应用程序分配一个默认替代访问映射

  为 Web 应用程序创建第一个内容数据库

  将搜索服务与 Web 应用程序相关联

  为 Web 应用程序分配一个名称,它将显示在 SharePoint 管理中心的 Web 应用程序列表中

  为 Web 应用程序指定常规设置,例如最大文件上载大小和默认时区

  或者,您可以将替代访问 URL 添加到 Web 应用程序中。这只是在创建了 Web 应用程序之后您可能想要完成的许多可选任务之一。创建站点集合时,SharePoint 还会根据站点定义来创建顶级站点,并为该站点设置常规属性,例如站点标题和站点所有者等。手动完成这些任务可能需要一段时间,因为涉及的数据输入量较大,而且执行起来又乏味又容易出错。自动化此任务可加快任务的完成速度并确保各环境间的数据一致性。

  正如您所料,自动化此任务会涉及大量的代码。文中显示的代码并非全部,您应下载本文随附的代码。您可在 SPDeployTests 项目中找到 CreateWebApp 方法。(在尝试运行控制台应用程序之前,请务必阅读代码示例中包含的必备文档。)在这里我们将强调代码的一些关键元素并调用一些特定的项目,如果不注意的话,它们可能会在您自动化此部分自定义门户部署时发生问题。

  还有一件事情要注意:一定要从 SharePoint 服务器运行此代码。此代码不是设计用于远程运行的。以我们的经验来看,最好在场中的 SharePoint 服务器上运行自动化后的 SharePoint 部署例程。

  Web 应用程序置备和设置

  为了创建新的 Web 应用程序,首先要从 SPWebService 对象调用 AdministrationService.Farm 属性。调用 Farm 属性将返回一个 SPFarm 对象。SPFarm 对象位于配置层次结构的顶部,它管理着 SharePoint 场中的所有服务器、服务和解决方案。在获得了 SPFarm 对象后,即可将其传递给 SPWebApplicationBuilder 构造函数:

SPFarm farm =
 SPWebService.AdministrationService.Farm;
SPWebApplicationBuilder webAppBld =
 new SPWebApplicationBuilder(farm);

  SPWebApplicationBuilder 是用来创建 SharePoint Web 应用程序的工作类。它可以完成先前概述的用于创建 Web 应用程序的所有步骤。要想利用这个类,可设置 SPWebApplicationBuilder 类的属性,然后调用其 Create 方法,这将返回新 Web 应用程序的 SPWebApplication 对象:

SPWebApplication webApp = webAppBld.Create();

  使用 SPWebApplication 类来设置附加属性,然后调用 Update 方法将所有更改发送回场中。最后,调用 SPWebApplication Provision 方法来创建 IIS Web 应用程序和应用程序池。

  在代码中以合适的时间和正确的顺序来调用这些方法至关重要。因此,请务必仔细研究本文中的代码示例以真正领会它们。

  设置 Web 应用程序的属性时,有几点需要加以考虑。首先,要清楚每个设置的实际意义。如果不确定某个设置的含义,例如,假如您在 Windows NT LAN Manager (NTLM) 身份验证和 Kerberos 之间无法做出取舍,应与 SharePoint 基础结构专家一起做出最终决定。其次,一些属性的设置可能需要一些技巧,或者难于判断其影响。例如,以下是设置 SPWebApplicationBuilder 对象的 ID 属性的示例:

webAppBld.Id = new Guid("3798E478-4E16-4856-A152-F05EF8C2C777");

  与此对象中的大多数属性一样,SharePoint 会将此属性设置为默认值或指定一个值。在本例中,SharePoint 将生成一个唯一的 GUID,并将其与 Web 应用程序一同存储到配置数据库的 Objects 表中。您可以对 SharePoint 配置数据库运行以下查询,以查看所有 Web 应用程序对象及其关联的 ID GUID:

SELECT id, name FROM OBJECTS
WHERE Properties
LIKE '%Microsoft.SharePoint.Administration.SPWebApplication%'

  您可以指定此值,也可以让 SharePoint 分配一个值。

  如果您打算配置新应用程序池并分配一个用户帐户(这是设置 SharePoint 的首选方法),则有一些需要特别加以注意的问题。首先,在工作组中,ApplicationPoolUserName 是本地用户的名称,而不包含预置的服务器名称。如果 SharePoint 是 Active Directory® 域的一部分,则应使用 Active Directory 用户帐户并为此属性预置该域名称:

@"domainnameusername"

  对于 ApplicationPoolPassword,必须为该值传递 SecureString 数据类型。以下是构建安全密码的模式:

// build the password as a secure string
SecureString appPoolPwd = new SecureString();
appPoolPwd.AppendChar('k');
appPoolPwd.AppendChar('E');
// more of the same to build-up the password
appPoolPwd.MakeReadOnly();

  在尝试创建 Web 应用程序之前,请确保为这些值分配的用户名和密码与已在身份库中设置好的值匹配。

  下一个属性 ApplicationPoolId 只是应用程序池在 IIS 中显示的名称。值得注意的是,在 WSS 3.0 SDK 帮助文件中误将 ApplicationPoolId 声明为标识应用程序池的 GUID。有人会认为它是 IIS 中应用程序池列表中的唯一标识符,但实际上它既不是全局唯一标识符也不是我们通常认为的 GUID 格式。

  将搜索服务实例与新 Web 应用程序相关联时,会遇到另一个障碍。图 1 显示了如何完成该任务,然后又进一步解释了如何查找正确的搜索服务实例。

使用 SharePoint API 自动部署 Web 应用程序Figure1关联搜索服务实例

// get the server hosting the search service
SPServer server = new SPServer("myServer");
// get the office SharePoint server search instances
SPSearchService srchService =
 SPFarm.Local.Services.GetValue<SPSearchService>("SPSearch");
// get the proper instance of the search service
SPSearchServiceInstance searchServiceInst =
 (SPSearchServiceInstance)srchService.Instances[new Guid(
  "C22E9545-71B4-471F-81A7-A213D5A7F8B2")];
// set the search service instance to crawl the web application
webAppBld.SearchServiceInstance = searchServiceInst;

  SharePoint 中有一个服务层次结构,在此结构中,一个服务会包含多个执行具体操作的服务实例。遗憾的是,要想查找某个搜索服务实例可能会比较困难,因为这些实例可能有类型名称,但其 Name 和可能的 DisplayName 属性却是空值。因此,将 GUID 传递给图 1 中的 Instances 集合是设置此值的一种方法。

  有两种方法可以查找某个搜索服务实例的正确 GUID。第一种方法是查询 SharePoint 配置数据库中的 Objects 表,如以下代码所示:

SELECT id, name, properties FROM OBJECTS
 WHERE (Properties LIKE
  '<object type=' +
  '"Microsoft.SharePoint.Search.' +
   'Administration.SPSearchServiceInstance%')
 ORDER by ID

  另一种方法是在代码 SPDeployTests 项目中运行 EnumFarmServices 方法,该项目包含在代码下载中。图 2 显示了我们的其中一个服务器的输出结果,相应的搜索服务实例以红色表示。

Figure2SPSearch 实例

Name: SPSearch
ID: 7fd9c4b0-25c2-4867-b716-cd3b61e7a08e
DisplayName: SPSearch
Instance 1
Name:
ID:c9043683-a431-4cc7-b30a-fa52163f649b
Type name:Windows SharePoint Services Search
DisplayName:
Instance 2
Name:
ID:c22e9545-71b4-471f-81a7-a213d5a7f8b2
Type name:Windows SharePoint Services Search
DisplayName:Search index file on the search server

  如果您要通过代码来配置搜索服务实例,但却未选择对应的搜索服务实例,Web 应用程序创建将会失败,并会出现数据库外键相依性错误。还有一些非常重要的设置可用来配置 Web 应用程序。代码下载中提供了一些帮助您入门的示例。

  创建第一个站点集合非常简单明了。但是,在 Web 场环境中创建顶级站点集合之前,应该先重置 IIS(使用 iisreset /noforce)。图 3 显示了创建顶级站点集合的方法。为简单起见,我们将一些变量移到了 Add 方法的输入参数中。在 Add 方法的开头,声明和描述了一些有趣的变量或具有潜在迷惑性的变量。

使用 SharePoint API 自动部署 Web 应用程序Figure3创建站点集合

// for the top-level site
string url = "/";
// this is the MS language Locale ID.
// see http://www.microsoft.com/globaldev/reference/lcid-all.mspx
uint LCID = 1033;
// this is the site template for the
// Publishing Site - Collaboration Portal merged site definition
string template = "SPSPORTAL";
// create a site collection with an out of the box site definition
 SPSite MSDNSiteCollection = webApp.Sites.Add(url,
 "The MSDN site collection", "a description of this site",
 LCID, template, "mydomainmyLoginName",
 "my owner name", "my email address");
// close the site collection
MSDNSiteCollection.Close();

  管理 Web.config

  大多数 SharePoint 代码项目的一项常见任务就是更新每个 Web 应用程序的 web.config。虽然在小型实现中可以手动更新,但这并不适用于大型的、多开发人员的项目。一种可行的方案是在源控制系统中保留一份 Web 应用程序的 web.config 副本,然后让开发人员签出文件、针对项目进行更新然后再将其签入。接下来,您可以定期或在发生特定事件(如签入)后,将 web.config 部署编写到 Web 前端服务器脚本中。但是,此方法不能利用 SharePoint 的功能来管理 web.config 设置。

  如果使用 SharePoint API 来更新 web.config,则被添加到 SharePoint 场的新前端会接收对 web.config 的更新,而 SharePoint 会在现有前端中维护这些设置。有两种常见的方法可通过编程方式将 SharePoint 托管更新引入到 web.config 中。对于 Web Part SafeControl 条目和自定义访问控制策略,可利用 SharePoint 解决方案打包框架。对于唯一条目,可使用 Microsoft.SharePoint.Administration 命名空间中的 SPWebConfigModification 类。

  图 4 显示了如何使用 SPWebConfigModificationType.EnsureChildNode 将 XML 子元素添加到 web.config 文件中。在本例中,SPWebConfigModification 类用来确保 <add key = "key01" value = "Setting01" /> 元素显示在 appSettings 元素的内部。代码中的注释说明了如何得到这一结果。请注意,在 xmlValue 变量中, 'key01' 和 'Setting01' 值使用的是单引号。使用单引号可使代码更加清晰,当这些值被写入每个前端 Web 服务器时,SPWebConfigModification 类负责将其改为双引号。

使用 SharePoint API 自动部署 Web 应用程序Figure4在 Web.config 中添加子节点

// get the webApp
SPWebApplication webApp =
 new SPSite("http://msdn.fabrikam.com").WebApplication;
// the element to add or verify contains
// the following name and attributes:
string elementName = "add[@key='key01'][@value='Setting01']";
// the location where the new element should be added or verified is
// present in the target web.config
string xPath = "configuration/appSettings";
// the value exactly as it should be written
string xmlValue = @"<add key = 'Key01' value = 'Setting01' />";
SPWebConfigModification modification =
 new SPWebConfigModification(elementName, xPath);
// this name determines who can modify this entry -
// only the owning name (typically a fully qualified program name,
// GUID or possibly the WebConfigModificationFeatureReceiver.OwnerID
// name can modify the entry
modification.Owner = "SPWebConfigTestAddChild";
// for identical entries, this controls what order the entry is made
// typically fine to leave this at 0
modification.Sequence = 0;
// EnsureChildNode means to add or verify that the child node is present
// as specified by the Value property next
modification.Type =
 SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
// the actual value to write
modification.Value = xmlValue;
// add the modification to the SPWebConfigModification collection
webApp.WebConfigModifications.Add(modification);
// check all web applications on the farm front ends to ensure
// that the web.config modification(s) have been applied
webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
// propagate changes in web application across the farm
webApp.Update();

  您也可以使用 SPWebConfigModification 类来添加、更改属性值或确保 XML 节点内的属性值显示在 web.config 中。如果要写入或验证的 XML 属性在 web.config 文件中是唯一的,则这会非常简单。例如,您可能希望在下面唯一的 XML 片段中将 autoDetect 的属性从 true 改为 false:

<system.net>
 <defaultProxy>
  <proxy autoDetect="true" />
 </defaultProxy>
</system.net>

  在本例中,SPWebConfigModification 构造函数的内容如下所示:

SPWebConfigModification modification =
 new SPWebConfigModification(
 "autoDetect", "system.net/defaultProxy");

  随后 SPWebConfigModificationType 枚举被设置为 EnsureAttribute,如下所示:

modification.Type =
 SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute;

  EnsureChildNode 和 EnsureAttribute 是此枚举中将要用于更新的两个值。有许多博客条目都建议使用 EnsureSection(第三个枚举)将整节写入 web.config。遗憾的是,删除这些条目会非常麻烦。

  除了提到的这些差别以外,用来写入属性的模式与用来将一个或多个 XML 节点写入 web.config 的模式之间几乎没有差别。当某个父元素中有多个同名元素(例如,appSettings 元素中有多个 add 子元素)时,写入或验证某个属性时会稍微复杂一些。在这种情况下,xPath 字符串会给出正确的元素。

  请看以下 appSettings 元素:

<appSettings>
 <add key="FeedCacheTime" value="300" />
 <add key="FeedPageUrl"
  value="/_layouts/feed.aspx?" />
 <add key="FeedXsl1"
  value="/Style Library/Xsl Style Sheets/Rss.xsl" />
 <add key="key01" value="Setting01" />
</appSettings>

  要更改第四个 add 元素的值属性,请使用指定子元素的 xPath 语句,如下所示:

configuration/appSettings/add[4]

  xPath 语法是准确判定要更新内容的关键。可通过 msdn2.microsoft.com/ms256115 获得有关 xPath 语法的参考信息。

  图 5 显示了如何修改值属性或验证值属性在 appSettings 元素的第四个 "add" 子元素中已设置为 Setting02。为简单起见,我们删除了图 4 中显示的注释。现在这些设置已添加完毕,您可以在运行目标 Web 应用程序的任何 Web 前端检查 web.config 文件。

使用 SharePoint API 自动部署 Web 应用程序Figure5修改子节点的第四个属性

SPWebApplication webApp =
 new SPSite("http://msdn.fabrikam.com").WebApplication;
// the attribute's name to which a value will be added,
// changed or verified:
string attributeName = "value";
// the location of the element that should be modified or verified
string xPath = "configuration/appSettings/add[4]";
// the value of the attribute as it should be written
string attributeValue = "Setting02";
SPWebConfigModification modification =
 new SPWebConfigModification(attributeName, xPath);
modification.Owner = "SPWebConfigTestModifyAttribute";
modification.Sequence = 0;
// EnsureAttribute means to add or verify that an attribute value is
// present as specified by the Value property next
modification.Type =
 SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute;
modification.Value = attributeValue;
webApp.WebConfigModifications.Add(modification);
webApp.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
webApp.Update();

  图 6 显示了在 Web 应用程序中如何通过枚举 WebConfigModfications 属性所包含的设置集合来了解由 SharePoint 管理的设置。从长远角度看,手动删除或更改 web.config 中由 SharePoint 管理的条目不会带来任何好处。SharePoint 会跟踪这些条目,确保每次 WSS 服务重新启动时这些条目都位于 web.config 中。

使用 SharePoint API 自动部署 Web 应用程序Figure6枚举修改列表

SPWebApplication webApp =
new SPSite("http://msdn.fabrikam.com").WebApplication;
// use the System.Collection collection class to get
// a collection of modifications in the configuration database
Collection<SPWebConfigModification> collection =
 webApp.WebConfigModifications;
// iterate the collection of modifications and return properties
// about the items
foreach (SPWebConfigModification item in collection)
{
Console.WriteLine("nitem {0}", collection.IndexOf(item));
Console.WriteLine("owner is: {0}", item.Owner);
Console.WriteLine("path is: {0}", item.Path);
Console.WriteLine("name is: {0}", item.Name);
Console.WriteLine("value is: {0}", item.Value);
Console.WriteLine("sequence is: {0}", item.Sequence);
}

  要删除条目,必须知道要修改的 Owner 属性的值。然后,即可使用 SPWebApplication 的 WebConfigModificatons 属性的 Remove 方法,删除由 SharePoint 维护的条目。有关删除条目的详细信息,请参阅 Vincent Rothwell 的博客,网址为 blog.thekid.me.uk/archive/2007/03/20/removing-web-config-entries-from-sharepoint-using-spwebconfigmodification.aspx。在本专栏的代码下载中还有一个示例,显示了如何删除条目。

  使用 SPWebConfigModification 类来修改 web.config 可能需要一些技巧。有一些需要加以注意的问题。您可以访问 Reza Alirezaei 的博客 (blogs.devhorizon.com/reza/?p=459) 和 Mark Wagner 的博客 (www.crsw.com/mark/default.aspx) 来阅悉最常见的问题。我们强烈建议您在开始使用该类之前仔细阅读这些文章。在研究完毕之后,请务必在隔离环境、共享开发环境以及 Web 场开发环境中仔细测试您的修改以及使用 SPWebConfigModification 类删除这些修改的能力。

  即使具备使用 SharePoint 来管理 web.config 设置的能力,在某些情况下,您可能还是会希望抛开 SharePoint API 来管理设置,例如,当管理唯一的敏感凭据信息节时。在这种情况下,应考虑使用 System.Web.Configuration 命名空间中的 WebConfigurationManager。要加密该信息,可使用 aspnet_regiis 实用工具或使用 System.Configuration 命名空间中的 AppSettingsSection 类。您可以访问 c-sharpcorner.com/UploadFile/neo_matrix/EditWebConfig05042007091116AM/EditWebConfig.aspx 来阅悉如何使用 C# 2.0 编辑和加密 Web.Config 节的内容。

  自定义 Web 部件

  Microsoft 使用 Web 部件来构建解决方案打包和部署框架。端到端 Web 部件部署的关键在于 Web 部件部署文件,其正式名称是 Web 部件控制描述文件。有两种 Web 部件部署格式:.WebPart 和 .dwp。它们都是具有底层架构的 XML 文件。Web 部件控制描述文件(详见 msdn2.microsoft.com/library/ms227561(VS.80).aspx)对 .WebPart 架构做了介绍。

  .dwp 格式具有向后兼容性。它是 WSS 2.0 和 SharePoint Portal Server 2003 中所采用的 SharePoint Web 部件控制描述文件格式。尽管可以在 WSS 3.0 和 MOSS 2007 中将此格式用于 Web 部件的部署,但是如果您的目标是完全自动化 Web 部件部署,则应避免使用 .dwp。这是因为 .dwp 架构不包括完全自动化所必需的一些基本设置。例如,如果需要隐藏自定义 Web 部件的镶边(也称为样式),直接使用 .dwp 文件将无法实现此目的。

  开始创建自定义 Web 部件的方式会影响所生成的、预期用于部署组件的部署文件类型。让人惊讶的是,几乎没有什么指导来解释自动生成 .dwp 文件或 .WebPart 文件的具体情况。如果使用旧的 .dwp 格式将 Web 部件部署到 SharePoint,这时要想切换到 .WebPart 文件,我们发现的唯一途径就是卸载解决方案;如果未使用解决方案,则手动将 Web 部件从 SharePoint 删除、重新构建项目,然后使用 .WebPart 文件重新创建解决方案。

  有两种方法可用来确保自定义 Web 部件使用新的 ASP.NET .WebPart 格式进行部署。第一种方法是启动 Visual Studio 类项目。请注意,声明 Web 部件类时,请不要从 SharePoint Web 部件类继承 (Microsoft.SharePoint.WebPartPages.WebPart),而应从 ASP.NET Web 部件类继承,如下所示:

public class WebPart1 : System.Web.UI.WebControls.WebParts.WebPart

  Microsoft 在其大部分文档中都建议从 ASP.NET Web 部件类继承,这主要是因为从该类继承的 Web 部件“可能”既可以部署到 SharePoint,又可以部署到自定义 ASP.NET 门户。我们之所以说“可能”,是因为与 SharePoint 对象模型交互的 Web 部件可能会依赖于在 SharePoint 门户环境中的运行情况。如果不再需要 SharePoint Web 部件类所提供的少数几项功能中的一项,则可以在随后切换到从 SharePoint 命名空间继承。但是,在切换之前,应先创建 SharePoint 解决方案和 .WebPart 文件。

  第二种确保 .WebPart 部署文件自动创建的方法是使用 Visual Studio Extensions for WSS 3.0 或最新的 WSPBuilder Extension。如果使用这些工具和随附的 SharePoint Web 部件项目模板,则从 Web 部件类继承时使用哪个命名空间都无关紧要。

  有了 .WebPart 文件之后,在完全部署自动化过程中,接下来的步骤会对解决方案进行更多的处理,在本文中我们只做简单的说明。现在的关键是获取准备用于部署的 .WebPart 文件。

  尽管可以将元素手动添加到 .WebPart 文件中,但如果借助以下方法则会显著简化此工作。在 Web 部件的构造函数中,添加以下代码:

// make the web part deployment file exportable
this.ExportMode = WebPartExportMode.All;

  如果构建了 Web 部件,随后又进行了安装和配置,则您可以将 .WebPart 文件导出。您也可以在工具部件属性中进行此项设置,而不必在代码中声明。

  接下来,将 Web 部件安装到 SharePoint 或自定义 ASP.NET Web 应用程序中,并将其拖放到页面的 Web 部件区域内。(在本文的稍后部分,我们将介绍自动化初始 Web 部件部署的方法。)从 Web 部件的“Tool Part Properties”(工具部件属性)对话框中,根据您的意愿对 Web 部件在页面中的显示外观和运行方式进行配置。从 Web 部件的编辑菜单中单击“Export”(导出)。将导出的 .WebPart 文件保存到为 Web 部件创建的 Visual Studio 项目中。

  图 7 中显示了基本的 .WebPart 文件,它是按照先前概述的配置步骤使用 1.1 版的 Visual Studio Extensions for WSS 生成的。当这些设置配置完毕后,自定义工具部件属性的设置和含有这些属性的自定义工具部件也将显示在 .WebPart 导出结果中。

使用 SharePoint API 自动部署 Web 应用程序Figure7Web 部件 XML 文件

  配置之前

<?xml version="1.0" encoding="utf-8"?>
<webParts>
 <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
  <metaData>
   <!--
    The following Guid is used as a reference to the web part class,
    and it will be automatically replaced with actual type name
    at deployment time.
   -->
   <type name="5ad2f5ec-8c67-4ca9-b2fb-83c4dadd50c0" />
   <importErrorMessage>
    Cannot import WebPart1 Web Part.</importErrorMessage>
  </metaData>
  <data>
   <properties>
    <property name="Title" type="string">WebPart1 Web Part</property>
    <property name="Description" type="string">
     WebPart1 Description</property>
   </properties>
  </data>
 </webPart>
</webParts>

  配置之后

webParts>
 <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
  <metaData>
   <type name="WPUsingVSeWSS1dot1.WebPart1, WPUsingVSeWSS1dot1,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=9f4da00116c38ec5" />
   <importErrorMessage>
    Cannot import WebPart1 Web Part.</importErrorMessage>
  </metaData>
  <data>
   <properties>
    <property name="AllowClose" type="bool">False</property>
    <property name="Width" type="unit">170px</property>
    <property name="AllowMinimize" type="bool">False</property>
    <property name="AllowConnect" type="bool">True</property>
    <property name="ChromeType" type="chrometype">None</property>
    <property name="TitleIconImageUrl" type="string" />
    <property name="Description" type="string">
     WebPart1 Description</property>
    <property name="Hidden" type="bool">False</property>
    <property name="TitleUrl" type="string" />
    <property name="AllowEdit" type="bool">True</property>
    <property name="Height" type="unit">25px</property>
    <property name="HelpUrl" type="string">
     /pages/SimpleHelp.htm</property>
    <property name="Title" type="string">WebPart1 Web Part</property>
    <property name="CatalogIconImageUrl" type="string" />
    <property name="Direction" type="direction">NotSet</property>
    <property name="ChromeState" type="chromestate">Normal</property>
    <property name="AllowZoneChange" type="bool">False</property>
    <property name="AllowHide" type="bool">False</property>
    <property name="HelpMode" type="helpmode">Modal</property>
    <property name="ExportMode" type="exportmode">All</property>
   </properties>
  </data>
 </webPart>
</webParts>

  遗憾的是,如果 Web 部件使用连接提供者或连接使用者接口,则必须通过编程方式绑定 Web 部件,或采取更常见的处理方式,允许通过 Web 部件的编辑下拉菜单在运行时建立连接。工具部件连接设置不会保存到导出文件中。如果不想将 Web 部件绑定到 Web 部件代码中,可使用 SharePoint 对象模型自动化此部分的部署。图 8 显示了如何通过编程方式连接两个 Web 部件的提供者和使用者连接点。

 

Figure8连接 Web 部件

// webPartPage is an SPFile object
// page check out is required before modifying publishing pages
webPartPage.CheckOut();
// get the web part manager for the page
SPLimitedWebPartManager webPartMgr =
 webPartPage.GetLimitedWebPartManager(PersonalizationScope.Shared);
// providerWebPart and consumerWebPart are of type
// System.Web.UI.WebControls.WebParts.WebPart
// providerConnection is type
// System.Web.UI.WebControls.WebParts.ProviderConnectionPoint
// consumerConnection is type
// System.Web.UI.WebControls.WebParts.ConsumerConnectionPoint
// connect the web parts
 webPartMgr.SPConnectWebParts(providerWebPart,
 providerConnection,  consumerWebPart, consumerConnection);
// update, check in, and publish the page
webPartPage.Update();
webPartPage.CheckIn("");
webPartPage.Publish("");

  您可以从 SPLimitedWebPartManager 的 GetConsumerConnectionPoints 和 GetProviderConnectionPoints 方法所返回的集合中获取相应 Web 部件的使用者和提供者连接点。如果连接类型是相互兼容的,则此方法会很有效。如果各连接类型之间不兼容(例如当您需要将筛选值从 QueryStringFilter Web 部件传递到使用者 Web 部件时),应将转换程序添加到 SPConnectWebParts 调用中,如下所示:

TransformableFilterValuesToFilterValuesTransformer
 transformer = new
  TransformableFilterValuesToFilterValuesTransformer();
webPartMgr.SPConnectWebParts(providerWebPart,
 providerConnection, consumerWebPart,
 consumerConnection, transformer);

  简化的站点标记

  我们已经讨论了有关创建 Web 应用程序和站点集合的内容。现在我们将关注点转移到如何修改默认站点外观上。有多种不同的方法可用来标记 MOSS 2007 站点,但我们现在只介绍其中一种置备和标记方法,它是在现成的 SharePoint 协作门户、发布页、自定义母版页、样式表、页面布局以及主题的基础上建立的。在关注发布站点的同时,还要记住其中的许多技术同样适用于非发布站点。

  首先有一点要注意:不要直接修改任何现成的 SharePoint 组件。每次都应该创建一个副本,然后将其移到单独的工作空间,再对此任务使用首选的代码编辑器进行编辑。

  SharePoint 母版页的实现方式与任何 ASP.NET 2.0 母版页的实现方式都完全一样。使用首选的工具创建完母版页后,将其上载到顶级 SharePoint 站点内的虚拟文件夹 /_catalogs/masterpage 中。然后,可以使用 Microsoft.SharePoint 命名空间中的 SPWeb 类将母版页应用到单个页面、站点或整个站点集合。MasterUrl 和 CustomMasterUrl 是 SPWeb 类中用来标识站点母版页的两个属性。这两个属性分别引用页面布局的 MasterPageFile 属性中的 ~masterurl/default.master 和 ~masterurl/custom.master。设置 MasterUrl 可改变站点内窗体和视图的系统母版页,设置 CustomMasterUrl 可影响站点内的发布页。正如您所料,更改系统母版页并不会影响地址中 /_layouts 以下的页面,例如“管理站点设置”页面和“访问被拒绝”页面。这些是从 application.master 或 simple.master 页面继承而来的。

  在 MOSS 2007 中,可使用 SPWeb 类的 AlternateCssUrl 属性来指定站点的重写样式表。WSS 站点不支持此选项,因此在该环境下可使用另一种方法,即在母版页或内容页面中指定 CSS 链接。如果要在站点中维护 CSS 文件,最好将其放在 /Style Library 中。当然其他位置也可以,只要在 SharePoint 中能通过 URL 路径访问即可。

  接下来的步骤是应用主题。主题是指对 SharePoint 用户界面的外观进行处理的方法,即使用 CSS 来应用新的颜色、样式和图像等。主题存储在 MOSS 服务器的 Program FilesCommon FilesMicrosoft SharedWeb Server Extensions12TEMPLATETHEMES 文件夹中。

  主题是在站点范围内应用的,它并不会被站点集合内的子 Web 继承。由于其作用范围的原因,主题会修改根 Web 内所有页面(包括“站点设置”页面)的外观。以下代码可设置站点集合内所有 Web 的主题:

// iterate all sites in the site collection
foreach (SPWeb webSite in MSDNSiteCollection.AllWebs)
{
 // apply the Lacquer theme
 webSite.ApplyTheme("Lacquer");
 // update the site
 webSite.Update();
}

  您可以将本例加以扩展,使其能够设置未从父站点继承设置的 Web 母版页和样式表。默认情况下,我们的方法会使所有新的子 Web 具有与顶级 Web 同样的样式设置。

  为发布的内容页面创建自定义的页面布局是另一种站点标记方法,它与母版页是相互配合的。有关标记 SharePoint 的信息,请参考 Heather Solomon 在博客中发表的与标记相关的帖子,登录起始页为 heathersolomon.com/blog/articles/sp2007.aspx。

  页面布局创建完毕后,必须将其上载到 /_catalogs/masterpage 库以及母版页中。图 9 中显示了如何通过从发布 Web 站点的可用布局列表中选择所需的页面布局来创建发布页。

使用 SharePoint API 自动部署 Web 应用程序Figure9从页面布局创建新页面

PageLayout myLayout = null;
// open a web site
SPWeb webSite = MSDNSiteCollection.OpenWeb();
if (PublishingWeb.IsPublishingWeb(webSite)) {
 // get the publishing web instance for this site
 PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
 // get the collection of publishing pages
 PublishingPageCollection ppages = publishingWeb.GetPublishingPages();
 // iterate the available page layouts until we find the one we want
 PageLayout[] layouts = publishingWeb.GetAvailablePageLayouts();
 for (int index = 0; index < layouts.Length; index++) {
  if (layouts[index].Name.Equals("my_page_layout.aspx",
   StringComparison.OrdinalIgnoreCase)) {
   myLayout = layouts[index];
   break;
  }
  }
 // add the page to the publishing pages collection
 newPage = ppages.Add("sample_page.aspx", myLayout);
 // set the page title
 newPage.Title = "Test Page";
 // update the page, check in and publish
 newPage.Update();
 newPage.CheckIn("");
 newPage.ListItem.File.Publish("");
 webSite.Update();
}

  修改导航是另一项常见的标记任务,因为它会影响用户能够看到的内容以及他们在站点层次结构中的浏览方式。Microsoft.SharePoint.Publishing 命名空间提供了多个以发布站点基础结构为目标的类,例如 PublishingWeb 和 PublishingPage。使用这些类,我们可以轻松地对各个站点的导航进行修改。

  如果希望子 Web 在全局导航中显示为根级站点,请先关闭从父站点的继承功能,如下所示:

publishingWeb.InheritGlobalNavigation = false;

  您可能还希望从全局导航中隐藏所有站点页面。将 IncludePagesInNavigation 设置为 false 会隐藏站点中的所有页面,无论 PublishingPage.IncludeInGlobalNavigation 属性是否设置为 true:

// do not show pages in navigation
publishingWeb.IncludePagesInNavigation = false;

  如果处理的并非是从 PublishingWeb 继承的默认站点,也可以从全局导航栏中隐藏它们。例如,如果使用协作门户模板创建一个站点集合并希望将新闻站点从全局导航中排除,可将该站点添加到站点的 __GlobalNavigationExcludes 属性中:

string globalNavExcludes = String.Empty;
SPWeb webSite = MSDNSiteCollection.RootWeb;
// _GlobalNavigationExcludes property contains a delimited string of
// GUIDs identifying the Id of each site to be excluded from global
// navigation
if (webSite.AllProperties.ContainsKey("__GlobalNavigationExcludes")) {
 globalNavExcludes =
  webSite.AllProperties["__GlobalNavigationExcludes"].ToString();
}
SPWeb newsSite = MSDNSiteCollection.AllWebs["News"];
// string is delimited "{GUID};{GUID};",
// use format code B to convert to string
globalNavExcludes += String.Concat(currentWeb.ID.ToString("B"), ";");
webSite.AllProperties["__GlobalNavigationExcludes"] = globalNavExcludes;
webSite.Update();

  要想只显示所需的节点以及对指向外部站点的节点和链接进行分组,将导航节点直接添加到 SPNavigationNodeCollection 是一种不错的方法。图 10 显示了如何将内部链接、外部链接和标题添加到全局导航栏中。本例介绍了 SPNavigation 类的某些属性,它们可决定链接在新窗口中是否开启,还会决定空 URL 的处理方式。

使用 SharePoint API 自动部署 Web 应用程序Figure10创建导航节点

SPWeb webSite = MSDNSiteCollection.OpenWeb("test", false);
if (PublishingWeb.IsPublishingWeb(webSite)) {
 // get the publishing web instance for this site
 PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(webSite);
 // get the collection of global navigation nodes
 SPNavigationNodeCollection navNodes =
  publishingWeb.GlobalNavigationNodes;
 // add an internal link as the first node
 SPNavigationNode internalLink = new SPNavigationNode("Help",
  "Pages/Help.aspx", false);
 navNodes.AddAsFirst(internalLink);
 // add an external link after the internal link node
 SPNavigationNode externalLink = new SPNavigationNode("MSDN",
  "http://msdn2.microsoft.com/en-us/default.aspx", true);
 navNodes.AddAsLast(externalLink, internalLink);
 // set the node to open in a new window
 navNode.Properties["Target"] = "_blank";
 navNode.Update();
 // add a header node with some children
 SPNavigationNode headerNode = new SPNavigationNode(
  "Header", "", false);
 navNodes.AddAsLast(headerNode);
 // set the node to be a header element
 headerNode.Properties["UrlFragment"] = "";
 headerNode.Properties["NodeType"] = "Heading";
 headerNode.Properties["BlankUrl"] = "True";
 headerNode.Update();
 // create the child nodes
 SPNavigationNode child1Node = new SPNavigationNode("Test1",
  "Pages/Test1.aspx", false);
 headerNode.Children.AddAsLast(child1Node);
 SPNavigationNode child2Node = new SPNavigationNode("Test2",
  "Pages/Test2.aspx", false);
 headerNode.Children.AddAsLast(child2Node);
 headerNode.Update();
 publishingWeb.Update();
}

  除了这里介绍的以外,还有许多其他有关标记站点的内容。但是,这些代码示例也足以能够帮助您开始部署自定义站点并配置站点集合以应用标记。

  设置列表

  由于列表是所有 SharePoint 站点的基本功能,因此通过自动化方式对其进行部署是非常重要的。可使用以下两种常见方法来自动部署列表:部署列表定义和部署单个填充的列表实例。具体采用哪种方法完全取决于您真正要实现的目的。如果需要可通过列表模板创建的列表结构,则列表定义方法更适合。如果最终目标是部署具有值的单个列表实例,则使用对象模型来生成可部署的列表实例。

  如果确定列表定义正是您所需要的,则可以在 Visual Studio Extensions for WSS 中使用 SharePoint Solution Generator 实用工具来创建列表定义 Visual Studio 项目。使用这一生成器,您可以选择 Web 应用程序或指定 Web 应用程序,如图 11 所示。

使用 SharePoint API 自动部署 Web 应用程序

  图 11生成列表定义向导

  然后,该向导会让您选择一个目标站点集合或某个站点集合内的特定 Web 作为提取过程的目标。如果在 Visual Studio Extensions for WSS 中选中“List Definition”(列表定义)选项,则可以提取要包括在 Visual Studio 项目中的特定列表。在将列表提取到某个项目之前,请确保已根据自己的需要配置了源列表,以使其在部署到其他位置时按需显示。

  如果在自定义部署中创建不希望模板化的列表实例,可以使用对象模型来创建列表并配置列表设置,如添加一个视图。请注意,此操作的关键类是 Microsoft.SharePoint 命名空间中的 SPListCollection、SPList、SPListItemCollection、SPListItem 和 SPViewCollection。WSS 3.0 SDK 在涵盖这些类方面做得非常出色。

  创建列表、创建列表中的项以及创建视图这三种模式都需要获取集合、创建对象以及将对象添加到集合中。要创建列表并将项目添加到其中,还必须调用 Update 方法以将更新提交至服务器。查看代码下载中的 SPListConfig 类,以了解那些演示如何通过代码来完成所有这些任务的简单方法。但是请注意,为了尽量简化代码下载,我们省略了对象处置和错误处理内容。

  此工作最棘手的环节是在代码中创建视图,因为编程视图配置是使用协作应用程序标记语言 (CAML) XML 查询语法来实现的。要简化此过程,可通过 SharePoint Web 界面来创建列表的视图,然后再使用 SharePoint Solution Generator 提取列表。最后,打开 schema.xml 文件并找到含有您的自定义视图名称的 View 标记。在该标记内,查找 Query 元素并将其中的 XML 复制到代码中的字符串变量内。这就是 CAML,它将会作为 SPViewCollection 类(views 对象)中 Add 方法的第三个参数加以传递,如下所示:

StringCollection fieldsInView = new StringCollection();
string query =
 "<GroupBy Collapse="TRUE" GroupLimit="100">" +
  "<FieldRef Name="" + _fieldBool + "" />" +
 "</GroupBy>" +
 "<OrderBy>" +
  "<FieldRef Name="Title" />" +
 "</OrderBy>";
views.Add("myView", fieldsInView, query, 10, true, true);

  您还可以使用 Lists Web 服务中的 Lists 类完成这些任务。但是,对于自动化部署而言,直接使用对象模型会更快一些。

  窗体和报告部署

  InfoPath® 窗体开发是一个专门的大主题,有许多资源可帮助您了解如何开发 InfoPath 窗体应用程序。使用 Visual Studio 2008 或 Visual Studio 2005 中的 InfoPath 窗体模板是我们的首选方法。

  完成了 InfoPath 窗体应用程序之后,接下来的步骤就是将其从 Visual Studio 发布到 SharePoint 场或某个网络位置。在 Visual Studio 中单击“生成”菜单上的“发布”时,发布向导会将 .xsn 文件部署到目标位置,即 InfoPath 窗体包,其中包含 .xsf InfoPath 窗体、程序集以及各种 XML 和架构文件等窗体项目组件。将 InfoPath 包添加到管理中心(应用程序管理)管理窗体模板库的过程会促使 SharePoint 构建一个解决方案文件(.wsp 包),它会被自动添加到目标 SharePoint 场中。

 

到目前为止,我们还没有给出任何有关 SharePoint 解决方案或者相关构建方法的详细信息。要想自动部署 InfoPath 窗体应用程序,关键要认识到 SharePoint 将会为您构建解决方案文件并将其添加到场中。完成该操作后,可以使用 Mark Wagner 开发的简单强大的 solutionExport 工具来提取要部署到其他 SharePoint 场中的 .wsp 文件。您可以访问 Mark Wagner 的博客(前文曾提到过)来阅读有关此工具的信息并下载它。

  此处有两个非常重要的问题需要引起注意。第一,只有在将新 .xsn 文件部署到场中时解决方案才会被更新。因此,如果打算将解决方案包部署到其他场环境中,必须要确保 InfoPath 窗体所使用的数据连接指向正确配置的数据连接。此外,.udcx 数据连接文件不会与 InfoPath 窗体 .xsn 包或生成的 .wsp 解决方案包打包在一起。

  自动部署数据连接文件的一种方法是创建另一个包含 Feature 的解决方案包,它可以在 Feature 被激活时将 .udcx 文件部署到目标数据连接库中。将 InfoPath 解决方案文件从一个 SharePoint 实例移到下一个实例时,如果保持窗体库与数据连接库的相对路径相同,则部署会变得更加容易。这个示例很好地印证了惯例优先于配置这一原则。

  随着 SQL Server 2005 SP2 版本的发布,Microsoft 在 SQL Server Reporting Services 中创建了一种将报告集成到 SharePoint 中的新模式。这一新模式称为 SharePoint 集成模式。非常遗憾,Microsoft 并没有解决如何自动将报告及其关联的数据连接部署到 SharePoint 中的问题。

  不过值得庆幸的是,Shawn Feldman 在其精彩的博客条目“Automating Report Deployment with Reporting Services in SharePoint Integration Mode”(在 SharePoint 集成模式中自动化报告部署和 Reporting Services)中提供了解决办法,博客条目网址为 feldrox.spaces.live.com/blog/cns!C46024CE04ED4278!469.entry。在这篇博客中,他详细解释了如何自动部署报告。实际上,此条目还解释了相关的任务以及如何使用 SharePoint 对象模型和 ReportingServices2006 Web 服务来自动化它们。以下是他使用这些 API 来演示的任务:

  在 SharePoint 中创建报告库

  将“内容类型”添加到库中

  创建数据源并将其添加到 SharePoint 数据连接库

  将 Reporting Services 报告添加到报告库中

  将 Reporting Services 报告与数据源相关联

  Shawn 没有谈及通过编程来激活 Feature 的问题;不过,我们将在“解决方案和 Features”侧栏中演示如何实现此步骤。

  还有许多其他部署任务我们在此无法一一介绍,例如配置 SharePoint 权限、集成在 SharePoint 实例环境下运行的唯一 IIS Web 应用程序、部署 HTTP 处理程序以及在部署后更新 web.config。但是,仅就我们已经介绍过的任务而言,它们应该足以使您能够顺利完成自动部署工作。

  下一步要做什么?

  我们已经为您简要介绍了如何自动化在部署自定义 SharePoint 应用程序时所涉及的最常见任务。接下来的几个步骤将进一步推进自动化工作,我们将继续探究 SharePoint 对象模型、讲解如何使用一个或多个解决方案打包工具以及如何将相应的自动化步骤移到解决方案打包框架中。

  在“SharePoint Feature 和解决方案资源”侧栏中列出了一些链接,分别指向有关开发和部署 SharePoint 应用程序元素的有用文章和博客帖子。此外,我们还在“一些用来创建解决方案的方法”侧栏中提供了有关创建解决方案的更多信息。

  一些用来创建解决方案的方法

  虽然可以手动创建解决方案,但如果使用 Microsoft 和 SharePoint 社区发布的众多工具将可以减少构建和部署此类解决方案所遇到的困难。

  Visual Studio Extensions for WSS 3.0

  Visual Studio Extensions for WSS 3.0 是一款用来自动化 SharePoint 组件构建和部署活动的有效工具,它已完全集成到 Visual Studio 2005 中。Extensions for WSS 的一个独特优势是它在 Visual Studio 中引入的部署功能。不过虽说这种部署功能对各种解决方案而言的确非常有效,但对于非常看重完全控制和自动化集中部署功能的大型团队来说,这并不是理想之选。

  Extensions for WSS 的最大限制在于其设计本意是运行于安装在 SharePoint 服务器上的 Visual Studio 中。通过添加以下注册表项,可以将扩展程序安装到 Windows XP 或 Windows Vista 中并使用有限的一些功能,例如创建 Web 部件项目:

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftShared ToolsWeb Server
Extensions12.0]
"SharePoint"="Installed"

  想要使用您的代码的其他开发人员必须安装 Extensions for WSS,否则将无法打开您的项目。

  Visual Studio Extensions for WSS 1.1 让人振奋的其他一些进展还包括编辑 .wsp 解决方案和在 WSPView 窗格中实时构建解决方案的能力。这为使用解决方案包的文件和结构提供了一种强大的方法。此外,在部署解决方案时,它会在项目的构建文件夹中放入一份 .wsp 文件的副本,以便您可以独立于 Extensions for WSS 部署机制来进行部署。

  Visual Studio Extensions for WSS 1.2(计划支持 Visual Studio 2008)预计在今年推出。您可以访问 Microsoft SharePoint 产品和技术团队的博客来了解有关最新版本的信息,网址为 blogs.msdn.com/sharepoint/archive/2008/02/11/announcing-the-final-release-of-vsewss-1-1-and-the-upcoming-version-1-2.aspx。

  WSP 生成器

  WSP 生成器(由 Carsten Keutmann 开发)是一款非常值得您在 SharePoint 解决方案构建工作中考虑采用的工具。如需要连续集成或开发人员需要交付打包工作,WSP 生成器会特别有用。

  此工具可通过模拟 SharePoint 12 文件夹以及其他几个特定文件夹的文件夹结构来创建解决方案文件。在 Visual Studio 中,只需在项目中创建文件夹结构、添加文件,然后将 WSPBuilder 作为生成后流程运行或独立于生成流程运行即可。WSPBuilder 会自动创建 manifest.xml 文件并将其捆绑到解决方案文件中,以部署 12 文件夹的内容。

  如果 Visual Studio 解决方案包含多个含有 Features 和程序集的项目,您只需将 SolutionPath 选项指向 Visual Studio 解决方案文件夹,WSPBuilder 就会将所有组件打包到单个 SharePoint 解决方案中。由于需要在项目中创建特定的文件夹结构,因此可能需要对现有项目进行大量的修改,这可能会给那些不熟悉 Features 或解决方案的开发人员带来麻烦。

  请记住,WSPBuilder 等开源工具始终在不断改进中,其回归测试可能不如商业工具那样稳定。因此,对此工具所做的更新可能会影响早期版本中可用的功能。例如,在 WSPBuilder 中加入的构建解决方案的功能改变了现有 SolutionPath 选项的行为,必须将其改为 ProjectPath;否则将会创建空解决方案。

  新版的 WSPBuilder(WSPBuilder Extensions)可用作 Visual Studio 2005 和 Visual Studio 2008 的加载项。扩展程序添加了两个 WSPBuilder 项目类型和多个项类型,例如具有 Feature 的 Web 部件和具有 Receiver 的 Feature。加入某个项后将会创建打包和部署所需的文件夹结构和文件,包括 Web 部件项的 .WebPart 文件。扩展程序还会向项目菜单中添加部署选项,但前提是必须在本地部署。

  目前,此版本所提供的文档资料非常有限;不过,作者在其博客中介绍了扩展程序的使用方法。项目位置是 codeplex.com/wspbuilder。

  SPDeploy

  SPDeploy 工具是 SharePoint 开发团队一直在寻找的解决方案打包和部署工具中的一种颇具吸引力的工具组合。此工具真正吸引人之处在于它主要侧重于远程部署。利用此工具,可以通过 Visual Studio 2005 中的标准 C# 类库项目来创建 .wsp 文件,它会自动读取 Visual Studio 中的文件树并构建您的 .wsp 包。此工具提供了对 MSBuild 的扩展并整合了 .targets 文件,以提供可靠的增量式构建和部署过程。

  部署目标可以在命令提示符下执行,也可在略加修改后从 Visual Studio 2005 启动。这些目标包括 CompileWsp、AddWsp、DeployWsp、UpgradeWsp、RetractWsp、DeleteWsp、UpgradeIncremental、UpgradeIncrementalFiles、UpgradeIncrementalAssembly、CreateSite、DeleteSite、CreateWebApplication 和 DeleteWebApplication。

  此工具的作者 Clint Simon 提供了一些有关远程调试的有用提示。此外,请务必阅读一下名为“SharePoint Custom Application Development Methodologies”(SharePoint 自定义应用程序开发方法)的博客帖子,网址为 ascentium.com/blog/sp/default.aspx。这是我们至今看到的众多开发团队中视角最为准确的一个。

  STSDev

  CodePlex 社区推出的另一个前景不错的部署工具就是 STSDev(用于 SharePoint 2007 开发的简单工具)。此项目由 SharePoint 的负责人 Ted Pattison 协调,他在 2008 年 3 月刊的 MSDN 杂志中撰写了关于它的一篇文章 (msdn2.microsoft.com/magazine/cc337895.aspx)。此工具为构建、测试和调试 .wsp 文件奠定了良好的基础,对于那些需要为其打包和部署工作设定常规流程的开发团队来说会非常有用。

  STSDev 是一个控制台应用程序,它启动不同的对话框并使用自定义 .targets 文件来构建 .wsp 文件。虽然此功能尚未集成到 Visual Studio 中,但可以通过借助外部工具接口指向 .exe 文件来添加到 Visual Studio 外壳中。建立了 Visual Studio 连接后,此工具可以自动化 manifest.xml 和 .ddf 文件的创建和更新流程,并将一些常用的 SharePoint 开发人员命令添加到 Visual Studio 环境中。

  STSDev 会创建基本的 Visual Studio 解决方案项目结构或部署文件目录,用以填充生成 .wsp 文件所必需的 SharePoint 文件。它还会创建 solutionconfig.xml 文件,用于修改 manifest.xml 文件的输入参数。Microsoft.SharePoint.targets 文件提供了许多不同的命令,允许您在不同的部署配置之间进行选择和切换。

  对于那些刚刚介入 SharePoint 开发工作的开发人员来说,这是一款非常不错的工具,CodePlex 项目站点提供了三篇值得一读的优秀教程。您可以通过以下网址访问此项目:codeplex.com/stsdev/Release/ProjectReleases.aspx?ReleaseId=10119。

  Ethan Wilansky 是一位 Microsoft 目录服务 MVP 和企业架构师。目前他每天的工作就是带领一个开发团队,专注于构建自定义的 SharePoint 应用程序,并提供目录服务编程解决方案 SME。

  Paul Olszewski 是 .NET 功能团队的信息专家。他专门负责创建和部署能充分利用 Microsoft 技术的可重用组件应用程序。

  Rick Sneddon 是一位集成工程实践方面的 EDS 高级基础结构专家和 MCSE。他致力于创建门户基础结构、开发技术策略以及针对门户复合应用程序解决方案的部署和支持为客户提供执行方面的建议。

 

 

本文摘自:http://tech.ddvip.com/2008-10/122498822284059.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值