C# CloudBlockBlob的URI在c中提供特殊字符#

C# CloudBlockBlob的URI在c中提供特殊字符#,c#,azure,azure-storage-blobs,C#,Azure,Azure Storage Blobs,我有如下与Azure Blob交互的简单代码。 我想获取上传文件的URL。 假设在blob存储中,我有一个容器,其中有多个文件夹,我需要获取文件的路径。因此,为了获取该路径,我尝试使用blockBlob.Uri参数 using Microsoft.WindowsAzure.Storage; using Microsoft.WindowsAzure.Storage.Blob; using System; using System.IO; namespace ConsoleApplication1

我有如下与Azure Blob交互的简单代码。
我想获取上传文件的URL。
假设在blob存储中,我有一个容器,其中有多个文件夹,我需要获取文件的路径。因此,为了获取该路径,我尝试使用blockBlob.Uri参数

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {         
            string   storageAccConnString = "Connection string";
            CloudStorageAccount storageAccount = "Account Name";
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            string folderPath    "Folder1" + Path.DirectorySeparatorChar + "Folder2" + Path.DirectorySeparatorChar + "Folder3";
            CloudBlobContainer container = blobClient.GetContainerReference(folderPath);
            CloudBlockBlob blockBlob = container.GetBlockBlobReference("Local system filePath which needs to be uploaded to Blob");
            Console.WriteLine("URI : " + blockBlob.Uri);
            Console.WriteLine("URI : " + blockBlob.Uri.ToString());
            Console.WriteLine("URI : " + blockBlob.Uri.OriginalString);
            Console.ReadLine();  
            // I didnt write the upload code as my question was regarding URI
        }
    }
}
我得到的是对此的响应,但不是像“
/
”或“
\
”这样的文件夹分隔符,而是
%5C

URI:


如何更正此问题。任何帮助都会很有用。谢谢。

查看您的代码,您似乎正在使用
System.IO.Path.directorySpeparatorChar
,它(根据)将:

提供特定于平台的字符,用于在反映分层文件系统组织的路径字符串中分隔目录级别

在Windows系统上运行时,
目录分离器CHAR
\
,而在Linux系统上则为
/

向web服务发出请求时,URI使用的路径分隔符是
/
,而
\
被认为是不安全的字符,需要编码-因此您看到的
%5C

要解决您所面临的问题,最简单的解决方案是用
“/”
替换您对
Path.directoryseportorchar
的使用

string folderPath=“Folder1/Folder2/Folder3”;

您的代码存在一些问题:

  • 首先,blob存储有两级层次结构:容器和blob。为容器创建引用的方式不正确。因为您的容器名称包含URL保留字符(
    \
    ),所以它的URL编码为
    %5C
  • 接下来,如果要在容器中的虚拟文件夹中上载文件,则需要将虚拟文件夹的路径附加到blob的名称中。例如,假设您有一个名为
    files
    的blob容器,并且您希望上载一个名为
    myfile.txt
    的文件,但将其放在
    Folder1/Folder2/Folder3
    虚拟文件夹中,您将这样做:

问题是您请求的是一个容器引用,其中包含目录分隔符。容器仅用于在根级别将blob分组在一起

容器组织一组blob,类似于文件系统中的目录。存储帐户可以包含无限数量的容器,容器可以存储无限数量的blob

资料来源:

blob中可以有目录分隔符,将它们组织在容器内的虚拟文件夹中


有关如何执行此操作的详细信息,请参见Blob存储实际上不使用文件夹和子文件夹。它只使用文件路径作为完整文件名。您所拥有的只是作为分离机制的容器。 您可以上载带有文件夹分隔符的文件,但实际上不会有多大作用,即使支持blob存储的文件浏览器通常会模拟文件夹。 只需在文件名中包含文件路径,即可模拟文件的位置。 要将文件移动到其他目录吗?只需重命名文件路径,等等

如果需要,可以通过以下方式解码URL:

    string input = "https://storageaccountname.blob.core.windows.net/Folder1%5CFolder2%5Folder3/Test.zip";
    string decoded = HttpUtility.UrlDecode(input);
    Console.WriteLine(decoded);

当您像这样保存文件时,请确保:

Stream str
...
CloudBlockBlob blob = container.GetBlockBlobReference(changePathCharacters(physicalRoute) + fileName);                        

blob.UploadFromStream(str);
physicalRoute没有文件夹分隔符的
\
,它必须有
/
分隔符:

private static string changePathCharacters(string path)
        {

            return path.Replace(@"\", @"/");
        }
然后在
blockBlob.Uri.AbsoluteUri
中,您将得到如下内容:

Stream str
...
CloudBlockBlob blob = container.GetBlockBlobReference(changePathCharacters(physicalRoute) + fileName);                        

blob.UploadFromStream(str);

https://storageaccountname.blob.core.windows.net/Folder1/Folder/Folder3/Test.zip

这就是URI嵌入特殊字符的方式。它们在远端应该可以被解码。@SteveTodd,我可以上传文件了。我在这方面没有任何问题。为了记录日志,我还必须打印URI。我无法获得带有特殊字符的正确URI。我不想使用String.Replace方法。@CrazyCoder这些是正确的URL字符。在任何情况下,在任何云存储提供商中都没有文件夹,而不是AWS、Google或Azure。所有这些都是带有blob的平面容器,blob的名称是容器URL后面的字符串。在AWS和Azure中,通过处理一些字符(如文件夹分隔符)来模拟Blob