步步为营 SharePoint 开发学习笔记系列 九、SharePoint web service 开发(上)

来源:岁月联盟 编辑:exp 时间:2011-08-02

 

概要

 

    Sharepoint中提供了很多开箱即用的Web Service,使用这些web service我们可以进行远程调用, 在"web server extensions/12/ISAPI"(其通常位于C:/Program Files/Common Files/Microsoft Shared/web server extensions/12/ISAPI")之下的"Microsoft Shared"目录中有大部分Web Services的物理文件。用于管理中心工具的管理Web Service位于ADMISAPI文件夹中,其在管理中心控制台里是一个名为"_vti_adm"的虚拟目录。当你创建了一个SharePoint站点时,它将包含一个名为"_vti_bin"的虚拟目录,以指向这个位置。IIS不为子站点包含任何应用程序或虚拟目录,它们只是包含通过SharePoint元数据和HttpModules实现的对_vti_bin虚拟目录的映射。

 

先看下Lists.asmx中的一些常用功能

1

 

 

首先我们先连接web Service

 

view sourceprint?01 public static NetworkCredential GetCredentials(SiteType type) 

 

02 { 

 

03  

 

04         return new System.Net.NetworkCredential(ConfigurationManager.AppSettings["Source_SPWSUserName"], 

 

05             ConfigurationManager.AppSettings["Source_SPWSUserPassword"], ConfigurationManager.AppSettings["Source_SPWSDomain"]); 

 

06 } 

 

07  

 

08 /// <summary> 

 

09 /// Get the list webservice based on the url 

 

10 /// </summary> 

 

11 /// <returns></returns> 

 

12 public static SPListWS.Lists GetListWebService(ListBE listProperty) 

 

13 { 

 

14     string wsUrl = GetWSUrl(listProperty) + "_vti_bin/Lists.asmx"; 

 

15     SPListWS.Lists ws = new SPListWS.Lists(); 

 

16     ws.Url = wsUrl; 

 

17     ws.Credentials = WSHelper.GetCredentials(listProperty.Type); 

 

18  

 

19     return ws; 

 

20 }

 

再把web service引用进来

image

 

 

Lists.GetListItems的用法

 

根据条件来查询的query语句

 

view sourceprint?01 private string GetCondition 

 

02 { 

 

03     get

 

04     { 

 

05         return @"<Where> 

 

06                   <And> 

 

07                      <And> 

 

08                         <Geq> 

 

09                            <FieldRef Name='Created' /> 

 

10                            <Value Type='DateTime'>{0}</Value>  

 

11                         </Geq> 

 

12                         <Leq> 

 

13                            <FieldRef Name='Created' /> 

 

14                            <Value Type='DateTime'>{1}</Value> 

 

15                         </Leq> 

 

16                      </And> 

 

17                      <Gt> 

 

18                         <FieldRef Name='ID' /> 

 

19                         <Value Type='Counter'>0</Value> 

 

20                      </Gt> 

 

21                   </And> 

 

22             </Where>"; 

 

23     } 

 

24 }

 

而后再调用Lists.GetListItems方法,返回的是XmlNode的结果集

 

view sourceprint?01 /// <summary> 

 

02 ///  

 

03 /// </summary> 

 

04 /// <returns></returns> 

 

05 private List<ListItemBE> GetSourceListItems(DateTime startDate, DateTime endDate) 

 

06 { 

 

07     int rowLimit = 8000; 

 

08     XmlDocument xmlDoc = new System.Xml.XmlDocument(); 

 

09     XmlElement query = xmlDoc.CreateElement("Query"); 

 

10     XmlElement viewFields = xmlDoc.CreateElement("ViewFields"); 

 

11     XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions"); 

 

12  

 

13     /*Use CAML query*/

 

14     query.InnerXml = string.Format(GetCondition, SPUtility.CreateISO8601DateTimeFromSystemDateTime(startDate), SPUtility.CreateISO8601DateTimeFromSystemDateTime(endDate)); 

 

15     viewFields.InnerXml = GetColumnFieldRef(MigrateProperty.AllColumn); 

 

16     queryOptions.InnerXml = "<ViewAttributes Scope=/"RecursiveAll/" />"; 

 

17     MigrateProperty.AllColumn.Remove("ID"); 

 

18     System.Xml.XmlNode nodes = _ws.GetListItems(_listProperty.ListName, string.Empty, query, viewFields, rowLimit.ToString(), queryOptions, null); 

 

19     return GetListItemListFromXml(nodes); 

 

20 }

 

从XmlNode取得我们需要的数据

 

view sourceprint?01 /// <summary> 

 

02 ///  

 

03 /// </summary> 

 

04 /// <param name="nodes"></param> 

 

05 /// <returns></returns> 

 

06 private List<ListItemBE> GetListItemListFromXml(XmlNode nodes) 

 

07 { 

 

08     UserOperations userOperations = new UserOperations(_listProperty); 

 

09     List<ListItemBE> result = new List<ListItemBE>(); 

 

10     ListItemBE listItem; 

 

11     foreach (XmlNode node in nodes) 

 

12     { 

 

13         if (node.Name == "rs:data") 

 

14         { 

 

15             for (int i = 0; i < node.ChildNodes.Count; i++) 

 

16             { 

 

17                 if (node.ChildNodes[i].Name == "z:row") 

 

18                 { 

 

19                     listItem = GetListItemBEFromXmlNode(node.ChildNodes[i], userOperations); 

 

20                     if (node.ChildNodes[i].Attributes.GetNamedItem("ows_ParentFolderId") == null) 

 

21                     { 

 

22                         listItem.ColumnValue.Add("FSObjType", "1"); 

 

23                         listItem.ColumnValue.Add("BaseName", listItem.ColumnValue["Title"]); 

 

24                         result.Add(listItem); 

 

25                     } 

 

26                     else

 

27                     { 

 

28                         listItem.ColumnValue.Add("FileRef", node.ChildNodes[i].Attributes["ows_FileRef"].Value); 

 

29                         secondListItem.Add(listItem); 

 

30                     } 

 

31                 } 

 

32             } 

 

33         } 

 

34     } 

 

35     return result; 

 

36 } 

 

37  

 

38 /// <summary> 

 

39 ///  

 

40 /// </summary> 

 

41 /// <param name="node"></param> 

 

42 /// <param name="userOperations"></param> 

 

43 /// <returns></returns> 

 

44 private ListItemBE GetListItemBEFromXmlNode(XmlNode node, UserOperations userOperations) 

 

45 { 

 

46     ListItemBE listItem = new ListItemBE(); 

 

47     listItem.Id = node.Attributes["ows_ID"].Value; 

 

48     foreach (KeyValuePair<string, string> column in MigrateProperty.AllColumn) 

 

49     { 

 

50         string nodeValue = string.Empty; 

 

51         if (node.Attributes.GetNamedItem("ows_" + column.Key) != null) 

 

52             nodeValue = node.Attributes["ows_" + column.Key].Value; 

 

53         if (string.Equals(column.Key, "Attachments", StringComparison.InvariantCultureIgnoreCase)) 

 

54         { 

 

55             GetAttachmentFromNode(nodeValue, listItem.Id); 

 

56             continue; 

 

57         } 

 

58         if (string.Equals(column.Key, "Author", StringComparison.InvariantCultureIgnoreCase) 

 

59             || string.Equals(column.Key, "Editor", StringComparison.InvariantCultureIgnoreCase)) 

 

60         { 

 

61             listItem.ColumnValue.Add(column.Value, userOperations.GetUserNameByOriginalName(nodeValue)); 

 

62             continue; 

 

63         } 

 

64         if (node.Attributes.GetNamedItem("ows_" + column.Key) != null) 

 

65             listItem.ColumnValue.Add(column.Value, nodeValue); 

 

66         else

 

67             listItem.ColumnValue.Add(column.Value, string.Empty); 

 

68     } 

 

69     return listItem; 

 

70 }

 

MigrateProperty.AllColumn定义如下

 

view sourceprint?01 public Dictionary<string,string> AllColumn 

 

02 { 

 

03     get

 

04     { 

 

05         Dictionary<string,string> listColumn = new Dictionary<string,string>(); 

 

06         listColumn.Add("ID", "ID"); 

 

07         listColumn.Add("Title", "Title"); 

 

08         listColumn.Add("Author", "Author"); 

 

09         listColumn.Add("Created", "Created"); 

 

10         listColumn.Add("Editor", "Editor"); 

 

11         listColumn.Add("Modified", "Modified"); 

 

12         listColumn.Add("Attachments", "Attachments"); 

 

13         listColumn.Add("ContentType", "ContentType"); 

 

14         listColumn.Add("Body", "Body"); 

 

15         listColumn.Add("ThreadIndex", "ThreadIndex"); 

 

16         listColumn.Add("ParentFolderId", "ParentFolderId"); 

 

17         listColumn.Add("TrimmedBody", "TrimmedBody"); 

 

18         return listColumn; 

 

19     } 

 

20 }

 

而我们ListItemBE的定义如下,保存返回的结果集

 

view sourceprint?01 public class ListItemBE 

 

02 { 

 

03     public ListItemBE() 

 

04     { 

 

05         ColumnValue = new Dictionary<string, string>(); 

 

06     } 

 

07   

 

08     public string Id { get; set; } 

 

09  

 

10     public Dictionary<string, string> ColumnValue { get; set; } 

 

11  

 

12 }

 

如上所示的步骤,我们就可以根据自定义的query语句通过web service来取得结果集。

 

Lists.UpdateListItems的用法

 

首先看下Insert item的xml格式

 

view sourceprint?01 <Batch OnError="Continue" ListVersion="1" 

 

02 ViewName="270C0508-A54F-4387-8AD0-49686D685EB2"> 

 

03    <Method ID="1" Cmd="New"> 

 

04       <Field Name='ID'>New</Field> 

 

05       <Field Name="Title">Value</Field> 

 

06       <Field Name="Date_Column">2007-3-25</Field> 

 

07       <Field Name="Date_Time_Column"> 

 

08          2006-1-11T09:15:30Z</Field> 

 

09    </Method> 

 

10 </Batch>

 

如果插入的item是folder时,插入的xml格式如下

 

view sourceprint?1 <Batch OnError="Continue" PreCalc="TRUE" 

 

2 ListVersion="0" 

 

3 ViewName="{EF2F5A21-0FD0-4654-84ED-112B4F5A48F8}"> 

 

4    <Method ID="1" Cmd="New"> 

 

5       <Field Name="ID">New</Field> 

 

6       <Field Name="FSObjType">1</Field> 

 

7       <Field Name="BaseName">Name</Field> 

 

8    </Method> 

 

9 </Batch>

 

我们生成xml时做如下处理,根据我们定义的ListItemBE方法来做如下处理

 

view sourceprint?01 /// <summary> 

 

02 /// Returns the XML that will be used to batch insert items 

 

03 /// </summary> 

 

04 /// <param name="batch"></param> 

 

05 /// <returns></returns> 

 

06 private string GetInsertXML(List<ListItemBE> batch) 

 

07 { 

 

08     StringBuilder xml = new StringBuilder(); 

 

09     xml.Append(string.Format(@"<Batch OnError=""Continue""  {0}>", _listProperty.RootUrl)); 

 

10     foreach (ListItemBE listItem in batch) 

 

11     { 

 

12         xml.AppendFormat(@"<Method ID=""{0}"" Cmd=""New"">", listItem.Id); 

 

13         xml.Append(GetInsertInnerXml(listItem)); 

 

14         xml.Append("</Method>"); 

 

15     } 

 

16     xml.Append("</Batch>"); 

 

17  

 

18     return xml.ToString(); 

 

19 }

 

调用方式如下:

 

view sourceprint?01 /// <summary> 

 

02 /// Insert the items 

 

03 /// </summary> 

 

04 /// <param name="batch"></param> 

 

05 /// <returns></returns> 

 

06 private UpdateResultBE InsertItems(List<ListItemBE> batch) 

 

07 { 

 

08     //Get the Insert XML Node 

 

09     XmlNode batchNode = GetInsertXmlNode(batch); 

 

10     XmlNode result = null; 

 

11  

 

12     _logger.Log("Started batch uploading list Items"); 

 

13     try

 

14     { 

 

15         //Call the webservice 

 

16         result = _ws.UpdateListItems(_listProperty.ListName, batchNode); 

 

17     } 

 

18     catch (Exception ex) 

 

19     { 

 

20         _logger.Log(String.Format("Error Inserting Items. Exception: {0}. Stack Trace: {1}", ex.Message, ex.StackTrace)); 

 

21     } 

 

22  

 

23     _logger.Log("Finished batch uploading list items"); 

 

24  

 

25     //Transform the result into an object 

 

26  

 

27     UpdateResultBE insertResult = new UpdateResultBE(result, _listProperty); 

 

28     LogInsertResult(insertResult); 

 

29  

 

30     return insertResult; 

 

31 }

 

我们的UpdateResultBE定义如下,它是用来获取返回我们想要的结果集。

 

返回结果集格式如下:

 

view sourceprint?01      * <Results xmlns="http://schemas.microsoft.com/sharepoint/soap/"> 

 

02    <Result ID="1,Update"> 

 

03       <ErrorCode>0x00000000</ErrorCode> 

 

04       <z:row ows_ID="4" ows_Title="Title" 

 

05          ows_Modified="2003-06-19 20:31:21" 

 

06          ows_Created="2003-06-18 10:15:58" 

 

07          ows_Author="3;#User1_Display_Name" 

 

08          ows_Editor="7;#User2_Display_Name" ows_owshiddenversion="3" 

 

09          ows_Attachments="-1" 

 

10          ows__ModerationStatus="0" ows_LinkTitleNoMenu="Title" 

 

11          ows_LinkTitle="Title" 

 

12          ows_SelectTitle="4" ows_Order="400.000000000000" 

 

13          ows_GUID="{4962F024-BBA5-4A0B-9EC1-641B731ABFED}" 

 

14          ows_DateColumn="2003-09-04 00:00:00" 

 

15          ows_NumberColumn="791.00000000000000" 

 

16          xmlns:z="#RowsetSchema" /> 

 

17    </Result> 

 

18    <Result ID="2,Update"> 

 

19       <ErrorCode>0x00000000</ErrorCode> 

 

20       <z:row ows_ID="6" ows_Title="Title" 

 

21          ows_Modified="2003-06-19 20:31:22" 

 

22          ows_Created="2003-06-18 19:07:14" 

 

23          ows_Author="2;#User1_Display_Name" 

 

24          ows_Editor="6;#User2_Display_Name" ows_owshiddenversion="4" 

 

25          ows_Attachments="0" ows__ModerationStatus="0" 

 

26          ows_LinkTitleNoMenu="Title" 

 

27          ows_LinkTitle="Title" ows_SelectTitle="6" 

 

28          ows_Order="600.000000000000" 

 

29          ows_GUID="{2E8D2505-98FD-4E3E-BFDA-0C3DEBE483F7}" 

 

30          ows_DateColumn="2003-06-23 00:00:00" 

 

31          ows_NumberColumn="9001.00000000000000" 

 

32          xmlns:z="#RowsetSchema" /> 

 

33    </Result> 

 

34    ... 

 

35 </Results>

 

我们取结果的方式如下:

 

view sourceprint?01 /// <summary> 

 

02 /// Class that holds the UpdateListItems webservice method result 

 

03 /// </summary> 

 

04 internal class UpdateResultBE 

 

05 { 

 

06     public List<SingleResultBE> Result { get; set; } 

 

07     /// <summary> 

 

08     /// Contructor that uses the result xml to load into objects 

 

09     /// </summary> 

 

10     /// <param name="resultXml"></param> 

 

11     public UpdateResultBE(XmlNode resultXml, ListBE properties) 

 

12     { 

 

13         Result = new List<SingleResultBE>(); 

 

14         SingleResultBE singleResult; 

 

15         if (resultXml == null) 

 

16             return; 

 

17  

 

18         foreach (XmlNode node in resultXml.ChildNodes) 

 

19         { 

 

20             singleResult = new SingleResultBE(); 

 

21             try

 

22             { 

 

23                 singleResult.Id = node.Attributes["ID"].Value.Split(',')[0]; 

 

24                 singleResult.Operation = node.Attributes["ID"].Value.Split(',')[1]; 

 

25  

 

26                 XmlNode errorCodeNode = FindChildNode(node, "ErrorCode"); 

 

27                 if (errorCodeNode != null) 

 

28                 { 

 

29                     singleResult.ErrorCode = errorCodeNode.InnerText; 

 

30                 } 

 

31  

 

32                 XmlNode errorTextNode = FindChildNode(node, "ErrorText"); 

 

33                 if (errorTextNode != null) 

 

34                 { 

 

35                     singleResult.ErrorMessage = errorTextNode.InnerText; 

 

36                 } 

 

37  

 

38                 XmlNode zRow = FindChildNode(node, "z:row"); 

 

39                 if (zRow != null) 

 

40                 { 

 

41                     singleResult.Attachments = Convert.ToInt32(zRow.Attributes["ows_Attachments"].Value); 

 

42                     singleResult.Created = DateTime.Parse(zRow.Attributes["ows_Created"].Value); 

 

43                     singleResult.ListItemId = Convert.ToInt32(zRow.Attributes["ows_ID"].Value); 

 

44                     singleResult.ModerationStatus = Convert.ToInt32(zRow.Attributes["ows__ModerationStatus"].Value); 

 

45                     singleResult.Modified = DateTime.Parse(zRow.Attributes["ows_Modified"].Value); 

 

46                     singleResult.ListItemGuid = zRow.Attributes["ows_UniqueId"].Value; 

 

47                     if (zRow.Attributes.GetNamedItem("ows_Title") != null) 

 

48                         singleResult.Title = zRow.Attributes["ows_Title"].Value; 

 

49                     singleResult.BaseName = zRow.Attributes["ows_BaseName"].Value; 

 

50                     singleResult.FileDirRef = zRow.Attributes["ows_FileDirRef"].Value; 

 

51                     singleResult.FileRef = zRow.Attributes["ows_FileRef"].Value; 

 

52                     if (zRow.Attributes.GetNamedItem("ows_BaseName") != null) 

 

53                         singleResult.BaseName = zRow.Attributes["ows_BaseName"].Value; 

 

54                 } 

 

55  

 

56                 Result.Add(singleResult); 

 

57             } 

 

58             catch (Exception ex) 

 

59             { 

 

60                 Logger.Logger logger = Logger.LoggerFactory.GetLogger(); 

 

61                 logger.Log(String.Format("Error when parsing the result. Exception: {0} /n XML: {1}", ex.Message, node.InnerXml)); 

 

62             } 

 

63         } 

 

64  

 

65     } 

 

66  

 

67  

 

68  

 

69     /// <summary> 

 

70     /// Find the Child node specified by name 

 

71     /// </summary> 

 

72     /// <param name="parent">Parent Node</param> 

 

73     /// <param name="childNodeName">Child node name</param> 

 

74     /// <returns></returns> 

 

75     private XmlNode FindChildNode(XmlNode parent, string childNodeName) 

 

76     { 

 

77         foreach (XmlNode node in parent.ChildNodes) 

 

78         { 

 

79             if (node.Name == childNodeName) 

 

80                 return node; 

 

81         } 

 

82  

 

83         return null; 

 

84     } 

 

85 }

 

SingleResultBE就是我们想要的结果集.

 

view sourceprint?01 /// <summary> 

 

02 /// Class that holds the properties for each result returned by the UpdateListItems webservice 

 

03 /// </summary> 

 

04 public class SingleResultBE 

 

05 { 

 

06     public string Id { get; set; } 

 

07     public string Operation { get; set; } 

 

08     public string ErrorCode { get; set; } 

 

09     public int ListItemId { get; set; } 

 

10     public string Title { get; set; } 

 

11     public DateTime Modified { get; set; } 

 

12     public DateTime Created { get; set; } 

 

13     public int Attachments { get; set; } 

 

14     public int ModerationStatus { get; set; } 

 

15     public string ErrorMessage { get; set; } 

 

16     public string ListItemGuid { get; set; } 

 

17     public string FileDirRef { get; set; } 

 

18     public string FileRef { get; set; } 

 

19     public string ServerUrl { get; set; } 

 

20     public string EncodedAbsUrl { get; set; } 

 

21     public string BaseName { get; set; } 

 

22     public const string NO_ERROR = "0x00000000"; 

 

23     public const string Exist_ERROR = "0x8107090d"; 

 

24 }

 

返回结果集里的ErrorCode是0x00000000表示插入成功,如果是0x8107090d表示插入的item己经存在。

 

接下来我们讲解update item做法和UserGroup的用法