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: 1 addition & 1 deletion sdk/core/Azure.Core/api/Azure.Core.net461.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ public SerializableOptions() { }
public bool IgnoreAdditionalProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool PrettyPrint { get { throw null; } set { } }
public Azure.Core.Serialization.ObjectSerializer? Serializer { get { throw null; } set { } }
public System.Collections.Generic.Dictionary<System.Type, Azure.Core.Serialization.ObjectSerializer> Serializers { get { throw null; } }
}
}
namespace Azure.Messaging
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/Azure.Core/api/Azure.Core.net5.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ public SerializableOptions() { }
public bool IgnoreAdditionalProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool PrettyPrint { get { throw null; } set { } }
public Azure.Core.Serialization.ObjectSerializer? Serializer { get { throw null; } set { } }
public System.Collections.Generic.Dictionary<System.Type, Azure.Core.Serialization.ObjectSerializer> Serializers { get { throw null; } }
}
}
namespace Azure.Messaging
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/Azure.Core/api/Azure.Core.net6.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ public SerializableOptions() { }
public bool IgnoreAdditionalProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool PrettyPrint { get { throw null; } set { } }
public Azure.Core.Serialization.ObjectSerializer? Serializer { get { throw null; } set { } }
public System.Collections.Generic.Dictionary<System.Type, Azure.Core.Serialization.ObjectSerializer> Serializers { get { throw null; } }
}
}
namespace Azure.Messaging
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/Azure.Core/api/Azure.Core.netcoreapp2.1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ public SerializableOptions() { }
public bool IgnoreAdditionalProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool PrettyPrint { get { throw null; } set { } }
public Azure.Core.Serialization.ObjectSerializer? Serializer { get { throw null; } set { } }
public System.Collections.Generic.Dictionary<System.Type, Azure.Core.Serialization.ObjectSerializer> Serializers { get { throw null; } }
}
}
namespace Azure.Messaging
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/Azure.Core/api/Azure.Core.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1173,7 +1173,7 @@ public SerializableOptions() { }
public bool IgnoreAdditionalProperties { get { throw null; } set { } }
public bool IgnoreReadOnlyProperties { get { throw null; } set { } }
public bool PrettyPrint { get { throw null; } set { } }
public Azure.Core.Serialization.ObjectSerializer? Serializer { get { throw null; } set { } }
public System.Collections.Generic.Dictionary<System.Type, Azure.Core.Serialization.ObjectSerializer> Serializers { get { throw null; } }
}
}
namespace Azure.Messaging
Expand Down
48 changes: 42 additions & 6 deletions sdk/core/Azure.Core/samples/Serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ DogListProperty dog = new DogListProperty
};

//STJ example
string json = JsonSerializer.Serialize(dog);
string json = System.Text.Json.JsonSerializer.Serialize(dog);
```

Deserialization
Expand All @@ -109,7 +109,7 @@ Deserialization
string json = "{\"latinName\":\"Animalia\",\"weight\":1.1,\"name\":\"Doggo\",\"isHungry\":false,\"foodConsumed\":[\"kibble\",\"egg\",\"peanut butter\"],\"numberOfLegs\":4}";

//stj example
DogListProperty dog = JsonSerializer.Deserialize<DogListProperty>(json);
DogListProperty dog = System.Text.Json.JsonSerializer.Deserialize<DogListProperty>(json);
```

## Using static deserializer
Expand Down Expand Up @@ -162,7 +162,7 @@ DogListProperty dog = new DogListProperty
FoodConsumed = { "kibble", "egg", "peanut butter" },
};
SerializableOptions options = new SerializableOptions();
options.Serializer = new NewtonsoftJsonObjectSerializer();
options.Serializers.Add(typeof(DogListProperty), new NewtonsoftJsonObjectSerializer());

Stream stream = ModelSerializer.Serialize(dog, options);
```
Expand All @@ -171,7 +171,7 @@ Deserialization

```C# Snippet:NewtonSoft_Deserialize
SerializableOptions options = new SerializableOptions();
options.Serializer = new NewtonsoftJsonObjectSerializer();
options.Serializers.Add(typeof(DogListProperty), new NewtonsoftJsonObjectSerializer());
string json = @"[{""LatinName"":""Animalia"",""Weight"":1.1,""Name"":""Doggo"",""IsHungry"":false,""FoodConsumed"":[""kibble"",""egg"",""peanut butter""],""NumberOfLegs"":4}]";

DogListProperty dog = ModelSerializer.Deserialize<DogListProperty>(json, options);
Expand All @@ -195,7 +195,7 @@ DogListProperty dog = new DogListProperty
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new ModelJsonConverter(false));

