音乐网站怎么做外链,某班级网站建设方案,专业团队介绍文案,建筑人才网站哪个比较好点击上方蓝字关注“汪宇杰博客”我的博客使用 Azure Blob Storage 存储文章配图#xff0c;结果今天玩 Azure CDN 的时候爆了#xff0c;原因是图片mime type不对。我们来看看如何在 .NET Core 里批量重置 Azure Blob Storage 中文件的mime type吧。起因使用编程方式#xf… 点击上方蓝字关注“汪宇杰博客”我的博客使用 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 不正确的文件才重置 ContentTypeprivate 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().OfTypeCloudBlockBlob()){ 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; } }}参考文档http://www.thepatrickdavis.com/blob-storage-dont-forget-the-mime/