Showing posts with label webservice. Show all posts
Showing posts with label webservice. Show all posts

Wednesday, September 18, 2013

Sharepoint WS - List - Delete file

here is the code to delete a file.
Note that FileRef cannot use encoded URL.
For the GetDocID method can refer to this post.

 private static void DeleteFile(string FilePath)  
     {  
       try  
       {  
         using (ListWS.Lists listService = new ListWS.Lists())  
         {  
           listService.Url = ListURL;  
           listService.Credentials = System.Net.CredentialCache.DefaultCredentials;  
           listService.Credentials = new System.Net.NetworkCredential(username, password);  
           //Get the file id  
           string fileName = FilePath.Substring(FilePath.LastIndexOf("/") + 1);  
           string DocID = GetDocID(fileName);  
           //get guid  
           string lListName = "EDMS";  
           XmlNode lSharePointListName = listService.GetList(lListName);  
           string lListID = lSharePointListName.Attributes["ID"].Value;   
           XmlDocument doc = new XmlDocument();  
           //Perform deletion  
           string xmlCommand;  
           doc = new XmlDocument();  
           //ID is the ID field value of MyFolder element  
           xmlCommand = "<Method ID='1' Cmd='Delete'><Field Name='ID'>" + DocID + "</Field><Field Name='FileRef'>" +   
             FilePath.Replace("%20"," ") + "</Field></Method>";  
           XmlElement ele = doc.CreateElement("Batch");  
           ele.SetAttribute("OnError", "Continue");  
           ele.SetAttribute("ListVersion", "1");  
           //ele.SetAttribute("RootFolder", FilePath.Substring(0, FilePath.LastIndexOf("/")));  
           ele.InnerXml = xmlCommand;  
           XmlNode node1 = listService.UpdateListItems(lListID, ele);  
           if ((node1 != null) && (node1.InnerText == SUCCESS))  
           {  
             Console.WriteLine("SUCCESS");  
           }  
           else  
           {  
             Console.WriteLine("There is an error : " + node1.InnerText);  
           }  
         }  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
     }  

here is the error that you may get:
1) 0x81020030Invalid file name.\n\nThe file name you specified could not be used. It may be the name of an existing file or directory, or you may not have permission to access the file.
This is because FileRef must be included in the query for deleting the item.

