Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(401) Unauthorized exception while downloading file from SharePoint

I have generated an access token using OAuth mechanism for SharePoint Online server. I am using this token to create ClientContext using CSOM. While I am able to access all the sites, libraries, and folders seamlessly, I get error

The remote server returned an error: (401) Unauthorized.

while downloading the file from SharePoint Online. Below is the code that I am using for file download:

var clientContext = TokenHelper.GetClientContextWithAccessToken("https://adventurer.sharepoint.com/Subsite1", accessToken);
var list = clientContext.Web.Lists.GetByTitle("SubSite 1 Library 1");
string vquery = @"<View Scope='RecursiveAll'><Query><Where><Eq><FieldRef Name='UniqueId' /><Value Type='Lookup'>" + "6718053d-a785-489c-877f-5a4b88dcb2a7" + "</Value></Eq></Where></Query></View>";
CamlQuery query = new CamlQuery();
query.ViewXml = vquery;
var listItems = list.GetItems(query);
clientContext.Load(listItems, items => items.Take(1).Include(item => item.File));
clientContext.ExecuteQuery();

var fileRef = listItems[0].File.ServerRelativeUrl;
var fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(clientContext, fileRef);

I don't understand the root cause of this error, as I am passing client context with right access token. I want to know if OpenBinaryDirect has a limitation to work with access tokens? If not, what is wrong with above code? Is there any other alternative that can be used to download using access token?

like image 485
Saket Kumar Avatar asked Aug 14 '17 12:08

Saket Kumar


1 Answers

After trying a lot of alternatives, I have come to conclusion that OpenBinaryDirect() cannot be used with OAuth tokens. I was able to download file from SharePoint Online using two other approaches. I am posting the answers here so that it might help someone:

Approach 1 (OpenBinaryStream):

var file = clientContext.Web.GetFileByServerRelativeUrl(fileRef);
clientContext.Load(file);
clientContext.ExecuteQuery();                    
ClientResult<Stream> streamResult = file.OpenBinaryStream();
clientContext.ExecuteQuery();

While this approach works perfectly, OpenBinaryStream is not available in Microsoft.SharePoint.Client.dll <= v 14.0.0.0.

Approach 2 (WebClient or Other Http Requests):

string downloadUrl = HostURL + "/_api/web/getfilebyserverrelativeurl('" + fileRef + "')/$value";
WebClient client = new WebClient(); 
client.Headers.Add("Authorization", "Bearer " + accessToken);
client.DownloadFile(downloadUrl, filePath);

Note the download URL that I have used for WebClient. Normal file URL will not work to download files from SharePoint Online.

like image 69
Saket Kumar Avatar answered Oct 17 '22 08:10

Saket Kumar