【问题标题】:Uploading blockblob and setting contenttype上传 blockblob 并设置 contenttype
【发布时间】:2014-08-28 14:08:14
【问题描述】:

我正在使用来自 C# 的 Microsoft.WindowsAzure.Storage.* 库。

这就是我将内容上传到存储的方式:

// Store in storage
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("...connection string...");
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("pictures");

// Create container if it doesnt exist
container.CreateIfNotExists();

// Make available to everyone
container.SetPermissions(new BlobContainerPermissions
{
    PublicAccess = BlobContainerPublicAccessType.Blob
});

// Save image
CloudBlockBlob blockBlob = container.GetBlockBlobReference("blah.jpg");
blockBlob.UploadFromByteArray(byteArrayThumbnail, 0, byteArrayThumbnail.Length);
blockBlob.Properties.ContentType = "image/jpg";  // *** NOT WORKING ***

我上传到存储的所有内容都以内容类型“application/octet-stream”保存,即使我使用的是值为“image/jpg”的设置器(请参阅我代码中的最后一行)。

那么问题 #1:为什么 ContentType 设置器不起作用?

以及问题#2:如果我手动将内容类型更改为“image/jpg”,使用Windows Azure管理门户,然后将文件的绝对URI复制到浏览器的地址字段,然后回车,jpg文件下载而不是显示。这种 MIME 类型不应该显示而不是下载吗?我该如何更改?

【问题讨论】:

    标签: c# azure azure-storage content-type azure-blob-storage


    【解决方案1】:

    Properties 进行任何更改后,您必须调用CloudBlockBlob.SetProperties() 才能实际保存这些更改。

    把它想象成类似于 LINQ-to-Entities 的东西。您可以对本地对象进行任何更改,但在您调用 SaveChanges() 之前,实际上并没有保存任何内容。

    【讨论】:

    • SetProperties 方法应该用于更新 blob,而不是在创建时。
    • SetProperties 应该在任何时候使用,无论是第一次创建还是更新。根据我的观察,如果您使用文件名(带扩展名),那么它会将 ContentType 默认为与扩展名匹配的内容。如果您想确保它始终将其设置为您期望的内容类型,我会 (1) 上传数据,(2) 设置您的内容类型 (3) 调用 SetProperties() azure.microsoft.com/en-us/documentation/articles/…
    【解决方案2】:

    实际上你不必调用 SetProperties 方法。为了在上传 blob 时设置内容类型,只需在调用上传方法之前设置 ContentType 属性。所以你的代码应该是:

    // Save image
    CloudBlockBlob blockBlob = container.GetBlockBlobReference("blah.jpg");
    blockBlob.Properties.ContentType = "image/jpg";
    blockBlob.UploadFromByteArray(byteArrayThumbnail, 0, byteArrayThumbnail.Length);
    

    这应该可以解决问题。

    【讨论】:

    • 哇!,我会接受这两个答案:/ 无论如何,没有人回答我的第二个问题:当我将 URL 放入浏览器时,它会将图像下载为文件而不是显示。尝试了 image/jpeg 和 image/jpg。
    • 其实我尝试上传一个JPG文件并将其内容类型设置为image/jpg。当我将 URL 放入浏览器时,我能够在浏览器中看到图像。我尝试使用 IE/Firefox/Chrome。您能否在 Fiddler 中跟踪请求/响应并查看存储服务返回的实际内容类型?
    • 您是通过 SDK 还是直接从 Azure 门户上传的?我会尝试跟踪
    • 其实这不是真的,我相信您可能会看到这种行为,因为文件名带有扩展名。如果您使用其他标识符作为 blob 的名称(如数据库键)或使用没有扩展名的名称,您将不会得到此行为。
    • 这不会设置内容类型。由于 blob 名称中的 jpg 扩展名,它可能对您有用。
    【解决方案3】:

    对于新版本的 Azure Blob SDK,这不再有效。

    这对我有用:

    CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference(blobName);
    blockBlob.Properties.ContentType = contentType;                            
    await blockBlob.SetPropertiesAsync();
    

    【讨论】:

      【解决方案4】:

      显然最好将其设置为像 Gaurav Mantri 的答案一样创建,如果您已经过了这一点并且需要在此处更新其他答案可能会让您感到困惑。

      // GET blob
      CloudBlobContainer container = blobClient.GetContainerReference(containerName);
      CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName); 
      
      // if you don't do this you'll wipe properties you didn't mean to
      await blockBlob.FetchAttributesAsync();
      
      // SET
      blockBlob.Properties.ContentType = mimetype;
      
      // SAVE
      await blockBlob.SetPropertiesAsync();
      

      【讨论】:

        【解决方案5】:

        使用新的 SDK Azure.Storage.Blobs

        BlobHttpHeaders blobHttpHeaders = new BlobHttpHeaders();
        blobHttpHeaders.ContentType = "image/jpg";
        blobClient.SetHttpHeaders(blobHttpHeaders);
        

        【讨论】:

        • 如果 blob 只包含一个,它会与 BlockBlobClient.UploadAsync(Stream, BlobUploadOptions, CancellationToken) 一起崩溃:状态:404(指定的 blob 不存在。)正确的方法是设置 BlobUploadOptions.Headers在调用 UploadAsync 之前。
        【解决方案6】:

        很遗憾,此处提供的答案目前均不适用于最新的 SDK (12.x.+)

        使用最新的SDK,内容类型应通过BlobHttpHeaders设置。

        var _blobServiceClient = new BlobServiceClient("YOURCONNECTIONSTRING");
        
        var containerClient = _blobServiceClient.GetBlobContainerClient("YOURCONTAINERNAME");
        
        var blob = containerClient.GetBlobClient("YOURFILE.png");
        
        var blobHttpHeader = new BlobHttpHeaders();
        
        blobHttpHeader.ContentType = "image/png";
        
        var uploadedBlob = await blob.UploadAsync(YOURSTREAM, blobHttpHeader);
        

        【讨论】:

        • 对于使用最新 Azure Blob SDK(v12 及更高版本)的人的完美解决方案。谢谢!
        猜你喜欢
        • 2020-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多