我使用SharePoint Online服务器的OAuth机制生成了访问令牌。我使用此令牌使用CSOM创建ClientContext。虽然我能够无缝访问所有站点,库和文件夹,但我收到错误
从SharePoint Online下载文件时远程服务器返回错误:(401)未经授权。
。以下是我用于文件下载的代码:
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);
我无法理解此错误的根本原因,因为我正在使用正确的访问令牌传递客户端上下文。我想知道OpenBinaryDirect是否有限制使用访问令牌?如果没有,上面的代码有什么问题?是否有其他可用于使用访问令牌下载的替代方案?
答案 0 :(得分:0)
我正在使用C#,这就是我目前从SharePoint Online检索文档的方式。我在gridview中向用户显示了他们的文档列表,因此我使用文档填充DataTable。我不确定使用访问令牌的方式,但如果您能够像我一样使用服务帐户,那么希望这对您有所帮助。
命名空间
using Microsoft.SharePoint.Client;
using SP = Microsoft.SharePoint.Client;
对象属性
SecureString securePassword = new SecureString();
private string username = "";
ClientContext context = new SP.ClientContext("https://<root>.sharepoint.com/<site collection (unless root)>/<site>");
构造函数(这是我的身份验证方式)
public SharePoint()
{
securePassword = convertToSecureString(System.Web.Configuration.WebConfigurationManager.AppSettings["O365PW"]);
username = System.Web.Configuration.WebConfigurationManager.AppSettings["O365UN"];
context.Credentials = new SharePointOnlineCredentials(username, securePassword);
}
获取文件的方法
public DataTable GetDocuments(int changeID)
{
DataTable dt = new DataTable("ChangeDocuments");
DataRow dr = dt.NewRow();
dt.Columns.Add("Title");
dt.Columns.Add("URL");
dt.Columns.Add("ChangeID");
dt.Columns.Add("Modified");
dt.Columns.Add("ID");
// The SharePoint web at the URL.
Web web = context.Web;
// We want to retrieve the web's properties.
context.Load(web);
// We must call ExecuteQuery before enumerate list.Fields.
context.ExecuteQuery();
// Assume the web has a list named "Announcements".
SP.List oList = context.Web.Lists.GetByTitle("Name of your document library");
// This creates a CamlQuery that has a RowLimit of 100, and also specifies Scope="RecursiveAll"
// so that it grabs all list items, regardless of the folder they are in.
CamlQuery query = CamlQuery.CreateAllItemsQuery(100);
query.ViewXml = "<View><Query><Where><Eq><FieldRef Name='ChangeID'/>" +
"<Value Type='Number'>" + changeID + "</Value></Eq></Where></Query><RowLimit>100</RowLimit></View>";
SP.ListItemCollection items = oList.GetItems(query);
// Retrieve all items in the ListItemCollection from List.GetItems(Query).
context.Load(items);
context.ExecuteQuery();
foreach (Microsoft.SharePoint.Client.ListItem listItem in items)
{
// We have all the list item data. For example, Title.
dr = dt.NewRow();
dr["Title"] = listItem["FileLeafRef"];
if (String.IsNullOrEmpty(listItem["ServerRedirectedEmbedUrl"].ToString()))
{
dr["URL"] = "<root>/<site>/<document library>" + listItem["FileLeafRef"].ToString();
}
else
{
dr["URL"] = listItem["ServerRedirectedEmbedUrl"];
}
dr["ChangeID"] = listItem["ChangeID"];
dr["Modified"] = Convert.ToDateTime(listItem["Modified"]).ToString("MMM.dd,yyyy h:mm tt");
dr["ID"] = listItem["ID"];
dt.Rows.Add(dr);
}
return dt;
}
将密码转换为安全字符串的方法
private SecureString convertToSecureString(string strPassword)
{
var secureStr = new SecureString();
if (strPassword.Length > 0)
{
foreach (var c in strPassword.ToCharArray()) secureStr.AppendChar(c);
}
return secureStr;
}
答案 1 :(得分:0)
在尝试了很多替代方案后,我得出结论,OpenBinaryDirect()不能用它OAuth令牌。我能够使用其他方法从SharePoint Online下载文件。我在这里发布答案,以便它可以帮助某人:
方法1(OpenBinaryStream):
var file = clientContext.Web.GetFileByServerRelativeUrl(fileRef);
clientContext.Load(file);
clientContext.ExecuteQuery();
ClientResult<Stream> streamResult = file.OpenBinaryStream();
clientContext.ExecuteQuery();
虽然此方法运行良好,但OpenBinaryStream
&lt; = v 14.0.0.0中无法使用Microsoft.SharePoint.Client.dll
。
方法2(WebClient或其他Http请求):
string downloadUrl = HostURL + "/_api/web/getfilebyserverrelativeurl('" + fileRef + "')/$value";
WebClient client = new WebClient();
client.Headers.Add("Authorization", "Bearer " + accessToken);
client.DownloadFile(downloadUrl, filePath);
请注意我用于WebClient的下载URL。普通文件URL无法从SharePoint Online下载文件。