Upload files to SharePoint using OData!
I posted yesterday about some pain I felt when working with SharePoint and the OData API. To balance the story, this post covers some of the pleasure of working with it—that being uploading a file to a document library using OData!
This is really easy to do once you know how—but it’s the learning curve of Everest here that makes this so hard to get right, as you have both OData specializations and SharePoint quirks to contend with. Before we start, the requirements are that we need a file (as a stream), we need to know its filename, we need its content type, and we need to know where it will go.
For this post, I am posting to a document library called Demo (which is why OData generated the name DemoItem), and the item is a text file called Lorem ipsum.txt. I know it is a text file, which means I also know its content type is plain/text.
The code below is really simple, and here’s what’s going on:
- Line 1: I am opening the file using the System.IO.File class, which gives me the stream I need.
- Line 3: To communicate with the OData service, I use the DataContext class, which was generated when I added the service reference to the OData service and passed in the URI to the service.
- Line 8: Here, I create a DemoItem—remember, in SharePoint, everything is a list or a list item, even a document, which means I need to create the item first. I set the properties of the item over the next few lines. It is vital you set these and set them correctly, or it will fail.
- Line 16: I add the item to the context, meaning it is being tracked locally—it is not in SharePoint yet. It is vital that this be done prior to associating the stream.
- Line 18: I associate the stream of the file with the item. Once again, this is still happening locally—SharePoint has not been touched yet.
- Line 20: SaveChanges handles the actual writing to SharePoint.
using (FileStream file = File.Open(@"C:\Users\Robert MacLean\Documents\Lorem ipsum.txt", FileMode.Open))
{
DataContext sharePoint = new DataContext(new Uri("http://<sharepoint>/sites/ATC/_vti_bin/listdata.svc"));
string path = "/sites/ATC/Demo/Lorem ipsum.txt";
string contentType = "plain/text";
DemoItem documentItem = new DemoItem()
{
ContentType = contentType,
Name = "Lorem ipsum",
Path = path,
Title = "Lorem ipsum"
};
sharePoint.AddToDemo(documentItem);
sharePoint.SetSaveStream(documentItem, file, false, contentType, path);
sharePoint.SaveChanges();
}
Path Property
The Path property, which is set on the item (Line 12) and when associating the stream (Line 18, final parameter), is vital. This must be the path to where the file will exist on the server. This is the relative path to the file, regardless of the SharePoint site you are in. For example:
Path: /Documents/demo.txt
- Server: http://sharepoint1
- Site: /
- Document Library: Documents
- Filename: demo.txt
Path: /hrDept/CVs/abc.docx
- Server: http://sharepoint1
- Site: /hrDept
- Document Library: CVs
- Filename: abc.docx
Wrap-up
I still think you need to consider WebDAV as a viable way to handle documents that do not have metadata requirements. But if you have metadata requirements, this is a great alternative to the standard web services.