对 SharePoint WebService 的调用
接触SharePoint已经有一段时间了,但是对Moss 提供的WebService的使用还是比较少的。今天有客户需求做信息同步,将信息同步到moss中。故此使用WebService 的方式来实现。
Moss自带了WebService,通常情况下是跨服务器的访问,因为同一服务器上不同网站可以简单的通过提升权限代码就可以访问数据。
实现上述功能 需要调用 Lists 服务 对项目添加 “http://<server-url>/_vti_bin/Lists.asmx” web引用 ,并将此命名空间命名为SPListsWS
为了方便以后使用,故封装几个方法,实现增,删,改功能。
/// <summary> /// 调用MossWebService为列表执行增删改(不带附件) /// </summary> /// <param name="ListName">列表名称</param> /// <param name="ListItemID">列表项ID,如果是增,可填写任意字符串</param> /// <param name="FieldAndValue">存储sharepoint 列表字段的键值对</param> /// <param name="Cmd">执行的操作 New Update Delete 不区分大小写</param> public XmlNode MossListComand(string ListName, string ListItemID, Hashtable FieldAndValue, string Cmd) { SPListsWS.Lists listService = new SPListsWS.Lists(); //listService.Credentials = System.Net.CredentialCache.DefaultCredentials; listService.Credentials = new System.Net.NetworkCredential(adminName, adminPWd, domainName); listService.RequestEncoding = Encoding.UTF8; StringBuilder strBatch = new StringBuilder(); switch (Cmd.ToLower()) { case "new":
//ID在增加操作时只是个唯一标记,可以随便指定,并不对应到实际//listitem的ID。
strBatch.Append("<Method ID='1' Cmd='New'><Field Name='ID'>New</Field>");
break; case "update":
//Update中<Field Name='ID'>的ID为要更新项的实际的ID了,因为要靠这个来唯一指定一条记录 strBatch.Append("<Method ID='1' Cmd='Update'><Field Name='ID'>" + ListItemID + "</Field>");
break; case "delete":
//<Field Name='ID'>的ID为要删除项项的实际的ID了,因为要靠这个来唯一指定一条记录
strBatch.Append("<Method ID='1' Cmd='Delete'><Field Name='ID'>" + ListItemID + "</Field>");
break; } foreach (string key in FieldAndValue.Keys) { strBatch.Append("<Field Name='" + key + "'>" + FieldAndValue[key].ToString() + "</Field>"); } strBatch.Append("</Method>"); XmlDocument xmlDoc = new XmlDocument(); XmlElement elBatch = xmlDoc.CreateElement("Batch"); elBatch.SetAttribute("OnError", "Continue"); //指定出错后是返回还是继续下一步 elBatch.InnerXml = strBatch.ToString(); XmlNode ndReturn = listService.UpdateListItems(ListName, elBatch); return ndReturn; }
跟据功能需求,要求记录新增项的ID,下面的方法实现了为Moss插入一条记录,并返回新增项的ID
/// <summary> /// 调用MossWebService为列表执行增加操作并返回新增项ID(不带附件) /// </summary> /// <param name="ListName">列表名称</param> /// <param name="ListItemID">列表项ID,如果是增,可填写任意字符串</param> /// <param name="FieldAndValue">存储sharepoint 列表字段的键值对</param> /// <returns>新增项ID</returns> public string MossListComandForNew(string ListName, string ListItemID, Hashtable FieldAndValue) { XmlNode node = MossListComand(ListName, ListItemID, FieldAndValue, "New"); string NewId = string.Empty; NewId = GetNewListItemID(node); return NewId; } /// <summary> /// 根据返回的Xml得倒新增加记录的ID /// </summary> /// <param name="ListItems"></param> /// <returns></returns> private string GetNewListItemID(XmlNode ListItems) { string newListItemID = string.Empty; IEnumerator ienum = ListItems.GetEnumerator(); XmlNode current, dataRow = null; bool isFind = false; while (ienum.MoveNext()) { current = (XmlNode)ienum.Current; if (current.Name == "Result") { dataRow = current; ienum = dataRow.GetEnumerator(); while (ienum.MoveNext()) { current = (XmlNode)ienum.Current; if (current.Name == "z:row") { newListItemID = current.Attributes["ows_ID"].Value; isFind = true; break; } } if (isFind) break; } } return newListItemID; }
当然执行增删改功能后都会返回一个xml文本,这里我只取ID,同样也可以取到列表项的其他信息。
上面是对列表的增删改。对列表的查询功能也作了简单的封装
(这里借鉴了 沙舟的一篇文章http://www.cnblogs.com/Hary/archive/2009/02/04/1383933.html做了简单的修改。)
public string UserName { get; set; } public string PassWord { get; set; } public string DomainName { get; set; } public DataSet GetItems(string ListName,string CamlStr,string Fields,string rowLimit) { SPListWs.Lists listsWS = new SPListWs.Lists(); //listsWS.Credentials = System.Net.CredentialCache.DefaultCredentials; //该句在编译环境可以代替下一句,但是跨服务器应用肯定要用下一句 listsWS.Credentials = new NetworkCredential(UserName, PassWord, DomainName); XmlDocument doc = new System.Xml.XmlDocument(); doc.LoadXml("<Document><Query>" + CamlStr + "</Query><ViewFields>" + Fields + "</ViewFields><QueryOptions /></Document>"); XmlNode listQuery = doc.SelectSingleNode("//Query"); XmlNode listViewFields = doc.SelectSingleNode("//ViewFields"); XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions"); Guid g = GetWebID(); XmlNode items = listsWS.GetListItems(ListName, string.Empty, listQuery, listViewFields, rowLimit, listQueryOptions, g.ToString()); NameTable nt = new System.Xml.NameTable(); XmlNamespaceManager nsMgr = new XmlNamespaceManager(nt); nsMgr.AddNamespace("w", "http://schemas.microsoft.com/office/word/2003/2/wordml"); XmlNode y = items.SelectSingleNode("*", nsMgr); DataSet ds = new DataSet(); if (y != null) { XmlReader xmlReader = new XmlTextReader(y.InnerXml, XmlNodeType.Element, null); ds.ReadXml(xmlReader); } return ds; } private Guid GetWebID() { SPData1.SiteData siteDataWS = new SPData1.SiteData(); siteDataWS.Credentials = new NetworkCredential(UserName, PassWord, DomainName); SPData1._sWebMetadata webMetaData; SPData1._sWebWithTime[] arrWebWithTime; SPData1._sListWithTime[] arrListWithTime; SPData1._sFPUrl[] arrUrls; string roles; string[] roleUsers; string[] roleGroups; uint i = siteDataWS.GetWeb(out webMetaData, out arrWebWithTime, out arrListWithTime, out arrUrls, out roles, out roleUsers, out roleGroups); Guid g = new Guid(webMetaData.WebID); return g; }
调用的小例子
this.UserName = "******"; this.PassWord = "******"; this.DomainName = "**"; string listname = "工作动态"; string camlStr = @" <OrderBy> <FieldRef Name='Created' Ascending='False' /> </OrderBy>"; camlStr += @" <Where><Gt> <FieldRef Name='ID' /> <Value Type='Counter'>3</Value> </Gt> </Where>"; string Fields = "<FieldRef Name='ID' /><FieldRef Name='Title' /><FieldRef Name='Created' />"; string rowLimit = "10"; DataSet ds = GetItems(listname, camlStr, Fields, rowLimit);
在上面的查询方法参数中GetItems 中 QueryOptions 可以通过设置得到一些其他的信息
XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions");
在Lambert Qin的博客中有针对QueryOptions使用的介绍
http://www.cnblogs.com/lambertqin/archive/2012/11/30/2796470.html