使用 SharePoint 2007 Lists WebService 中的 GetListItems、GetVersionCollection 和 UpdateListItems 方法






2.71/5 (5投票s)
使用 SharePoint 2007 Lists WebService 中的 GetListItems、GetVersionCollection 和 UpdateListItems 方法,将字段历史记录复制到同一列表的单个字段中。
引言
此代码是在客户要求将 SharePoint 2007 的问题跟踪列表导出到 Microsoft Excel 后开发的。当 SharePoint 2007 字段具有“将更改追加到现有文本”功能时,字段历史记录会在浏览器中显示,但在导出到 Microsoft Excel 后不会显示。SharePoint 2007 的问题跟踪列表有两个字段类型:Description(描述)和 Comments(评论)。此代码的开发目的是解决此问题,即将所需的字段历史记录复制到另一个字段,该字段包含单个记录中的历史记录,从而可以以直接的方式将其导出到 Excel。目标是,对于列表中的每个记录,获取给定字段的完整历史记录,并将完整历史记录复制到同一 SharePoint 列表中存在的单个字段中。
解决方案
使用 SharePoint 2007 Lists Web Service(_vti_bin/lists.asmx),我想使用 GetListItems
方法获取列表项。为了获取每个记录中给定字段的历史记录,我将使用 GetVersionCollection
方法。此方法只允许获取单个字段的历史记录:最好能有一个方法来检索多个字段的历史记录。我想没有办法做到这一点:( 获取历史记录后,我调用 UpdateListItems
方法来更新每个记录。只有当历史记录自上次更新历史记录字段以来发生更改时,才会进行更新。
注意 1:我希望在历史记录字段中包含修改者。对源字段调用的 GetVersionCollection
方法不返回修改者。为了获取修改者,我将对“Editor”(编辑器)字段调用 GetVersionCollection
方法。通过同时迭代两个结果中的每个节点(源字段的 GetVersionCollection
结果和 Editor 字段),我将能够匹配源字段的历史记录和 Editor 字段,从而知道哪个用户进行了更改。
注意 2:我将为每个记录调用一次 UpdateListItems
。实际上,我可以在一次 UpdateListItems
调用中包含多个更新。
要求
该解决方案是使用 VS2005 在 Windows XP SP2 上构建的。SharePoint 2007 服务器在 Windows 2003 服务器上运行,与 XP 工作站位于同一域中。
配置
程序配置通过应用程序配置文件中的 appSettings
部分进行。不支持命令行参数。
支持的参数是
<add key="PrintMessages2Console" value="true"/>
<!-- Print messages to console -->
<add key="UrlListSite"
value="http://sharepoint.viatecla.pt/nso/issues_business/_vti_bin/lists.asmx"/>
<!-- The url for SharePoint list WebService. Be sure to have the correct
sharePoint site in it: the one where the list exists -->
<add key="ListName" value="NSO - Issues - PROD"/>
<!-- The list name to look for -->
<add key="SourceField" value="V3Comments"/>
<!-- The field used to retrieved the history from -->
<add key="TargetField" value="CommentsHistory"/>
<!-- The field used to store the history retrieved the source field -->
<add key="SPWSUserName" value="[user]"/>
<!-- Username required to access SharePoint site.
Current credentials will be used if left blank -->
<add key="SPWSUserPassword" value="[pwd]"/>
<!-- Password required to access SharePoint site.
Current credentials will be used if left blank -->
<add key="SPWSDomain" value="[domain]"/>
<!-- Domain required to access SharePoint site.
Current credentials will be used if left blank -->
<add key="LogFileName" value=""/>
<!-- Logfilename and path. Program file name,
replace by the extension ".log" will be used if left blank -->
<add key="SPListItemQueryString" value=""/>
<!-- SPListItemQueryString can be set to retrieve just some records from
the SharePoint List. If not set, all records will be retrieved.
An example of a query string: <Query><Where><Eq><FieldRef Name=\"ID\" />
<Value Type=\"Counter\">2213</Value></Eq></Where></Query> -->
已知问题
此方法未考虑性能。通过使用 SharePoint Lists WebService,我(至少据我所知)除了为每个记录调用两次 GetVersionCollection
外,别无他法:一次调用检索所需字段的历史记录,另一次调用检索修改者。尽管如此,UpdateListItems
方法支持一次调用更新多个记录。这样做将减少对 Web Service 的调用次数,但要小心:这种方法会迫使您控制每次调用的记录数。过去,我在使用大量记录调用更新方法时遇到了一些麻烦。另一个影响性能的问题:SharePoint 2007 的问题跟踪列表有两个字段具有“将更改追加到现有文本”功能:Description(描述)和 Comments(评论)。此代码只更新一个字段。如果您想同时获取这两个字段的历史记录,您必须运行此代码两次。最后一点:如果性能是问题,您其实不应该使用 WebService 方法。
可能的改进
您可能需要更新同一列表中的多个字段。目前,该代码仅支持一个 SourceField
(源字段)和一个 TargetField
(目标字段)。代码可以轻松修改以支持字段集合的更新,以源-目标字段对的形式。此代码存在多个性能问题。显然,无法避免为每个记录调用两次 GetVersionCollection
,但可以避免为每个记录调用一次 UpdateListItems
来进行更新。这可以稍微提高性能,但主要问题是为每个记录调用两次 GetVersionCollection
(请记住,更新只会在历史记录已更改的记录上调用)。如果性能是问题,您其实不应该使用 WebService 方法。我认为还有两个方向可以探索:
- 您可以研究 SharePoint 对象模型,希望对象模型提供的功能比 WebService 更多。当然,代码必须在 SharePoint 服务器上运行。
- 您可以查看 SQL Server SharePoint 表,尝试找出信息存储在数据模型中的哪个位置。在浏览器使用 SharePoint 站点请求历史记录信息时运行 SQL Profiler 将有助于找到您需要的信息。到目前为止,我还没有需要修改 SharePoint SQL 表。
反馈请求
此代码是为了解决将 SharePoint 列表导出到 Microsoft Excel 工作簿后缺少历史记录信息的问题而开发的。尽管该代码可以作为学习 SharePoint 2007 WebServices 的一种方式,但我很想知道是否有人知道更好的解决方案。
历史
版本 0.1 由 Joao Faneca (jfaneca@hotmail.com) 于 2008 年 5 月 24 日开发。