Upload file in document library with metadata including lookup field using sharepoint web service

Issue

When we try to upload document (especially pdf) with metadata association to sharepoint document library using CopyIntoItems method of Copy webservice. Then it works great for upload & association of metadata.

However it has one issue: It could not update metadata for lookup column but it does not throw any error also.

Description

This article will show you how to upload metadata and how to update lookup column while uploading document.

The Code:

The following functions shows how this can be done.

Function UploadFile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/// <summary>
/// This function upload document with metadata (except lookup fields) and return item id of uploaded document.
/// Note: this will not update all those fields which are lookup column.
/// </summary>
/// <param name="destinationPath"></param>
/// <param name="destinationFolderPath"></param>
/// <param name="sourceFilePath"></param>
/// <returns></returns>
public int UploadFile(string destinationPath, string destinationFolderPath, string sourceFilePath)
{
    /*
    // Example of parameters for this function
 
    //Parameter 1
    string destinationPath = <SiteUrl> + "/" + <DocumentLibraryName> + "/" + <FolderName1> 
                               + "/" + <FolderName2> + "/" + <FileName>;
    //Example
    string destinationPath = "http://sharepoint.infoyen.com" + "/" + "HistoricalDocs" 
                                + "/" + "Historical" + "/" + "IT" + "/" + "Historical_IT.doc";
 
    //Parameter 2
    string destinationFolderPath = <SiteUrl> + "/" + <DocumentLibraryName> + "/" + <FolderName1> 
                                     + "/" + <FolderName2>;
    //Example
    string destinationFolderPath = "http://sharepoint.infoyen.com" + "/" + "HistoricalDocs"  
                                     + "/" + "Historical" + "/" + "IT";
 
    //Parameter 3
    string sourceFilePath = "c:\HistoricalDocs\Historical\20121111\IT\Historical_IT.doc;
    */
 
	int result = -1; // -1 means failure
	Copy.Copy copyReference = new Copy.Copy();
	try
	{
		string destination = destinationPath;
		string[] destinationUrl = { destination };
		byte[] fileBytes = GetFileFromFileSystem(sourceFilePath);
		copyReference.Url = settings.SiteUri.ToString().TrimEnd('/') + "/_vti_bin/copy.asmx";
		copyReference.Credentials = new NetworkCredential(settings.User, settings.Password, settings.Domain); ;
 
		Copy.CopyResult[] cResultArray = null;
		Copy.FieldInformation documentTypeField = new Copy.FieldInformation();
		documentTypeField.DisplayName = "DocumentType";
		documentTypeField.Type = Copy.FieldType.Text;
		documentTypeField.Value = "HR";
		Copy.FieldInformation titleField = new Copy.FieldInformation();
		titleField.DisplayName = "Title";
		titleField.Type = Copy.FieldType.Text;
		titleField.Value = "HR1";
 
		//Associate metadata
		Copy.FieldInformation[] filedInfo = { documentTypeField, titleField };
		//Upload the document from Local to SharePoint
		copyReference.CopyIntoItems(destination, destinationUrl, filedInfo, fileBytes, out cResultArray);
		//Get item id of uploaded docuemnt // fileName will be like abc.pdf
		string fileName = Path.GetFileName(destinationPath);
		string queryXml = "<Where><And><Eq><FieldRef Name=’FileLeafRef’ /><Value Type=’File’>" + fileName +
		 "</Value></Eq><Eq><FieldRef Name=’ContentType’ /><Value Type=’Text’>Document</Value></Eq></And></Where>";
		string itemId = GetItemID(settings.DocumentLibrary, queryXml, destinationFolderPath);
 
		result = Convert.ToInt32(itemId);
	}
	catch (Exception ex)
	{//exception code here 
	}
	finally
	{
		if (copyReference != null)
			copyReference.Dispose();
	}
	return result;
}

Function GetFileFromFileSystem:}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary>
/// Read file and return bytes
/// </summary>
/// <param name="path">file path</param>
/// <returns>file bytes</returns>
private byte[] GetFileFromFileSystem(string path)
{
	byte[] fileBytes = null;
 
	if (File.Exists(path))
	{
		//read the file.
		using (FileStream fs = File.Open(path, FileMode.Open))
		{
			fileBytes = new byte[fs.Length];
			fs.Position = 0;
			fs.Read(fileBytes, 0, Convert.ToInt32(fs.Length));
		}
	}
	return fileBytes;
}

Function GetItemId:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/// <summary>
/// This function return item id based on query
/// </summary>
/// <param name="strListName">list name</param>
/// <param name="lookupTitleValue">lookup value</param>
/// <returns>look id</returns>
public string GetItemID(string strListName, string queryXml, string destinationFolderPath)
{
	Lists.Lists listReference = new Lists.Lists();
	string lookupId = string.Empty;
	try
	{
		listReference.Credentials = credentials;
		listReference.Url = settings.SiteUri.ToString().TrimEnd('/') + "/_vti_bin/lists.asmx";
		System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
		System.Xml.XmlElement query = xmlDoc.CreateElement("Query");
		System.Xml.XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
		System.Xml.XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");
		query.InnerXml = queryXml;
		viewFields.InnerXml = "<FieldRef Name="ID" />";
		queryOptions.InnerXml = "<Folder>" + destinationFolderPath + "</Folder>";
		System.Xml.XmlNode items;
		if (String.IsNullOrEmpty(destinationFolderPath))
			items = listReference.GetListItems(strListName, string.Empty, query, viewFields, string.Empty, null, null);
		else
			items = listReference.GetListItems(strListName, string.Empty, query, viewFields, string.Empty, 
                                                           queryOptions, null);
 
		foreach (System.Xml.XmlNode node in items)
		{
			if (node.Name == "rs:data")
			{
				for (int i = 0; i < node.ChildNodes.Count; i++)
				{
					if (node.ChildNodes[i].Name == "z:row")
					{
						lookupId = node.ChildNodes[i].Attributes["ows_ID"].Value;
						break;
					}
				}
			}
		}
	}
	catch (Exception ex)
	{
		//exception
	}
	finally
	{
		if (listReference != null)
			listReference.Dispose();
	}
 
	return lookupId;
}

