Azure CloudBlobStream serialization (with Json.NET) Azure CloudBlobStream serialization (with Json.NET) json json

Azure CloudBlobStream serialization (with Json.NET)


In your code it looks like you are literally trying to serialize a Stream object as if it were data. This will not work. The exception is happening because the serializer is trying to read all the public properties from the Stream object. One of these properties is Length, which is not readable when the stream is opened for writing.

I think you are misunderstanding how to use streams with Json.Net and Azure storage blobs. The JsonConvert class is really just a façade, and unfortunately its SerializeObject() method does not have an overload that supports streams. To work with streams using Json.Net, you need to use a JsonSerializer instance along with a StreamWriter and JsonTextWriter if you're serializing to the stream, or StreamReader and JsonTextReader if you're deserializing from it.

Here are a couple of extension methods which you might find helpful and instructive:

public static class BlobExtensions{    public static async Task SerializeObjectToBlobAsync(this CloudBlockBlob blob, object obj)    {        using (Stream stream = await blob.OpenWriteAsync())        using (StreamWriter sw = new StreamWriter(stream))        using (JsonTextWriter jtw = new JsonTextWriter(sw))        {            JsonSerializer ser = new JsonSerializer();            ser.Serialize(jtw, obj);        }    }    public static async Task<T> DeserializeObjectFromBlobAsync<T>(this CloudBlockBlob blob)    {        using (Stream stream = await blob.OpenReadAsync())        using (StreamReader sr = new StreamReader(stream))        using (JsonTextReader jtr = new JsonTextReader(sr))        {            JsonSerializer ser = new JsonSerializer();            return ser.Deserialize<T>(jtr);        }    }}

Now let's say you have a class Item representing some data that you want to serialize to JSON and store into an Azure blob:

class Item {    public int Id { get; set; }    public string Name { get; set; }    public double Price { get; set; }}

Here's how you can do that using the first extension method:

...var item = new Item { Id = 1, Name = "Widget", Price = 2.5 };cloudBlockBlob.SerializeObjectToBlobAsync(item).Wait();

Conversely, if you want to retrieve the JSON from the blob and deserialize it back into an Item, you can use the other extension method:

var item = cloudBlockBlob.DeserializeObjectFromBlobAsync<Item>().Result;

Note: if you are using these methods from within an async method, you should use the await syntax instead of using Wait() and .Result, respectively:

await cloudBlockBlob.SerializeObjectToBlobAsync(item);...var item = await cloudBlockBlob.DeserializeObjectFromBlobAsync<Item>();


The paramter of the CloudBlobContainer.GetBlockBlobReference should be blob name.

please remove the containerName from your code.

 CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference("Test.txt"); //remove the container name from original code

According to the error execption, it indicates that JsonConvert.SerializeObject doesn't support CloudBlobStream as paramter.

Any idea on how to solve the problem?

If you want to get text string, you could use the cloudBlockBlob.DownloadTextAsync().So please change your code to following

container.CreateIfNotExistsAsync().Wait();CloudBlockBlob cloudBlockBlob = container.GetBlockBlobReference("Test.txt"); //make sure that blob is existingvar json = cloudBlockBlob.DownloadTextAsync().Result;