c# - AzureStorageFile.Uri 未返回具有特殊字 rune 件名的正确 Uri,导致 404 响应

标签 c# .net azure azure-storage

我正在编写一个程序来从给定的 AzureStorage 帐户下载所有数据和元数据。 我几乎完成了帐户的文件部分,但在测试我的输出后,我遇到了一些奇怪的事情。

当我检查其中包含特殊字符(例如 & é #)的文件名时,AzureStorageFile.Uri 方法返回的 Uri 与 AzureStorage Explorer 中的 Uri 不同.

一个示例是名为:& é #New Rich Text Document.rtf

该方法所需的 Uri 输出将是当我右键单击该文件并单击“属性”时 AzureStorage Explorer 给出的输出:http://accountname.file.core.windows.net/share/%26%20%C3%A9%20%23New%20Rich%20Text%20Document.rtf

但是运行代码后我得到的结果如下:https://accountname.file.core.windows.net/share/& é %23New Rich Text Document.rtf

我猜测在转换过程中一些特殊字符没有正确翻译,并且我没有发现该主题的类似问题。

编辑:Fred Han确实给出了解决方案,但问题仍然存在,当我使用GetFileReference获取CloudFile时,它仍然具有带有特殊字符的Uri属性。 执行 File.FetchAttributes 时,发送到服务器的请求使用错误编码的 File.Uri,我无法更改属性的值

如果我尝试使用其编码表示形式获取文件名,CloudFile.Uri 将在执行服务器请求时再次编码,这也会导致 404

我的目标是下载 CloudFile,而不仅仅是获取 URI,但我无法做到这一点,因为请求将使用错误编码的 URI

更新:我确实下载了该文件和所有其他包含特殊字符的文件,但我没有使用 File.Uri 属性来执行此操作,因为它的编码错误并且无法修改它的值(value)。我必须使用 GetFileReference 方法来执行此操作,但直接使用整个文件路径,而不仅仅是下面的答案/评论指出的文件名。然后我必须手动更正文件路径,然后获取文件引用并下载它。

public CloudFile getFile()
    {
        CloudFileClient client = AzureWorker.Connector.FileClient;
        CloudFileShare share = client.GetShareReference(ShareName);
        CloudFileDirectory root = share.GetRootDirectoryReference();

        string path = Uri.LocalPath.Substring(1, Uri.LocalPath.Length - 1);
        int index = path.IndexOf('/');
        path = path.Substring(index + 1, path.Length - index - 1).Replace("%25", "%");           
        index = path.LastIndexOf('/');
        StringBuilder sb = new StringBuilder(path);
        if (index != -1)
        {
            sb.Remove(index + 1, path.Length - index - 1);
            sb.Append(FileName);
            return root.GetFileReference(sb.ToString());
        }
        return root.GetFileReference(FileName);
    }

Uri 是我的类中 CloudFile 的 Uri 属性 FileName 是我的类中 Cloudfile 的 Name 属性 我认为只在我的类中存储 Uri 就足够了,因此此函数旨在获取带有 Uri 的正确文件并进行一些更正(适用于名称中带有特殊字符的文件夹)

感谢大家的帮助

最佳答案

我使用以下代码示例从名为 sinequa-data 的文件共享中获取名为 & é #New Rich Text Document.rtf 的文件的 Uri ,正如你所说,Uri中的文件名不是URL编码的。但文件共享名称仍然是 sinequa-data,它不会作为 share 返回。您应确保在使用 fileClient.GetShareReference("{file_share_name}") 获取共享引用时传递的文件共享名称是否正确。

CloudStorageAccount storageAccount = CloudStorageAccount.Parse("{connection_string}");

CloudFileClient fileClient = storageAccount.CreateCloudFileClient();


CloudFileShare share = fileClient.GetShareReference("sinequa-data");

if (share.Exists())
{

    CloudFileDirectory rootDir = share.GetRootDirectoryReference();

    CloudFile file = rootDir.GetFileReference("& é %23New Rich Text Document.rtf");

    if (file.Exists())
    {
        Console.WriteLine(file.Uri.ToString());
    }
}

enter image description here

Azure 存储资源管理器中文件的属性

enter image description here

此外,如果可能,您可以在将文件上传到文件共享之前对文件名进行编码。

编辑:

Azure存储资源管理器帮助我们对文件Uri中的文件名进行编码,但是Azure存储SDK不这样做,如果您想让Uri与Azure存储资源管理器返回的Uri相同,您可以尝试以下代码:

//Uri.EscapeUriString(file.Uri.ToString())

file.Share.Uri + "/" + Uri.EscapeUriString(file.Name).Replace("&", "%26")

enter image description here

更新:

首先,正如 Michael Roberson 提到的,我的文件名是 & é %23New Rich Text Document.rtf ,它与你的不同,所以如果你在你的程序中复制并运行我的代码,你收到 404 错误。

另外,我将文件重命名为&é#New Rich Text Document.rtf并修改了代码,示例代码适合我,你可以引用一下。

CloudStorageAccount storageAccount = CloudStorageAccount.Parse("{connection_string}");

CloudFileClient fileClient = storageAccount.CreateCloudFileClient();
List<CloudFileShare> fl = fileClient.ListShares().ToList();

CloudFileShare share = fileClient.GetShareReference("sinequa-data");

if (share.Exists())
{

    CloudFileDirectory rootDir = share.GetRootDirectoryReference();

    CloudFile file = rootDir.GetFileReference("& é #New Rich Text Document.rtf");


    if (file.Exists())
    {
        //encode the file name
        Console.WriteLine(file.Share.Uri + "/" + Uri.EscapeUriString(file.Name).Replace("&", "%26").Replace("#","%23"));

        //download file 
        file.DownloadToFile(@"d:\des1.rtf",FileMode.OpenOrCreate);
    }
}

关于c# - AzureStorageFile.Uri 未返回具有特殊字 rune 件名的正确 Uri,导致 404 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46302705/

相关文章:

c# - 如何在 ASP.NET MVC ActionLink 中将 C# 变量分配给 CSS 类变量

c# - 如果浏览器可以显示 Accept-Encoding of deflate,它可以处理 .NET gzip 响应吗?

c# - 我如何告诉设计者我的自定义 winforms 控件具有固定高度?

azure - 如何添加链接以在 Azure B2C 自定义策略中提供备用路由

python - Azure函数Python docker容器: Unable to find an Azure Storage connection string to use for this binding

c# - web.config 中的 Oracle 连接字符串抛出错误

c# - Azure blob 作为图像 Windows 窗体

.net - VSTO Outlook 2007 唯一邮件 ID

python - 当使用 asyncio.run 运行时,aio download_blob 可以工作一次,但不能工作两次

c# - 如何找到列表之间的差异?