2) You got success code (0x00000000) however the file just stays there in the Document Library.
This is because the FileRef path is using encoded URL
(eg. http://url/a/b/c/cc%20c.pdf -> must change to -> http://url/a/b/c/cc c.pdf)
After changing to non-encoded URL, wala.. it's working like magic!

Hope it helps!

Sharepoint WS References

Good reference websites:
http://sarangasl.blogspot.sg/2009/12/addupdate-list-item-using-sharepoint.html
http://sarangasl.blogspot.sg/2009/12/sharepoint-list-web-service.html
http://sarangasl.blogspot.sg/2009/10/caml-spquery-in-sharepoint.html

CAML Query Helper to help you create the query, can just download, it's quite easy to use.
http://spcamlqueryhelper.codeplex.com/

Sharepoint WS - Copy - Move the file from one server to another

Here's the method
faxObj is just an object if u wan to include for the field information purpose.
EDMSPath is the source
EDMSRPath is the destination

 private static bool MoveEDMSToEDMSR(ISDAFaxDBO faxObj, string EDMSPath, string EDMSRPath, string msg ="")  
     {  
       using (CopyWS.Copy copyService = new CopyWS.Copy())  
       {  
         copyService.Url = CopyURL;  
         copyService.Credentials = System.Net.CredentialCache.DefaultCredentials;  
         copyService.Credentials = new System.Net.NetworkCredential(username, password);  
         CopyWS.FieldInformation fiEDMS = new CopyWS.FieldInformation();  
         CopyWS.FieldInformation[] fi = { fiEDMS };  
         byte[] byteArr;  
         uint getFile = copyService.GetItem(EDMSPath, out fi, out byteArr);  
         string[] destination = { EDMSRPath };  
         CopyWS.CopyResult cResult1 = new CopyWS.CopyResult();  
         CopyWS.CopyResult cResult2 = new CopyWS.CopyResult();  
         CopyWS.CopyResult[] cResultArray = { cResult1, cResult2 };  
         CopyWS.FieldInformation fiRecordDate = new CopyWS.FieldInformation();  
         fiRecordDate.DisplayName = "Record Date";  
         fiRecordDate.Type = CopyWS.FieldType.DateTime;  
         fiRecordDate.Value = faxObj.MaturityDate.ToString("yyyy/MM/ddT00:00:00Z");  
         CopyWS.FieldInformation fiSector = new CopyWS.FieldInformation();  
         fiSector.DisplayName = "Sector";  
         fiSector.Type = CopyWS.FieldType.Choice;  
         fiSector.Value = "Fax";  
         CopyWS.FieldInformation[] fis = { fiRecordDate, fiSector };  
         uint copyresult = copyService.CopyIntoItems(EDMSPath, destination, fis, byteArr, out cResultArray);  
         //Array.Resize<CopyWS.FieldInformation>(ref fi, fi.Length + 2);  
         //fi[fi.Length - 2] = fiRecordDate;  
         //fi[fi.Length - 1] = fiSector;  
         //uint copyresult = copyService.CopyIntoItems(EDMSPath, destination, fi, byteArr, out cResultArray);  
         if (copyresult == 0)  
         {  
           int idx = 0;  
           foreach (CopyWS.CopyResult myCopyResult in cResultArray)  
           {  
             string opString = (idx + 1).ToString();  
             if (cResultArray[idx].ErrorMessage == null)  
             {  
               msg += "Copy operation " + opString +  
                 "completed.\r\n" + "Destination: " +  
                 cResultArray[idx].DestinationUrl;  
             }  
             else  
             {  
               msg += "Copy operation " + opString +  
                 " failed.\r\n" + "Error: " +  
                 cResultArray[idx].ErrorMessage + "\r\n" +  
                 "Code: " + cResultArray[idx].ErrorCode;  
             }  
             idx++;  
           }  
           return true;  
         }  
         else  
         {  
           return false;  
         }  
       }  
     }  

Sharepoint WS - Lists - Check if folder exists and create folders

Here's the code to check if the folder exists using Sharepoint Web Service
EDMSRPath is the full path of the file (eg. http://url/ListName/blabla/be/bo/x.pdf)
WSPath is the url of the document library (eg. http://url)
 char[] separator = ("/").ToCharArray();  
       string[] folder = EDMSRPath.Substring(EDMSRPath.IndexOf("ListName") + ("ListName").Length + 1).Split(separator);  
 //check first folder  
       // This method is separated to avoid getting the subfolders for all top folders, as it will have too much recurrence.  
       getFolders(string.Empty, ref dt);  
       string firstFolder = WSPath + "/ListName";  
       if (!checkFolderExist(dt, firstFolder + "/" + folder[0]))  
       {  
         CreateFolder(firstFolder, folder[0]);  
       }  
       firstFolder += "/" + folder[0];  
       //check the subfolders required  
       dt = new DataTable();  
       if (folder.Length > 1)  
       {  
         getFolders(folder[0], ref dt, true);  
         string subfolder = firstFolder;  
         for (int i = 1; i < folder.Length; i++)  
         {  
           if (!checkFolderExist(dt, subfolder + "/" + folder[i]))  
           {  
             CreateFolder(subfolder, folder[i]);  
           }  
           subfolder += "/" + folder[i];  
         }  
       }  
Now the actual functions
CheckFolderExist - to check if the folder exists

     private static bool checkFolderExist(DataTable dt, string folderpath)  
     {  
       if (dt.Rows.Count > 0)  
       {  
         for (int i = 0; i < dt.Rows.Count; i++)  
         {  
           if (dt.Rows[i][0].ToString() == folderpath || dt.Rows[i][0].ToString() == folderpath.Replace(" ","%20"))  
           {  
             return true;  
           }  
         }  
       }  
       return false;  
     }  
And function to create the folder

     private static string CreateFolder(string path, string foldername)  
     {  
       string res = string.Empty;  
       try  
       {  
         using (ListWS.Lists listService = new ListWS.Lists())  
         {  
           listService.Url = ListURL;  
           listService.Credentials = System.Net.CredentialCache.DefaultCredentials;  
           listService.Credentials = new System.Net.NetworkCredential(username, password);  
           XmlDocument doc = new XmlDocument();  
           string xmlCommand = "<Batch OnError='Continue' RootFolder='" + path +  
               "'><Method ID='1' Cmd='New'><Field Name='ID'>New</Field><Field Name='FSObjType'>1</Field><Field Name='BaseName'>" +  
               foldername + "</Field></Method></Batch>";  
           doc.LoadXml(xmlCommand);  
           XmlNode batchNode = doc.SelectSingleNode("//Batch");  
           XmlNode node1 = listService.UpdateListItems("ListName", batchNode);  
           if ((node1 != null) && (node1.FirstChild.FirstChild.InnerText == FOLDER_EXISTS) || (node1.FirstChild.FirstChild.InnerText == SUCCESS))  
           {  
             // success  
             res = "";  
           }  
           else  
           {  
             res = "Create new folder failed for: " + foldername + ". Error Details: " + node1.InnerText;  
           }  
             
         }  
       }  
       catch (Exception ex)  
       {  
         if (ex.Message != "Column name 'ID' is defined for different mapping types.")  
           throw ex;  
       }  
       return res;  
     }  

Sharepoint WS - Copy - Save local file to EDMS

Here is the method to save the local file in your computer and put it to the document library, my list name is EDMS.

 private static bool saveFileInEDMS(ISDAFaxDBO faxObj, string localPath, string EDMSPath)  
     {  
       using (CopyWS.Copy copyService = new CopyWS.Copy())  
       {  
         copyService.Url = CopyURL;  
         copyService.Credentials = System.Net.CredentialCache.DefaultCredentials;  
         copyService.Credentials = new System.Net.NetworkCredential(username, password);  
         string[] destination = { EDMSPath };  
         CopyWS.CopyResult cResult1 = new CopyWS.CopyResult();  
         CopyWS.CopyResult cResult2 = new CopyWS.CopyResult();  
         CopyWS.CopyResult[] cResultArray = { cResult1, cResult2 };  
         CopyWS.FieldInformation fiRecordDate = new CopyWS.FieldInformation();  
         fiRecordDate.DisplayName = "Date";  
         fiRecordDate.Type = CopyWS.FieldType.DateTime;  
         fiRecordDate.Value = faxObj.MaturityDate.ToString("yyyy/MM/ddT00:00:00Z");  
         CopyWS.FieldInformation[] fis = { fiRecordDate };  
         FileStream strm = new FileStream(localPath, FileMode.Open, FileAccess.Read);  
         Byte[] fileContents = new Byte[strm.Length];  
         int ia = strm.Read(fileContents, 0, Convert.ToInt32(strm.Length));  
         strm.Close();  
         uint copyresult = copyService.CopyIntoItems(localPath, destination, fis, fileContents, out cResultArray);  
         if (copyresult == 0)  
         {  
           return true;  
         }  
         else  
         {  
           return false;  
         }  
       }  
     }  

Sharepoint WS - Lists - Get Document ID

Here is the function to get the document data and it will return the document ID in result string.

 private static string GetDocID(string docname)  
     {  
       try  
       {  
         string result="";  
         using (ListWS.Lists listService = new ListWS.Lists())  
         {  
           listService.Url = ListURL;  
           listService.Credentials = System.Net.CredentialCache.DefaultCredentials;  
           listService.Credentials = new System.Net.NetworkCredential(username, password);  
           XmlDocument doc = new XmlDocument();  
           XmlElement query = doc.CreateElement("Query");  
           XmlElement viewFields = doc.CreateElement("ViewFields");  
           XmlElement queryOptions = doc.CreateElement("QueryOptions");  
           //query.InnerXml = "<Where><Gt><FieldRef Name=\"ID\" />" +  
           //     "<Value Type=\"Counter\">0</Value></Gt></Where>";  
           //docname = "STAR.BE_CIS_B_My%20%20test%20123.pdf";  
           query.InnerXml = "<Where><Eq><FieldRef Name=\"LinkFilename\" />" +  
                "<Value Type=\"Text\">"+ docname.Replace("%20"," ") + "</Value></Eq></Where>";  
           //query.InnerXml = "<Where><BeginsWith><FieldRef Name=\"LinkFilename\" />" +  
           //     "<Value Type=\"Text\">S</Value></BeginsWith></Where>";  
           viewFields.InnerXml = "";  
           queryOptions.InnerXml = "<ViewAttributes Scope='Recursive'/>";  
           XmlNode nodes = listService.GetListItems("ListName", String.Empty, query, viewFields, string.Empty, queryOptions, null);  
           foreach (System.Xml.XmlNode node in nodes)  
           {  
             if (node.Name == "rs:data")  
             {  
               for (int i = 0; i < node.ChildNodes.Count; i++)  
               {  
                 if (node.ChildNodes[i].Name == "z:row")  
                 {  
                   for (int j = 0; j < node.ChildNodes[i].Attributes.Count; j++)  
                   {  
                     Console.WriteLine(j + "|" + node.ChildNodes[i].Attributes[j].Name + "|" + node.ChildNodes[i].Attributes[j].Value);  
                   }  
                   result = node.ChildNodes[i].Attributes["ows_ID"].Value;  
                 }  
               }  
             }  
           }  
         }  
         return result;  
       }  
       catch (Exception ex)  
       {  
         throw ex;  
       }  
     }  

Tuesday, May 28, 2013

Sharepoint webservice - create and get list of subfolders

To create folder
            Dim webUrl as string = "http://localhost/sites/test1/"
            Dim listWebService As New ListService.Lists()
            listWebService.Url = webUrl + "/_vti_bin/lists.asmx"
            listWebService.Credentials = System.Net.CredentialCache.DefaultCredentials 'New System.Net.NetworkCredential("user", "pwd")
            Dim doc As New XmlDocument
            Dim xmlCommand As String
            Dim node1 As XmlNode
            xmlCommand = "<Batch OnError='Continue' RootFolder='" & webUrl & "/Main'><Method ID='1' Cmd='New'><Field Name='ID'>New</Field><Field Name='FSObjType'>1</Field><Field Name='BaseName'>" & foldername & "</Field></Method></Batch>"
            doc.LoadXml(xmlCommand)
            Dim batchNode As XmlNode = doc.SelectSingleNode("//Batch")
            node1 = listWebService.UpdateListItems("Main", batchNode)
ListService is the web service http://localhost/sites/test1/_vti_bin/lists.asmx added as reference.

If you want to add subfolder, just need to change the rootfolder on the xmlCommand.

To get the list of subfolders (this can be used to check if subfolder exists)
   Sub getSubFolders(parent As String, ByRef retTable As DataTable)
        Dim query As String = "<mylistitemrequest><Query><Where><Eq><FieldRef Name=""FSObjType"" /><Value Type=""Lookup"">1</Value></Eq></Where></Query><ViewFields><FieldRef Name=""EncodedAbsUrl""/><FieldRef Name=""ID"" /><FieldRef Name=""Title"" /></ViewFields><QueryOptions><Folder>" & parent & "</Folder></QueryOptions></mylistitemrequest>"
        Dim dt As DataTable = Nothing
        Console.WriteLine("Parent is " & parent)
        Using listProxy As ListService.Lists = New ListService.Lists()
            listProxy.Url = webUrl + "/_vti_bin/lists.asmx"
            listProxy.UseDefaultCredentials = True

            Dim doc As XmlDocument = New XmlDocument()
            doc.LoadXml(query)

            Dim queryNode As XmlNode = doc.SelectSingleNode("//Query")
            Dim viewNode As XmlNode = doc.SelectSingleNode("//ViewFields")
            Dim optionNode As XmlNode = doc.SelectSingleNode("//QueryOptions")

            Dim retNode As XmlNode = listProxy.GetListItems("Main", String.Empty, queryNode, viewNode, String.Empty, optionNode, Nothing)

            Dim ds As DataSet = New DataSet()
            Using sr As StringReader = New StringReader(retNode.OuterXml)
                ds.ReadXml(sr)
            End Using



            If Not IsNothing(ds.Tables("Row")) Then
                If ds.Tables("Row").Rows.Count > 0 Then
                    Dim folderUrls = From f In ds.Tables("Row").AsEnumerable() Select f("ows_EncodedAbsUrl")
                    dt = ds.Tables("Row").Copy()

                    For Each folderUrl As String In folderUrls
                        getSubFolders(folderUrl, dt)
                    Next

                    retTable.Merge(dt)
                End If
            End If

        End Using

    End Sub

Comment the getSubFolders(folderUrl, dt) if you do not want to drill down the subfolders.

Subfolders references: here and here