Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/api/Azure.Core.net461.cs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,9 @@ public JsonObjectSerializer(System.Text.Json.JsonSerializerOptions options) { }
public override object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<object?> DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { }
public override System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<System.BinaryData> SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public abstract partial class ObjectSerializer
{
Expand Down
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/api/Azure.Core.net5.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,9 @@ public JsonObjectSerializer(System.Text.Json.JsonSerializerOptions options) { }
public override object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<object?> DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { }
public override System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<System.BinaryData> SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public abstract partial class ObjectSerializer
{
Expand Down
2 changes: 2 additions & 0 deletions sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,9 @@ public JsonObjectSerializer(System.Text.Json.JsonSerializerOptions options) { }
public override object? Deserialize(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<object?> DeserializeAsync(System.IO.Stream stream, System.Type returnType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override void Serialize(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { }
public override System.BinaryData Serialize(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public override System.Threading.Tasks.ValueTask SerializeAsync(System.IO.Stream stream, object? value, System.Type inputType, System.Threading.CancellationToken cancellationToken) { throw null; }
public override System.Threading.Tasks.ValueTask<System.BinaryData> SerializeAsync(object? value, System.Type? inputType = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
}
public abstract partial class ObjectSerializer
{
Expand Down
14 changes: 14 additions & 0 deletions sdk/core/Azure.Core/src/Serialization/JsonObjectSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ public override async ValueTask SerializeAsync(Stream stream, object? value, Typ
return JsonSerializer.DeserializeAsync(stream, returnType, _options, cancellationToken);
}

/// <inheritdoc />
public override BinaryData Serialize(object? value, Type? inputType = default, CancellationToken cancellationToken = default) =>
SerializeToBinaryDataInternal(value, inputType);

/// <inheritdoc />
public override ValueTask<BinaryData> SerializeAsync(object? value, Type? inputType = default, CancellationToken cancellationToken = default) =>
new ValueTask<BinaryData>(SerializeToBinaryDataInternal(value, inputType));

private BinaryData SerializeToBinaryDataInternal(object? value, Type? inputType)
{
byte[] bytes = JsonSerializer.SerializeToUtf8Bytes(value, inputType ?? value?.GetType() ?? typeof(object), _options);
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The jsonSerializable ctor of BinaryData actually does this, but it seems better to be explicit here in terms of the serializer being used.

return new BinaryData(bytes);
}

/// <inheritdoc/>
string? IMemberNameConverter.ConvertMemberName(MemberInfo member)
{
Expand Down
87 changes: 87 additions & 0 deletions sdk/core/Azure.Core/tests/BinaryDataSerializationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
// Licensed under the MIT License.

using System;
using System.IO;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core.Serialization;
using NUnit.Framework;
Expand Down Expand Up @@ -76,6 +78,74 @@ async Task AssertData(BinaryData data)
}
}

[Test]
public async Task CustomSerializerCanCreateBinaryDataFromCustomType()
{
var payload = new Model { A = "value", B = 5, C = 3 };
// testing the base ObjectSerializer implementation
var serializer = new CustomSerializer();

await AssertData(await serializer.SerializeAsync(payload));
await AssertData(serializer.Serialize(payload));
await AssertData(await serializer.SerializeAsync(payload, typeof(Model)));
await AssertData(serializer.Serialize(payload, typeof(Model)));
await AssertData(await serializer.SerializeAsync(payload, null));
await AssertData(serializer.Serialize(payload, null));

async Task AssertData(BinaryData data)
{
Assert.AreEqual(payload.A, data.ToObject<Model>(serializer).A);
Assert.AreEqual(payload.B, data.ToObject<Model>(serializer).B);
Assert.AreEqual(0, data.ToObject<Model>(serializer).C);
Assert.AreEqual(payload.A, (await data.ToObjectAsync<Model>(serializer)).A);
Assert.AreEqual(payload.B, (await data.ToObjectAsync<Model>(serializer)).B);
Assert.AreEqual(0, (await data.ToObjectAsync<Model>(serializer)).C);
}
}

[Test]
public async Task CustomSerializerCanCreateBinaryDataFromCustomTypePassingBaseType()
{
var payload = new ExtendedModel() { A = "value", B = 5, C = 3, F = 5 };
// testing the base ObjectSerializer implementation
var serializer = new CustomSerializer();

await AssertData(await serializer.SerializeAsync(payload, typeof(Model)));
await AssertData(serializer.Serialize(payload, typeof(Model)));

async Task AssertData(BinaryData data)
{
Assert.AreEqual(payload.A, data.ToObject<Model>(serializer).A);
Assert.AreEqual(payload.B, data.ToObject<Model>(serializer).B);
Assert.AreEqual(0, data.ToObject<Model>(serializer).C);
Assert.AreEqual(payload.A, (await data.ToObjectAsync<Model>(serializer)).A);
Assert.AreEqual(payload.B, (await data.ToObjectAsync<Model>(serializer)).B);
Assert.AreEqual(0, (await data.ToObjectAsync<Model>(serializer)).C);
Assert.AreEqual(0, (await data.ToObjectAsync<ExtendedModel>(serializer)).F);
}
}

[Test]
public async Task CustomSerializerCanCreateBinaryDataFromNullObject()
{
Model model = null;
// testing the base ObjectSerializer implementation
var serializer = new CustomSerializer();

await AssertData(await serializer.SerializeAsync(model));
await AssertData(serializer.Serialize(model));
await AssertData(await serializer.SerializeAsync(model, typeof(Model)));
await AssertData(serializer.Serialize(model, typeof(Model)));
await AssertData(await serializer.SerializeAsync(model, null));
await AssertData(serializer.Serialize(model, null));

async Task AssertData(BinaryData data)
{
Assert.IsNull(data.ToObject<Model>(serializer));
Assert.IsNull(await data.ToObjectAsync<Model>(serializer));
}
}

public class Model
{
public string A { get; set; }
Expand Down Expand Up @@ -104,5 +174,22 @@ internal ExtendedModel(int readOnlyD)

public int F { get; set; }
}

public class CustomSerializer : ObjectSerializer
{
private static JsonObjectSerializer s_serializer = new JsonObjectSerializer();

public override object Deserialize(Stream stream, Type returnType, CancellationToken cancellationToken)
=> s_serializer.Deserialize(stream, returnType, cancellationToken);

public async override ValueTask<object> DeserializeAsync(Stream stream, Type returnType, CancellationToken cancellationToken)
=> await s_serializer.DeserializeAsync(stream, returnType, cancellationToken).ConfigureAwait(false);

public override void Serialize(Stream stream, object value, Type inputType, CancellationToken cancellationToken)
=> s_serializer.Serialize(stream, value, inputType, cancellationToken);

public async override ValueTask SerializeAsync(Stream stream, object value, Type inputType, CancellationToken cancellationToken)
=> await s_serializer.SerializeAsync(stream, value, inputType, cancellationToken).ConfigureAwait(false);
}
}
}