接觸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