Uploading An Object As JSON To Windows Azure Blob Storage

 original link

[2015/05/13] The code in this post has been updated to work with the “Windows Azure Storage 4.4.0-preview” NuGet package

Applying the ModelCommand pattern I was able to create a command that enables us to upload a serializable object as JSON and store it in an existing Blob Container.

Working with Json.NET, which can be installed using NuGet, we are able to serialize objects and send them to the Windows Azure Blob Storage. The UploadToBlogStorageAsJsonModelCommand was created specifically to simplify this process.

To upload JSON to a Blob Storage container we first have to get the Contrainer Reference using the container name provided by the constructor parameters. Then from the Container Reference we get the Blob Reference. We then prepare the Blob Reference with the provided Metadata and Properties before uploading the JSON to Windows Azure Blob Storage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class UploadToBlobStorageAsJson : ModelCommand<CloudStorageAccount>
{
    private const string CONTENT_TYPE = "application/json";
    private readonly object obj;
    private readonly string containerPath;
    private readonly string blobAddressUri;
    private readonly Dictionary<string, string> metadata;
    public UploadToBlobStorageAsJson(object obj,
                                        string containerPath,
                                        string blobAddressUri,
                                        Dictionary<string, string> metadata)
    {
        this.obj = obj;
        this.containerPath = containerPath;
        this.blobAddressUri = blobAddressUri;
        this.metadata = metadata;
    }
    public void Apply(CloudStorageAccount model)
    {
        var client = model.CreateCloudBlobClient();
        var container = client.GetContainerReference(containerPath);
        if (!container.Exists())
            container.Create();
        var blobReference = container.GetBlockBlobReference(blobAddressUri);
        var blockBlob = blobReference;
        UploadToContainer(blockBlob);
    }
    private void UploadToContainer(CloudBlockBlob blockBlob)
    {
        SetBlobProperties(blockBlob);
        using (var ms = new MemoryStream())
        {
            LoadStreamWithJson(ms);
            blockBlob.UploadFromStream(ms);
        }
    }
    private void SetBlobProperties(CloudBlockBlob blobReference)
    {
        blobReference.Properties.ContentType = CONTENT_TYPE;
        foreach (var meta in metadata)
        {
            blobReference.Metadata.Add(meta.Key, meta.Value);
        }
    }
    private void LoadStreamWithJson(Stream ms)
    {
        var json = JsonConvert.SerializeObject(obj);
        StreamWriter writer = new StreamWriter(ms);
        writer.Write(json);
        writer.Flush();
        ms.Position = 0;
    }
}

Using the UploadToBlobStorageAsJson ModelCommand

The following tests have been written to demonstrate an interesting side effect of theModelCommand. The first test shows how to instantiate a command and upload an object to Windows Azure Blob Storage. The second test is interesting because it applies the command twice, effectively reusing the command instance.

The command holds a reference to the object that it will serialize and send to the Windows Azure Blob Storage. By preserving the Command instance, we can upload the object. Then we can modify it locally and call Apply on the command to re-upload the modified object to the same Blob in Windows Azure Blob Storage.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[TestClass]
public class BlobStorageUnitTests
{
    [TestMethod]
    public void TestUploadToBlobStorage()
    {
        var obj = new
        {
            By = "Alexandre Brisebois",
            Message = "This is a test Message"
        };
        var uploadToBlobStorage = new UploadToBlobStorageAsJson(obj,
                                                "test",
                                                "testObject",
                                                new Dictionary<string, string>());
        var storageAccount = CloudStorageAccount.Parse(GetConnectionString());
        uploadToBlobStorage.Apply(storageAccount);
    }
    [TestMethod]
    public void TestUploadThenChangeThenUpload()
    {
        var obj = new
        {
            By = "Alexandre Brisebois",
            Message = "This is a test Message"
        };
        var uploadToBlobStorage = new UploadToBlobStorageAsJson(obj,
                                                "test",
                                                "testObject",
                                                new Dictionary<string, string>());
        var storageAccount = CloudStorageAccount.Parse(GetConnectionString());
        uploadToBlobStorage.Apply(storageAccount);
        obj = new
        {
            By = "Charles Brisebois",
            Message = "This is a test Message"
        };
        uploadToBlobStorage = new UploadToBlobStorageAsJson(obj,
                                                "test",
                                                "testObject",
                                                new Dictionary<string, string>());
        uploadToBlobStorage.Apply(storageAccount);
    }
    private static string GetConnectionString()
    {
        return CloudConfigurationManager.GetSetting("StorageConnectionString");
    }
}

The CloudConfigurationManager will first look for the Cloud Configurations, if it does not find them, it will then look a matching AppSetting. In this example it found the setting in the following App.Config.

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="StorageConnectionString"
         value="DefaultEndpointsProtocol=https;
                AccountName=*******;
                AccountKey=********" />
 </appSettings>
</configuration>

// RANDOM CODE

// get all blob from contrainer

var storageAccount = CloudStorageAccount.Parse(GetConnectionString());

var blobClient = storageAccount.CreateCloudBlobClient();

CloudBlobContainer container = blobClient.GetContainerReference(“tablesbloblogs”);

ConfigurationDetail configurationDetailsObj = null;

RedisCacheHelper.RedisCacheHelper redisCacheHelper = new RedisCacheHelper.RedisCacheHelper();

 

foreach (IListBlobItem item in container.ListBlobs(null, false))

{

if (item.GetType() == typeof(CloudBlockBlob))

{

CloudBlockBlob blob = (CloudBlockBlob)item;

var configurationDetails = blob.DownloadText();

configurationDetailsObj = JsonConvert.DeserializeObject<ConfigurationDetail>(configurationDetails);

//delete all blob items

blob.Delete();

}

}               redisCacheHelper.setConfigurationByKey(configurationDetailsObj);

 

 

 

 

One thought on “Uploading An Object As JSON To Windows Azure Blob Storage

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s