0
votes

I am writing a service that uploads / downloads items from Azure Blob storage. When I upload a file I set the ContentType.

public async Task UploadFileStream(Stream filestream, string filename, string contentType)
{
    CloudBlockBlob blockBlobImage = this._container.GetBlockBlobReference(filename);
    blockBlobImage.Properties.ContentType = contentType;
    blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString());
    blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString());
    await blockBlobImage.UploadFromStreamAsync(filestream);
}

However when I retrieve the file the ContentType is null.

public async Task<CloudBlockBlob> GetBlobItem(string filename)
{
    var doesBlobExist = await this.DoesBlobExist(filename);
    return doesBlobExist ? this._container.GetBlockBlobReference(filename) : null;
}

In my code that uses these methods I check the ContentType of the returned Blob but it is null.

var blob = await service.GetBlobItem(blobname);
string contentType = blob.Properties.ContentType; //this is null!

I have tried using the SetProperties() method in my UploadFileStream() method (above) but this doesn't work either.

CloudBlockBlob blockBlobImage = this._container.GetBlockBlobReference(filename);
blockBlobImage.Properties.ContentType = contentType;
blockBlobImage.SetProperties(); //adding this has no effect
blockBlobImage.Metadata.Add("DateCreated", DateTime.UtcNow.ToLongDateString());
blockBlobImage.Metadata.Add("TimeCreated", DateTime.UtcNow.ToLongTimeString());
await blockBlobImage.UploadFromStreamAsync(filestream);

So how do I set the ContentType for a blob item in Azure Blob storage?

1
Can you share the code for this.DoesBlobExist method?Gaurav Mantri
Removing the error checking code it is essentially -- return await this._container.GetBlockBlobReference(filename).ExistsAsync();DomBurf
The problem with ExistsAsync is that it returns a Task<bool>. You need something that makes a network call and returns Task<CloudBlockBlob>.Gaurav Mantri

1 Answers

1
votes

The problem is with the following line of code:

this._container.GetBlockBlobReference(filename)

Essentially this creates an instance of CloudBlockBlob on the client side. It does not make any network calls. Because this method simply creates an instance on the client side, all the properties are initialized with default values and that's why you see the ContentType property as null.

What you would need to do is actually make a network call to fetch blob's properties. You can call FetchAttributesAsync() method on CloudBlockBlob object and then you will see the ContentType property filled in properly.

Please keep in mind that FetchAttributesAsync method can throw an error (e.g. 404 in case blob does not exists) so please ensure that the call to this method is wrapped in try/catch block.

You can try code like something below:

public async Task<CloudBlockBlob> GetBlobItem(string filename)
{
  try
  {
    var blob = this._container.GetBlockBlobReference(filename);
    await blob.FetchAttributesAsync();
    return blob;
  }
  catch (StorageException exception)
  {
    return null;
  }
}