能否从内容URI获取精确的文件路径?

4

我正在使用机器人框架创建请求的机器人。在那里,我需要上传文件以支持工单。我遇到了一个问题,无法获取文件的确切文件路径。我能够获取内容URI。如何获取确切的文件路径,例如"**C:\Users\j.jobin\Pictures\Mobile\images.jpeg**"

以下是我正在使用的代码

foreach(Attachment file in filesData) {
  context.UserData.SetValue("Attachment", file.ContentUrl);
  string FileURL = file.ContentUrl; // @"C:\Users\j.jobin\Pictures\Mobile\images.jpeg";

  string fileName = file.Name;
  string test = fileName;
  //CreateSR(context);
  string p = FileURL;
  p = new Uri(p).LocalPath;

  string TicketNo = "24712";
  UploadAttchement(TicketNo, p, fileName);
}

内容 URI 的格式类似于http://localhost:56057/v3/attachments/479e6660-f6ef-11e8-9659-d50246e856bf/views/original

我尝试使用 string path = Path.GetFullPath(FileName);,但那会返回服务器路径(‘C:\Program Files (x86)\IIS Express\tesla-cat.jpg’),而不是本地文件路径。


可能是如何从文件名获取完整文件路径?的重复问题。 - Hamza Haider
如果文件是从服务器上传的,它可以通过字符串路径=Path.GetFullPath(FileName)获取当前目录路径。但是在这里上传时,我需要获取文件路径并将其存储在某个地方。 - Jobin Joseph
3
如果文件是从客户端上传到服务器的,你会发送一个包含字节数组的文件。你需要先将文件保存到服务器上然后再从磁盘中读取它,或者更方便的方法是直接使用数据流(stream)。 - Derviş Kayımbaşıoğlu
文件应该被视为流来处理,因为路径在机器人在远程机器上运行时会有所不同。通道应该将文件作为流或附件发送。 - Mandar Dharmadhikari
1个回答

2
没有机制可以检索文件在磁盘上的路径或用户上传它的本地路径(这被视为安全风险:如何使用jav获取更改文件输入类型时所选文件的完整路径)。
因为机器人连接到仿真器,所以ContentUrl属性是http://localhost:56057/v3/attachments/guid/views/original。该路径是Bot Framework Channel特定的。您的本地仿真器服务器托管在端口56057上。如评论中所述,您需要下载文件并将其保存在某个位置。
此示例演示了如何检索文件的字节:core-ReceiveAttachment
粗略修改以保存本地文件夹中的多个文件:(在生产环境中,没有其他保障措施,这不是一个好主意。最好使用Microsoft.WindowsAzure.Storage或类似的东西将字节上传到blob存储中。)
if (message.Attachments != null && message.Attachments.Any())
{
    using (HttpClient httpClient = new HttpClient())
    {
        // Skype & MS Teams attachment URLs are secured by a JwtToken, so we need to pass the token from our bot.
        if ((message.ChannelId.Equals(ChannelIds.Skype, StringComparison.InvariantCultureIgnoreCase) 
            || message.ChannelId.Equals(ChannelIds.Msteams, StringComparison.InvariantCultureIgnoreCase)))
        {
            var token = await new MicrosoftAppCredentials().GetTokenAsync();
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }

        foreach (Attachment attachment in message.Attachments)
        {
            using (var responseMessage = await httpClient.GetAsync(attachment.ContentUrl))
            {
                using (var fileStream = await responseMessage.Content.ReadAsStreamAsync())
                {
                    string path = Path.Combine(System.Web.HttpContext.Current.Request.MapPath("~\\Content\\Files"), attachment.Name);
                    using (FileStream file = new FileStream(path, FileMode.Create, FileAccess.Write))
                    {
                        await fileStream.CopyToAsync(file);
                        file.Close();
                    }
                }
                var contentLenghtBytes = responseMessage.Content.Headers.ContentLength;
                await context.PostAsync($"Attachment of {attachment.ContentType} type and size of {contentLenghtBytes} bytes received.");
            }
        }
    }
}

这个BotBuilder-v4的示例展示了另一种方法:15.handling-attachments/AttachmentsBot.cs#L204
private static void HandleIncomingAttachment(IMessageActivity activity, IMessageActivity reply)
        {
            foreach (var file in activity.Attachments)
            {
                // Determine where the file is hosted.
                var remoteFileUrl = file.ContentUrl;

                // Save the attachment to the system temp directory.
                var localFileName = Path.Combine(Path.GetTempPath(), file.Name);

                // Download the actual attachment
                using (var webClient = new WebClient())
                {
                    webClient.DownloadFile(remoteFileUrl, localFileName);
                }

                reply.Text = $"Attachment \"{activity.Attachments[0].Name}\"" +
                             $" has been received and saved to \"{localFileName}\"";
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接