I posted yesterday about some pain I felt when working with SharePoint and the OData API, to balance the story this post cover some pleasure of working with it – that being uploading a file to document library using OData!
This is really easy to do, once you know how – but it’s the learning curve of Everest here which makes this really hard to get right, as you have both OData specialisations and SharePoint quirks to contend with. The requirements before we start is we need a file (as a stream), we need to know it’s filename, we need it’s 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 of DemoItem) and the item is a text file called Lorem ipsum.txt. I know it is a text file, which means I also know it’s Content Type is plain/text.
The code, below, is really simple and here are what is going on:
- Line 1: I am opening the file using the System.IO.File class, this 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 OData 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, this means that it is being tracked now locally – it is not in SharePoint yet. It is vital that this be done prior to you associating the stream.
- Line 18: I associate the stream of the file to the item. Once again, this is still only 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 I associate 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 what 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 still look at 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.