Function UpdateMetaData:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/// <summary>
/// Update metadata of document in document library
/// You can generate query in below way:-
///string query = @"<Method ID=’1' Cmd=’Update’><Field Name=’ID’>" + itemID + "</Field>” +
///"<Field Name=’SPID’>" + spLookUpId + "</Field> </Method>";
/// </summary>
/// <param name="strListName">list name</param>
/// <param name="strCAML">metadata information in query</param>
public void UpdateMetaData(string strListName, string strCAML)
{
	Lists.Lists listReference = new Lists.Lists();
	try
	{
		listReference.Credentials = credentials;
		listReference.Url = settings.SiteUri.ToString().TrimEnd('/') + "/_vti_bin/lists.asmx";
 
		/*Get Name attribute values (GUIDs) for list and view. */
		System.Xml.XmlNode ndListView = listReference.GetListAndView(strListName, "");
		string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;
		string strViewID = ndListView.ChildNodes[1].Attributes["Name"].Value;
 
		/*Create an XmlDocument object and construct a Batch element and its
		 attributes. Note that an empty ViewName parameter causes the method to use the default view. */
		System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
		System.Xml.XmlElement batchElement = doc.CreateElement("Batch");
		batchElement.SetAttribute("OnError", "Continue");
		batchElement.SetAttribute("ListVersion", "1");
		batchElement.SetAttribute("ViewName", strViewID);
 
		/*Specify methods for the batch post using CAML. To update or delete, 
		 specify the ID of the item, and to update or add, specify 
		 the value to place in the specified column.*/
		batchElement.InnerXml = strCAML;
 
		/*Update list items. This example uses the list GUID, which is recommended, 
		 but the list display name will also work.*/
		listReference.UpdateListItems(strListID, batchElement);
	}
	catch (Exception ex)
	{
		//exception
	}
	finally
	{
		if (listReference != null)
			listReference.Dispose();
	}
}

Summary

I have done migration of more than 100 GB data using these functions. It works great. I have taken reference from below url to create these functions:-

http://msdn.microsoft.com/en-us/library/copy.copy.copyintoitems(v=office.12).aspx
http://msdn.microsoft.com/en-us/library/lists.lists.updatelistitems(v=office.12).aspx
http://msdn.microsoft.com/en-us/library/websvclists.lists.getlistitems.aspx

Hope it helps!!
Thanks.

calendarFebruary 23, 2012 · cardInfoyen · comments8 Comments
tagTags: , , , , , , , ,  · Posted in: MOSS, SharePoint, SharePoint 2010, Web Service

8 Responses

  1. Kuldeep - May 26, 2012

    hi;
    Thanks for this article. but have an issue in copy.copy class. I am unable to load that class even after adding the copy.asmx webservice into my project.

  2. Infoyen - May 27, 2012

    This question is not related this article and not related copy.asmx webservice.
    However I think if you add any webservice in your project; it will not work.
    My suggestion:
    Make your project work for any other web service then try copy.asmx.
    To do so you may try to take msdn help.
    These below point may help you run your project:
    1. Adding and Removing Web References http://msdn.microsoft.com/en-us/library/d9w023sx(v=vs.71).aspx
    2. Walkthrough: Creating a Custom ASP.NET Web Service
    http://msdn.microsoft.com/en-us/library/ms464040.aspx

    Note: To avoid security issues; You may work with admin access on dev machine.

    Thanks!

  3. Rosalie - October 14, 2012

    Thanks very nice blog!

  4. Lisa - November 29, 2012

    Thanks for the article, just a quick question on the destinationFolderPath in GetItemId function. Should it be a full url to the folder in the doc lib or a relative path or just the folder name?

  5. Infoyen - November 29, 2012

    Hi Lisa,
    Please find below parameters sample for “UploadFile” function:-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
     
    //Parameter 1
    string destinationPath = <SiteUrl> + "/" + <DocumentLibraryName> + "/" + <FolderName1> 
                                + "/" + <FolderName2> + "/" + <FileName>;
    //Example
    string destinationPath = "http://sharepoint.infoyen.com" + "/" + "HistoricalDocs" 
                                + "/" + "Historical" + "/" + "IT" + "/" + "Historical_IT.doc";
     
    //Parameter 2
    string destinationFolderPath = <SiteUrl> + "/" + <DocumentLibraryName> + "/" + <FolderName1> 
                                        + "/" + <FolderName2>;
    //Example
    string destinationFolderPath = "http://sharepoint.infoyen.com" + "/" + "HistoricalDocs"  
                                        + "/" + "Historical" + "/" + "IT";
     
    //Parameter 3
    string sourceFilePath = "c:\HistoricalDocs\Historical\20121111\IT\Historical_IT.doc;
  6. More hints - February 17, 2013

    It’s difficult to find well-formed details on this subject, however, you wrote perfectly.
    Thanks

  7. R2 - April 4, 2013

    Hi Infoyen,

    How can we do the same with a WCF client?

    I mean – using “Add Service Reference” in Visual Studio 2010, instead of “Add Web Reference”.

    Could you please consider posting another article for that? Thank you.

  8. Marcos - June 20, 2014

    Hi Infoyen,

    Thanks for the article, it helped me a lot.

    Regards
    M

Leave a Reply

Spam Protection: , required

myworldmaps infoyen