Skip to content

Instantly share code, notes, and snippets.

@annelo-msft
Last active May 26, 2023 23:52
Show Gist options
  • Save annelo-msft/21e4cc8706fb9898bca7e32edeff8cb2 to your computer and use it in GitHub Desktop.
Save annelo-msft/21e4cc8706fb9898bca7e32edeff8cb2 to your computer and use it in GitHub Desktop.

Problem

We would like to add support for BinaryData in DynamicData. There is a PR available with the current proposal, which is to write BinaryData values as base64 encoded strings in the JSON: Azure/azure-sdk-for-net#36517

The open question is whether encoding BinaryData in JSON as a base64 encoded string is an acceptable user experience. If we took this approach, it would apply to the following use cases:

  1. Assignment of a BinaryData instance to a DynamicData property, e.g. json.Property = BinaryData.FromString("a")
  2. Converstion of a DynamicData property to a BinaryData value, e.g. BinaryData bd = (BinaryData)json.Property
  3. Serialization of a model type with a BinaryData property, e.g. json.Property = new Model()

Precedent

  • JsonElement's API for getting byte[] from a JsonElement instance uses a JSON string encoded as base64 -- see GetBytesFromBase64()

Scenarios

BYOM serialization

There is a concern that customers assigning serialized BYOM models might inadvertently do the following:

// Create the batch payload
dynamic batch = BinaryData.FromString("{}").ToDynamicFromJson();

// We'll serialize our strongly typed model with STJ, but could be JSON.NET
ObjectSerializer serializer = new JsonObjectSerializer(new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });

// Get the JSON for an individual document
Hotel hotel = new("123", "Just like a regular hotel.");
BinaryData hotelJson = serializer.Serialize(hotel);

// Add the doc to the batch
batch.value = new[] { hotelJson };

// "serialize" the batch
Console.WriteLine(batch.ToString());

// Simple Hotel model
public record Hotel(string Id, string Name);

Output is:

    {"value":["eyJpZCI6IjEyMyIsIm5hbWUiOiJKdXN0IGxpa2UgYSByZWd1bGFyIGhvdGVsLiJ9"]}

The user may have expected JSON to be written, and the would not get a warning that it wasn't.

Changing to either of the following would work as expected:

- batch.value = new[] { hotelJson };
+ batch.value = new[] { hotelJson.ToDynamicFromJson() };
- batch.value = new[] { hotelJson };
+ batch.value = new[] { hotelJson.ToObjectFromJson() };

Where the new output would be:

    {"value":[{"id":"123","name":"Just like a regular hotel."}]}

Adding ContentType to BinaryData

There is a proposal under consideration by the BCL team to add ContentType to BinaryData. If we did this, we could treat BinaryData assignments and serialized model properties as binary or JSON based on the underlying content type. If we wanted to wait for this option, we could throw in DynamicData when BinaryData values are assigned or serialized until it is available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment