locked
Why is my metadata of a blob not stored? RRS feed

  • Question

  • Hi there,

    I upload a picture. Here is my code:

    CloudBlockBlob blob = cloudBlobContainer.GetBlockBlobReference(filename);
    blob.Metadata["FileType"] = "img";
    blob.Metadata["FileName"] = fuPicture.FileName;
    blob.Properties.ContentType = fuPicture.PostedFile.ContentType;
    
    // Upload the blob to the storage
    blob.UploadFromStream(fuPicture.FileContent);
    
    

    The picture is stored as blob (this works). However, the metadata is not stored. I also tried to read it and let some code count the metakeys (always 0).

    What am I doing wrong?

    Monday, April 25, 2011 8:03 PM

Answers

  • Yes, setting metadata before uploading will fail with NotFound. However, you do not require a separate SetMetadata call since your metadata would have been uploaded in the Upload request (either with PutBlob or PutBlockList call depending on the size of the blob being uploaded).

    In the Get path, I realized that you are not using the item itself which would have the metadata. When you create a new reference, it would require a call to FetchAttributes. The IListBlobItem can either be a CloudBlobDirectory or a CloudBlob. Here is some code that you can use to validate the metadata:

          IEnumerable<IListBlobItem> blobList = container.ListBlobs(new BlobRequestOptions()
            {
               BlobListingDetails = BlobListingDetails.Metadata,
               //UseFlatBlobListing = true // use this for just retrieving a list of blobs in a flat structure
            });
          foreach (IListBlobItem item in blobList)
          {
            CloudBlob blobItem = item as CloudBlob;
            if (blobItem != null)
            {
               // the blobItem instance will have metadata set on it
            }
            else
            {
               // this will be a CloudBlobDirectorywhen flat listing is NOT used 
            }
          }
    

    Thanks,

    jai

    • Marked as answer by Wenchao Zeng Monday, May 2, 2011 3:07 AM
    Tuesday, April 26, 2011 2:44 PM

All replies

  • You forgot to call blob.SetMetadata() after uploading the blob.
    Cory Fowler Windows Azure MVP http://blog.syntaxc4.net

    Monday, April 25, 2011 8:32 PM
    Answerer
  • As SyntaxC4 mentioned, SetMetaData() call would persist metadata into Blob service.

    @SyntaxC4 - I am just curious, does it matter whether invoking SetMetaData() before or after Uploading the content to blob? I guess, the prerequisite for SetMetaData() is only existance of blob and SetMetaData() and Upload operations are independent calls (is there any way to do these two operations in single call, as these both refer same blob?). Please correct me, if I am wrong.

     

    HTH.


    Please mark it as answer by clicking on "Propose As Answer", if it helps. My Blog : http://dotnetizen.blogspot.com
    Monday, April 25, 2011 8:54 PM
  • --  I am just curious, does it matter whether invoking SetMetaData() before or after Uploading the content to blob?

    If memory serves, invoking SetMetaData() before uploading the blob causes an error that the blob does not exist.

    Monday, April 25, 2011 9:42 PM
    Answerer
  • The PutBlob/PutBlockList REST APIs do support uploading metadata in a single call. The client library call should have sent the metadata. Can you use fiddler or wireshark to see the http trace over the wire? This should tell us what headers were sent over the wire.

    Also, how did you validate that this metadata was not saved? Was this after getting a blob reference and invoking FetchAttributes?

    Traces can aid us in understanding why the metadata was not uploaded along with the blob.

     

    Thanks,

    jai

    Tuesday, April 26, 2011 8:12 AM
  • I tried to add SetMetaData() before the UploadFromStream() method. This results in the exception "the specified blob does not exist", as Neil Mackenzie mentioned before. Thus, we have to add the meta data after the UploadFromStream() method.

    I use this code to select the blobs:

    BlobRequestOptions blobRequestOptions = new BlobRequestOptions();
    blobRequestOptions.BlobListingDetails = BlobListingDetails.Metadata;
    
    IEnumerable<IListBlobItem> blobList = cloudBlobContainer.ListBlobs(blobRequestOptions);
    
    foreach (IListBlobItem item in blobList) {
    CloudBlob blob = cloudBlobClient.GetBlobReference(item.Uri.ToString());
    
    [..] blob.Metadata.Count.ToString();
    
    }
    

    I thought it will get the metadata because of blobRequestOptions, however I needed to add blob.FetchAttributes() before the [..] to get the counter to work. Why is that?

    Tuesday, April 26, 2011 9:03 AM
  • Yes, setting metadata before uploading will fail with NotFound. However, you do not require a separate SetMetadata call since your metadata would have been uploaded in the Upload request (either with PutBlob or PutBlockList call depending on the size of the blob being uploaded).

    In the Get path, I realized that you are not using the item itself which would have the metadata. When you create a new reference, it would require a call to FetchAttributes. The IListBlobItem can either be a CloudBlobDirectory or a CloudBlob. Here is some code that you can use to validate the metadata:

          IEnumerable<IListBlobItem> blobList = container.ListBlobs(new BlobRequestOptions()
            {
               BlobListingDetails = BlobListingDetails.Metadata,
               //UseFlatBlobListing = true // use this for just retrieving a list of blobs in a flat structure
            });
          foreach (IListBlobItem item in blobList)
          {
            CloudBlob blobItem = item as CloudBlob;
            if (blobItem != null)
            {
               // the blobItem instance will have metadata set on it
            }
            else
            {
               // this will be a CloudBlobDirectorywhen flat listing is NOT used 
            }
          }
    

    Thanks,

    jai

    • Marked as answer by Wenchao Zeng Monday, May 2, 2011 3:07 AM
    Tuesday, April 26, 2011 2:44 PM
  • you may have already created the metadata but you didn't yet set it to the blob, so all you need to do is blobname.SetMetadata();
    Tuesday, July 23, 2013 12:26 AM