.NET Core 批量重置 Azure Blob Storage 的 mime type
點擊上方藍字關注“汪宇杰博客”
我的博客使用 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++;
? ? ? ? }
? ? }
}
參考文檔:http://www.thepatrickdavis.com/blob-storage-dont-forget-the-mime/
總結
以上是生活随笔為你收集整理的.NET Core 批量重置 Azure Blob Storage 的 mime type的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浅淡Kubernetes 与容器技术体系
- 下一篇: [NewLife.XCode]实体工厂(