Home > OS >  How to SerializeObject which contains string value stored in BinaryData?
How to SerializeObject which contains string value stored in BinaryData?

Time:11-11

I am trying to Serialize ServiceBusReceivedMessage where the Message body is declared as BinaryData. So when I try to execute the below code, the body of the message is returned empty whereas the remaining properties in ServiceBusReceivedMessage are serialized as expected. What would be the efficient way to Serialize all the properties in the object?

var serviceBusClient = new ServiceBusClient(_serviceBusConnectionString);
 
ServiceBusReceiver receiver = serviceBusClient.CreateReceiver(queueName); 
             
IReadOnlyList<ServiceBusReceivedMessage> receivedMessages =
    await receiver.ReceiveMessagesAsync(maxMessages: 200, maxWaitTime: new TimeSpan(0, 0, 15)).ConfigureAwait(false);

foreach (ServiceBusReceivedMessage receivedMessage in receivedMessages)
{                
    var fullMessage = JsonConvert.SerializeObject(receivedMessage);
}

CodePudding user response:

BinaryData has no public properties, so you will need to write a custom JsonConverter in order to serialize it. And, while it is possible to construct a BinaryData from many different types of object including strings, serialized JSON, byte arrays and streams, internally it simply remembers its content as a ReadOnlyMemory<byte> field without any indication of how that binary data was constructed. Thus, since both Json.NET and System.Text.Json have built-in support for serializing a byte [] array with arbitrary binary content as a Base64 string, it makes sense to serialize BinaryData that way also. The following converter does the job:

public class BinaryDataConverter : JsonConverter<BinaryData>
{
    public override BinaryData ReadJson(JsonReader reader, Type objectType, BinaryData existingValue, bool hasExistingValue, JsonSerializer serializer) =>
        serializer.Deserialize<byte []>(reader) switch
        {
            null => null,
            var a => new BinaryData(a),
        };

    public override void WriteJson(JsonWriter writer, BinaryData value, JsonSerializer serializer) =>
        // For performance we avoid calling ToArray() (which copies the internal ReadOnlyMemory<byte> _bytes;) and use the implicit operator casting BinaryData to ReadOnlyMemory<byte>
        writer.WriteValue(Convert.ToBase64String(value));  
}

To use it, serialize as follows:

var settings = new JsonSerializerSettings
{
    Converters = { new BinaryDataConverter() },
};
var fullMessage = JsonConvert.SerializeObject(receivedMessage, settings);

Demo fiddle here.

CodePudding user response:

JSON is a format that encodes objects in a string. So serialization means to convert an object into that string, and deserialization is its inverse operation.

So we can say that suppose if we have an object like :

{foo: [1, 4, 7, 10], bar: "baz"}

Then, serializing into JSON will convert it into a string like the following:

'{"foo":[1,4,7,10],"bar":"baz"}'

Json.NET provides an excellent support for serializing and deserializing collections of objects. To serialize a collection like list, array and dictionary simply call the serializer with the object you want to get JSON for. Json.NET will serialize the collection and all of the values it contains.

The following code snippet shows how can you serialize a list of items.

Item i1 = new Item
{
    Name = "itemA",
    Price = 99rs,
    ExpiryDate = new DateTime(2000, 12, 29, 0, 0, 0, DateTimeKind.Utc),
};
Item i2 = new Item
{
    Name = "itemB",
    Price = 12rs,
    ExpiryDate = new DateTime(2009, 7, 31, 0, 0, 0, DateTimeKind.Utc),
};

List<Item> items = new List<Item>();
items.Add(i1);
items.Add(i2);

string Serializedjson = JsonConvert.SerializeObject(items, Formatting.Indented);

You don't need the loop. But to use it you may need to install the Newtonsoft.Json package first via NuGet Package Manager (Tools --> NuGet Package Manager --> Package Manager Console) :

PM> Install-Package Newtonsoft.Json

I would highly recommend to read this Json.NET documentation for more information on how to serialize and deserialize the collection of objects.

Note that if you are using .Net Core 3.0 or later version you can achieve the same by using the built in System.Text.Json parser implementation as show below.

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

You should also check this answer for more knowledge.

  • Related