Azure Blob 存储 - 如何在上传 Blob 后获取 Blob 存储 ID?

时间:2021-01-20 11:04:55

标签: c# azure asp.net-core-3.1

我正在使用 C# 控制台应用程序 (.NET Core 3.1) 从 Azure Blob 存储读取大量图像文件并生成这些图像的缩略图。新图像将保存回 Azure,并将 Blob ID 存储在我们的数据库中。如何找到保存的项目的 ID。这是命令:

Azure.Response<BlobContentInfo> blobs = containerClient.UploadBlob(fileName, outStream);

我似乎在返回的对象中找不到它

https://docs.microsoft.com/en-us/dotnet/api/azure.storage.blobs.models.blobcontentinfo?view=azure-dotnet

我的原始图片是使用 PowerApps 创建和保存的,其中控件确实返回 Blob ID - 见下文:

 Set(
        gblSentBlob,
        AzureBlobStorage.CreateFile(
            Text(gblAzureFileContainer),
            GUID() & ".jpg",
            camControl.Photo
        )
    );
    If(
        !IsEmpty(gblSentBlob),
        Notify("Picture saved to Azure storage:" & gblSentBlob.DisplayName);
        UpdateContext({locFileName: gblSentBlob.DisplayName});
        UpdateContext({locAzureStorageID: Text(gblSentBlob.Id)}); // <- *** this is the Blob ID ***
        UpdateContext({locSavedToAzure: true});

这里,AzureBlobStorage.CreateFile 函数返回一个包含我要查找的 ID 的对象。

如何在我的控制台应用程序中获取此 ID。

典型的 Blob ID 如下所示:

JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==

然后我可以使用以下(在 PowerApps 中)检索要显示的图像

AzureBlobStorage.GetFileContent(ThisItem.BlobStorageID)

我的完整代码:

 var blobClient = containerClient.GetBlobClient(blobName);
                using Stream stream = await blobClient.OpenReadAsync();
                Image myImage = Image.FromStream(stream);
                Image myThumbnail = PictureProcessor.returnThumbnail(myImage);
                // now save this image
             
                string guid = Guid.NewGuid().ToString();
                string fileName = guid + ".jpg";
                //create a memory stream ready for the rescaled image
                Stream outStream = new MemoryStream();
                
                myThumbnail.Save(outStream, System.Drawing.Imaging.ImageFormat.Jpeg);

                Console.WriteLine(
                    "Length = {0}, Position = {1}\n",
                    outStream.Length.ToString(),
                    outStream.Position.ToString());

                outStream.Position = 0;
                Azure.Response<BlobContentInfo> blobs = containerClient.UploadBlob(fileName, outStream);

                Console.WriteLine("blobs RETURN OBJECT: " + blobs.ToString());
                Console.WriteLine("blobs GetRawResponse: " + blobs.GetRawResponse());
                
                Console.ReadKey();

2 个答案:

答案 0 :(得分:1)

当我将其从 Base64 解码然后解码为 UTF-8 时:

JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==

我明白了:

%2fshireblobcontainer%2f5973484f-4ea7-472d-9234-ab07395ce8db.jpg

因此,您的“Blob ID”似乎是您传入 AzureBlobStorage.CreateFile 的 URL 编码字符串值的 UTF-8(或 7 位 ASCII?)表示的 Base64 编码表示第二个参数。

这样做:

String powerAppsBlobId = @"JTJmc2hpcmVibG9iY29udGFpbmVyJTJmNTk3MzQ4NGYtNGVhNy00NzJkLTkyMzQtYWIwNzM5NWNlOGRiLmpwZw==";

Byte[] blobIdBytes = Convert.FromBase64String( powerAppsBlobId );

String urlEncodedBlobName = Encoding.UTF8.GetString( bytes );

String actualBlobName = Uri.UnescapeDataString( urlEncodedBlobName );

Console.WriteLine( actualBlobName )

这个程序会打印:

/shireblobcontainer/5973484f-4ea7-472d-9234-ab07395ce8db.jpg

答案 1 :(得分:0)

在发布我的第一个答案(使用 Base64 解码)I took a look at the documentation for the Azure Blob connector for PowerApps 后,我发现 BlobMetadata.Name 和/或 BlobMetadata.Path 值也应该包含完整的 blob 名称.

我不知道你为什么指出 Azure.Storage.Blobs.Models 的文档,因为它不是供 PowerApps 使用的。

因此,更好的主意是在您从 PowerApps 中上传 blob 时存储 Blob.MetadataPath 值,以便您的控制台应用程序可以访问它 - 这是以防 PowerApps 更改其生成这些 Base64 的“算法” BlobId(例如,它们可以包含 Blob 版本日期+时间或共享访问签名)。

把你的代码改成这样:

 Set(
        gblSentBlob,
        AzureBlobStorage.CreateFile(
            Text(gblAzureFileContainer),
            GUID() & ".jpg",
            camControl.Photo
        )
    );
    If(
        !IsEmpty(gblSentBlob),
        Notify("Picture saved to Azure storage:" & gblSentBlob.DisplayName);
        UpdateContext({locFileName: gblSentBlob.DisplayName});
        UpdateContext({locAzureStorageID: Text(gblSentBlob.Id)});
        UpdateContext({locAzureStoragePath: Text(gblSentBlob.Path)}); // <--- Add this here
        UpdateContext({locSavedToAzure: true});