I was trying to get a file from a SharePoint document library (host-web) with the .NET Client Object Model (CSOM) in a provider hosted app. I used the OpenBinaryDirect method from the File-class.
- List spList = ctx.Web.Lists.GetByTitle(“Dokumente”);
- CamlQuery camlQuery = new CamlQuery {ViewXml = String.Format(@”<View>
- <Query>
- <Where><Eq><FieldRef Name=’FileLeafRef’ /><Value Type=’File’>{0}</Value></Eq></Where>
- </Query>
- <ViewFields><FieldRef Name=’ID’ /><FieldRef Name=’FileRef’ /><FieldRef Name=’FileLeafRef’ /><FieldRef Name=’FileSizeDisplay’ /><FieldRef Name=’Title’ /></ViewFields>
- </View>”, filename)};
- ListItemCollection listItems = spList.GetItems(camlQuery);
- ctx.Load(listItems);
- ctx.ExecuteQuery();
- if (listItems.Count != 1) return null;
- var item = listItems.First();
- File file = item.File;
- ctx.Load(file);
- ctx.ExecuteQuery();
- FileInformation fileInfo = File.OpenBinaryDirect(ctx, file.ServerRelativeUrl);
But I’m getting a 401 unauthorized error, while the credentials are correct in the ClientContext.
After searching, I found this post: http://tech-karma.blogspot.se/2013/05/sharepoint-2013-online-app-403-response.html. It explained that OpenBinaryDirect is unable to evaluate the AppToken and is therefore unable to access SharePoint.
The solution is to use the OpenBinaryStream method of the File class. The result is delivered as a ClientResult. The file access works with:
- //FileInformation fileInfo = File.OpenBinaryDirect(ctx, file.ServerRelativeUrl);
- var clientResultStream = file.OpenBinaryStream();
- ctx.ExecuteQuery();
- var stream = clientResultStream.Value;
It works great. Thank you