前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET Core 批量重置 Azure Blob Storage 的 mime type

.NET Core 批量重置 Azure Blob Storage 的 mime type

作者头像
Edi Wang
发布2019-07-09 10:10:28
8630
发布2019-07-09 10:10:28
举报
文章被收录于专栏:汪宇杰博客汪宇杰博客

我的博客使用 Azure Blob Storage 存储文章配图,结果今天玩 Azure CDN 的时候爆了,原因是图片mime type不对。我们来看看如何在 .NET Core 里批量重置 Azure Blob Storage 中文件的mime type吧。

起因

使用编程方式(Azure Storage API)上传的文件,如果不指定 ContentType ,那么 Azure 不会聪明到根据文件拓展名设置 ContentType 。这个 ContentType 最终就是输出给浏览器的HTTP Header中的content-type,即Web服务器上的mime type。对于没有设置 ContentType 的文件,直接访问 Azure Blob 的地址,会返回"application/octet-stream"。不同浏览器对此处理方式不一样,大部分浏览器会调用文件下载,而不是打开文件。于是,图片就没法显示了。

我博客中的配图,以前之所以没问题,是因为没有使用CDN让客户端直接读取图片,而是通过后台处理,会自动加上正确的mime type,因此这个问题一直没暴露。

获取文件的 ContentType

.NET Core 没有 MimeMapping.GetMimeMapping() 这个API,因此我们需要一个workaround。

感谢长沙.NET技术社区成员 @刘命汉 的发现以及 @周杰 的验证,ASP.NET Core 自带的 FileExtensionContentTypeProvider 是个可替代方案。

var pvd = new FileExtensionContentTypeProvider();

bool isKnownType = pvd.TryGetContentType("test.png", out string mimeType);

// mimeType: "image/png"

对于不认识的拓展名,TryGetContentType() 会返回 false | null

CloudBlockBlob 不设置 ContentType 的话会返回默认的 application/octet-stream,因此null不影响。

更改文件的 ContentType

对于已经上传到 Azure Blob Storage 的文件,可以通过编程方式更改 ContentType 。获取到 CloudBlockBlob 对象以后,设置 Properties.ContentType,然后调用 SetPropertiesAsync() 方法保存更改即可。

对于未上传到Azure的文件,设置完 ContentType 以后,不需要调用 SetPropertiesAsync(), 上传操作 UploadFromStreamAsync() 会带上这些属性。

参见我博客代码commit: https://github.com/EdiWang/Moonglade/commit/3508e35055ae33b2c2241d93f615283a109bad85

自制开源工具

我今天抽空写了个批量重置 Azure Blob Storage 文件Mime Type 的工具,已在 GitHub 开源:

https://github.com/EdiWang/Azure-Blob-MimeType-Reset

关键代码

获取 CloudBlobContainer

有了 CloudBlobContainer 才能遍历里面的文件

private static CloudBlobContainer GetBlobContainer()

{

CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(Options.AccountName, Options.AccountKey), true);

CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer container = blobClient.GetContainerReference(Options.ContainerName);

return container;

}

修改ContentType

此处我做了个判断,只有 ContentType 不正确的文件,才重置 ContentType

private static CloudBlockBlob TrySetContentType(CloudBlockBlob blob, string contentType)

{

if (blob.Properties.ContentType.ToLower() != contentType)

{

blob.Properties.ContentType = contentType;

return blob;

}

return null;

}

遍历文件及提交更改

var pvd = new FileExtensionContentTypeProvider();

WriteMessage($"[{DateTime.Now}] Updating Mime Type...");

int affectedFilesCount = 0;

foreach (var blob in BlobContainer.ListBlobs().OfType<CloudBlockBlob>())

{

string extension = Path.GetExtension(blob.Uri.AbsoluteUri).ToLower();

bool isKnownType = pvd.TryGetContentType(extension, out string mimeType);

if (isKnownType)

{

if (TrySetContentType(blob, mimeType) != null)

{

WriteMessage($"[{DateTime.Now}] Updating {blob.Uri.AbsoluteUri} => {mimeType}");

await blob.SetPropertiesAsync();

affectedFilesCount++;

}

}

}

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 汪宇杰博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
内容分发网络 CDN
内容分发网络(Content Delivery Network,CDN)通过将站点内容发布至遍布全球的海量加速节点,使其用户可就近获取所需内容,避免因网络拥堵、跨运营商、跨地域、跨境等因素带来的网络不稳定、访问延迟高等问题,有效提升下载速度、降低响应时间,提供流畅的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档