string json = JsonSerializer.Serialize(dog, options);
string json = System.Text.Json.JsonSerializer.Serialize(dog, options);
```

Deserialization
Expand All @@ -206,5 +206,41 @@ string json = @"[{""LatinName"":""Animalia"",""Weight"":1.1,""Name"":""Doggo"","
JsonSerializerOptions options = new JsonSerializerOptions();
options.Converters.Add(new ModelJsonConverter(false));

DogListProperty dog = JsonSerializer.Deserialize<DogListProperty>(json, options);
DogListProperty dog = System.Text.Json.JsonSerializer.Deserialize<DogListProperty>(json, options);
```

## Envelope BYOM Case
The following examples show a use case where a User brings a model unknown to the Serializer. The serialization used for each model can also be set in the SerializableOptions options property Serializers.

Model Being Used by User
private class ModelT
{
public string Name { get; set; }
public int Age { get; set; }
}

Serialization
```C# Snippet:BYOMWithNewtonsoftSerialize
Envelope<ModelT> envelope = new Envelope<ModelT>();
envelope.ModelA = new CatReadOnlyProperty();
envelope.ModelT = new ModelT { Name = "Fluffy", Age = 10 };

SerializableOptions options = new SerializableOptions();
options.Serializers.Add(typeof(ModelT), new NewtonsoftJsonObjectSerializer());

Stream stream = ModelSerializer.Serialize(envelope, options);
```

Deserialization
```C# Snippet:BYOMWithNewtonsoftDeserialize
string serviceResponse =
"{\"readOnlyProperty\":\"read\"," +
"\"modelA\":{\"name\":\"Cat\",\"isHungry\":false,\"weight\":2.5}," +
"\"modelT\":{\"Name\":\"hello\",\"Age\":1}" +
"}";

SerializableOptions options = new SerializableOptions();
options.Serializers.Add(typeof(ModelT), new NewtonsoftJsonObjectSerializer());

Envelope<ModelT> model = ModelSerializer.Deserialize<Envelope<ModelT>>(new MemoryStream(Encoding.UTF8.GetBytes(serviceResponse)), options: options);
```
48 changes: 31 additions & 17 deletions sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,18 @@ public static class ModelSerializer
/// <returns></returns>
public static Stream Serialize<T>(T model, SerializableOptions? options = default) where T : IJsonSerializable, new()
{
// if options.Serializer is set
if (options != null && options.Serializer != null)
// if options.Serializers is set and the model is in the dictionary, use the serializer
if (options != null)
{
System.BinaryData data = options.Serializer.Serialize(model);
return data.ToStream();
}
ObjectSerializer? serializer;

if (options.Serializers.TryGetValue(typeof(T), out serializer))
{
System.BinaryData data = serializer.Serialize(model);
return data.ToStream();
}
}
// else use default STJ serializer
IJsonSerializable serializable = (model ??= new T()) as IJsonSerializable;
Stream stream = new MemoryStream();
serializable.Serialize(stream, options);
Expand All @@ -42,13 +47,18 @@ public static class ModelSerializer
/// <returns></returns>
public static T Deserialize<T>(Stream stream, SerializableOptions? options = default) where T : IJsonSerializable, new()
{
if (options != null && options.Serializer != null)
if (options != null)
{
var obj = options.Serializer.Deserialize(stream, typeof(T), default);
if (obj is null)
throw new InvalidOperationException();
else
return (T)obj;
ObjectSerializer? serializer;

if (options.Serializers.TryGetValue(typeof(T), out serializer))
{
var obj = serializer.Deserialize(stream, typeof(T), default); //problem here T is Envelope<T> and typeof(T) is Envelope<T> but we want typeof(T) to be DogListProperty
if (obj is null)
throw new InvalidOperationException();
else
return (T)obj;
}
}

IJsonSerializable serializable = new T();
Expand All @@ -69,14 +79,18 @@ public static class ModelSerializer
using StreamWriter writer = new StreamWriter(stream);
writer.Write(json);
stream.Position = 0;
ObjectSerializer? serializer;

if (options != null && options.Serializer != null)
if (options != null)
{
var obj = options.Serializer.Deserialize(stream, typeof(T), default);
if (obj is null)
throw new InvalidOperationException();
else
return (T)obj;
if (options.Serializers.TryGetValue(typeof(T), out serializer))
{
var obj = serializer.Deserialize(stream, typeof(T), default);
if (obj is null)
throw new InvalidOperationException();
else
return (T)obj;
}
}

IJsonSerializable serializable = new T();
Expand Down
7 changes: 5 additions & 2 deletions sdk/core/Azure.Core/src/Serialization/SerializableOptions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;

namespace Azure.Core.Serialization
{
/// <summary>
Expand All @@ -24,8 +27,8 @@ public class SerializableOptions
public bool PrettyPrint { get; set; }

/// <summary>
/// todo
/// Dictionary that holds all the serializers for the different model types.
/// </summary>
public ObjectSerializer? Serializer { get; set; }
public Dictionary<Type, ObjectSerializer> Serializers { get; } = new Dictionary<Type, ObjectSerializer>();
}
}
Loading