Changing a Document in SharePoint Over HTTP Programmatically 

Tags:

Note: this post was derived from a solution first built by Wictor Wilen and Eric White, please reference this article for the complete write-up

 

There are many ways to programmatically retrieve documents from within SharePoint. Some choices are more obvious, like for instance when you're within a web request that has a SharePoint context. When that is the case the best approach is to leverage that SPContext (SPContext.Current.Site…) and pull out an SPFile object that contains the byte array of your document's content. However, some of the less obvious choices come when you don't have an SPContext. These are as follows:

 

Option 1) Leveraging the SharePoint API and specifically the SPFile Object (AGAIN)

Even without a SPContext you can get at the SharePoint API if your code is running on one of the farm's web front ends. In this case you'll have a SharePoint DLL available to you in the global assembly cache, and you can code against the API, eg: SPSite site = new SPSite("http://intranet");

 

Option 2) Leveraging the SharePoint Web Services

If you're not on the web front end, it would be a better choice to use SharePoint's web services to get at SharePoint data. For instance, with the Lists.asmx web service you can do stuff like download/upload a document, instantiate a new List, check out a document, etc. The only problem with the SharePoint web services is the goofy XML you got to deal with – making "batches", as they call them, can be daunting for newbies.

 

Option 3) Keep it simple with HTTP

A third and not well known approach is simply to use web requests to get at data over HTTP. If you know the URL to your SharePoint data, simply create a web request/response to that data and do something with it. The WebClient object makes this very easy:

 

using (WebClient wc = new WebClient())

{

    wc.Credentials = new NetworkCredential("domain\\username", "password");

    byte[] doc = wc.DownloadData("http://intranet/documents/documentA.docx");

    MemoryStream mems = new MemoryStream();

    mems.Write(doc, 0, doc.Length);

 

    // Make some Edit to the stream here...

 

    wc.UploadData(url, "PUT", mems.ToArray());

}

 

Notice how I'm passing credentials into this WebClient, and thus authenticating to secure SharePoint data. Then I call the DownloadData mehtod and pass a URL, this returns a byte array that contains my data/document from the web response. In essense these are the bytes of a document if that URL is the URL to a document in SharePoint, otherwise it would be the bytes of a SharePoint page or list.

 

Next I load that byte array into a stream, in which case I could make all kinds of alterations to that document that I want. Afterwards, I can call the UploadData mehtod to save my changes back into SharePoint.

 

Pretty easy huh? I guesss there's 2 morals to this story – 1) don't make things more complicated than they ought to be, and 2) HTTP web requests/responses still have their place. Truth be said, I often leverage all three mechanisms quite oftent, and the architecture usually dictates which approach is best. The order though makes sense. My first preference is option one. Then the second option is usually needed for more complicated functions. If it is simple I go with option 3.

 

Now with all that said – the Client Object model that comes new with SharePoint 2010 sure mixes this up a lot. But more on that later…

 

Phil

 
Posted by BENDER\pwicklund on 4-Nov-09
0  Comment  |  Trackback Url  | 0  Link to this post | Bookmark this post with:        
 
Failed to render control: Value does not fall within the expected range.

Comments

Bookmark and Share