3

I'm pretty sure this is a limitation of the Windows Azure SDK (Using the latest, 1.4), but there has got to be a way around this without using manual REST...

The code:

CloudBlob blob = container.GetBlobReference(url); // works
blob.UploadByteArray(bytes); // works
blob.Metadata["test"] = "public, max-age=259200"; // works
// FAILS with "The metadata specified is invalid. It has characters that are not permitted."
blob.Metadata["x-ms-blob-cache-control"] = "public, max-age=259200";
blob.SetMetadata(); // FAILS due to the 2nd meta data

It's pretty clear from my tests that the client is blowing up due to these dashes '-', but I cannot think of any way around this. Setting cache control is very important, and common operation, which baffles me as to why I cannot find anyone else reporting on this problem.

I've also tried encoding the data, which technically shouldn't be necessary, but out of desperation I did it anyway. Ideas?

Aaron
  • 475
  • 3
  • 14

2 Answers2

4

It ended up being a silly SDK limitation after all, there is a specific property which in turns sets that specific meta data for you... I don't mind having this property as a helper, but I see no reason why setting the meta directly shouldn't work.

blob.Properties.CacheControl = "public, max-age=259200";
blob.UploadByteArray(bytes);
Aaron
  • 475
  • 3
  • 14
  • 2
    Metadata is different from headers... if allowed, blob.Metadata["x-ms-blob-cache-control"] would send a header of "x-ms-meta-x-ms-blob-cache-control". (The "x-ms-meta" is there specifically to distinguish metadata from other kinds of headers.) – user94559 Jul 30 '11 at 17:31
  • 3
    In general, note that the rule concerning metadata is that the key has to follow C# identifier naming rules: http://msdn.microsoft.com/en-us/library/dd179414.aspx. (That's why you got an error.) – user94559 Jul 30 '11 at 17:34
  • I'm facing a similar issue when setting "filename" metadata. Do you know a workaround for that? – gayashanbc Aug 03 '21 at 14:38
0

You get this message still today but with the replacing 'BlobContainerClient' in nuget package Azure.Storage.Blobs, version 12.14.1. Below is a version of usage that works both with Azurite and deployed in Azure:

var blobClient = blobContainerClient.GetBlobClient(blobName);
    if (await blobClient.ExistsAsync())
    {
        // Azurite doesn't support tags and Azure doesn't support use of metadata so make it work case by case.
        var isLocalEnvironment = string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WEBSITE_INSTANCE_ID"));
        if (!isLocalEnvironment)
        {
            // This solution works only in Azure.
            var tags = new Dictionary<string, string>
            {
                { "TagKey1", "value1" },
                { "TagKey2", "value2" },
            };

            await blobClient.SetTagsAsync(tags);
        }
        else
        {
            // This solution works in Azurite (it does work in Azure also - but only without special characters).
            BlobProperties properties = blobClient.GetProperties();

            properties.Metadata["TagKey1"] = "value1";
            properties.Metadata["TagKey2"] = "value2";

            await blobClient.SetMetadataAsync(properties.Metadata);
        }
    }

Allowed special characters:

https://learn.microsoft.com/en-us/rest/api/storageservices/set-blob-tags?source=recommendations&tabs=azure-ad

Henrik
  • 1,897
  • 1
  • 16
  • 9