如何为Azure Blob Storage中的Blob项设置ContentType?
解决Azure Blob Storage设置ContentType后检索为null的问题
我之前也碰到过一模一样的问题,核心原因其实很明确:UploadFromStreamAsync方法会覆盖你提前设置的Blob属性——当你上传流时,SDK会默认重新处理Blob的属性(比如自动尝试检测ContentType,或者重置为默认值),所以你在上传前设置的ContentType直接被冲掉了,哪怕提前调用SetProperties()也没用,因为上传操作是在后面对Blob进行了完整的写入覆盖。
下面给你两种靠谱的解决方案,以及一个容易忽略的检索细节:
方案一:使用带ContentType参数的上传重载(最简洁)
直接用支持指定ContentType的UploadFromStreamAsync重载,上传和设置属性一步到位,避免后续覆盖问题:
public async Task UploadFileStream(Stream filestream, string filename, string contentType) { CloudBlockBlob blockBlobImage = this._container.GetBlockBlobReference(filename); // 先添加元数据 blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString()); blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString()); // 使用带ContentType参数的重载上传 await blockBlobImage.UploadFromStreamAsync(filestream, contentType); }
方案二:先上传,再设置属性并保存(更灵活)
如果需要批量设置多个属性或元数据,可以先完成上传,再修改属性并调用SetPropertiesAsync()持久化修改:
public async Task UploadFileStream(Stream filestream, string filename, string contentType) { CloudBlockBlob blockBlobImage = this._container.GetBlockBlobReference(filename); // 先完成文件上传 await blockBlobImage.UploadFromStreamAsync(filestream); // 上传后再设置ContentType和元数据 blockBlobImage.Properties.ContentType = contentType; blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString()); blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString()); // 分别保存属性和元数据的修改 await blockBlobImage.SetPropertiesAsync(); await blockBlobImage.SetMetadataAsync(); }
检索时的关键细节:手动加载Blob属性
另外你还要注意:通过GetBlockBlobReference()获取的Blob对象,默认不会自动加载远程的属性和元数据,所以需要在返回前调用FetchAttributesAsync()拉取最新数据,否则拿到的就是默认的null值:
public async Task<CloudBlockBlob> GetBlobItem(string filename) { var doesBlobExist = await this.DoesBlobExist(filename); if (!doesBlobExist) return null; var blob = this._container.GetBlockBlobReference(filename); // 手动拉取Blob的属性和元数据 await blob.FetchAttributesAsync(); return blob; }
这样调整后,你再调用获取方法时,blob.Properties.ContentType就能拿到正确的设置值了。
内容的提问来源于stack exchange,提问作者DomBurf
相关产品推荐
相关产品推荐

