c# - 下载从 Sharepoint 上传到 Bot 的图片返回 403 FORBIDDEN
问题描述
我正在使用 Bot Framework v4 SDK。我正在尝试将通过机器人上传到 Microsoft Teams 的图片下载到临时目录中,然后使用该图片。我之所以这样做是因为我需要拍摄一张用户附加到聊天中的照片,然后将这张照片放入文档中并将文档返回给用户。当我在模拟器上运行它时,这可以工作,但是一旦机器人在 Teams 中,我就会收到错误。
我通过 AttachmentPrompt 提示用户输入照片:
return await stepContext.PromptAsync(
"imagePrompt",
new PromptOptions
{
Prompt = MessageFactory.Text("Please attach a picture."),
});
从 stepContext.Result 中获取附件:
List<Attachment> contextAttachmentResult = (List<Attachment>)stepContext.Result;
确定文件的托管位置
var remoteFileUrl = contextAttachmentResult[0].ContentUrl;
设置系统临时目录的路径
var tempImagePath = Path.Combine(Path.GetTempPath(), contextAttachmentResult[0].Name);
并尝试使用WebClient
using (var webClient = new WebClient())
{
webClient.Headers.Add("User-Agent", "Other");
webClient.Headers.Add("Authorization", userProfile.Token);
webClient.DownloadFile(remoteFileUrl, tempImagePath);
}
我已经尝试将令牌放入从 中获得的令牌OAuthPrompt
,但我仍然得到 403。当我尝试下载它时,就会出现 403。我认为这是 SharePoint 问题的原因是因为如果我打印出来,remoteFileUrl
我会得到https://company-my.sharepoint.com/personal/my_name/Documents/Microsoft Teams Chat Files/someImage.png
堆栈跟踪的开头是:
System.Net.WebException: The remote server returned an error: (403) FORBIDDEN. at System.Net.HttpWebRequest.GetResponse() at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream) at System.Net.WebClient.DownloadFile(Uri address, String fileName)
编辑:根据米克的评论,我试图以ConnectorClient
这种方式使用(并尝试两种不同的下载方式):
using (var connectorClient = new ConnectorClient(new Uri(stepContext.Context.Activity.ServiceUrl, MYAPPID, MYAPPPASSWORD)))
{
var token = await (connectorClient.Credentials as MicrosoftAppCredentials).GetTokenAsync();
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contextAttachmentResult[0].ContentType));
var byteArray = await httpClient.GetByteArrayAsync(remoteFileUrl);
}
using (var webClient = new WebClient())
{
webClient.Headers.Add("User-Agent", "Other");
webClient.Headers.Add("Authorization", token);
webClient.DownloadFile(remoteFileUrl, siteReviewFile1ImagePath);
}
}
但即使我已将连接器设置为使用我的 appId 和 appPwd,我也会收到 401System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at System.Net.Http.HttpClient.d__30.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at IBIBot.Dialogs.SiteReviewSpace.SiteReviewDialog.<>c__DisplayClass4_0.<<-ctor>b__2>d.MoveNext() in
我仍然对如何获取此下载感到困惑
解决方案
这可以通过不使用 Attachment.ContentUrl 而是使用 Attachment.Content.DownloadUrl 来解决。downloadurl 是预授权下载,因此不需要任何承载或授权标头。我的代码看起来像这样:
var remoteFileUrl = ((JObject)contextAttachmentResult[0].Content)["downloadUrl"].ToString();
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, someFileLocationPath);
}
推荐阅读
- apache-spark - 在 Scala Spark 的 DataFrame 列中用新值替换指定值
- c++ - 如何为使用 CMAKE 的交叉编译配置设置特定的 CMAKE_C_OUTPUT_EXTENSION?
- python - 无法满足的错误 conda-installing MySQL-python
- java - 我怎样才能得到这个ID?
- python - 安装 lib 表时出错,在 windows 中找不到 hdf5
- text-editor - 括号扩展停止工作
- c# - 如何使标题文本在 TemplateField 中动态显示?
- maven - Jenkins 管道未完成 tomcat 战争部署
- python - 如何为每个点绘制具有指定颜色的 3D 散点图
- vba - 在 VBA 中将范围设置为找到的字符串位置