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
21 changes: 21 additions & 0 deletions sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,11 @@ public static class ModelSerializer
/// <param name="options">The <see cref="ModelSerializerOptions"/> to use.</param>
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="options"/>.</returns>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerOptions.Format"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="model"/> is null.</exception>
public static BinaryData Serialize<T>(T model, ModelSerializerOptions? options = default) where T : IModelSerializable<T>
{
Argument.AssertNotNull(model, nameof(model));

options ??= ModelSerializerOptions.DefaultWireOptions;

return model.Serialize(options);
Expand All @@ -34,6 +37,7 @@ public static BinaryData Serialize<T>(T model, ModelSerializerOptions? options =
/// <param name="format">The <see cref="ModelSerializerFormat"/> to use.</param>
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="format"/>.</returns>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerFormat"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="model"/> is null.</exception>
public static BinaryData Serialize<T>(T model, ModelSerializerFormat format)
where T : IModelSerializable<T>
=> Serialize<T>(model, ModelSerializerOptions.GetOptions(format));
Expand All @@ -46,8 +50,11 @@ public static BinaryData Serialize<T>(T model, ModelSerializerFormat format)
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="options"/>.</returns>
/// <exception cref="InvalidOperationException">Throws if <paramref name="model"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerOptions.Format"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="model"/> is null.</exception>
public static BinaryData Serialize(object model, ModelSerializerOptions? options = default)
{
Argument.AssertNotNull(model, nameof(model));

options ??= ModelSerializerOptions.DefaultWireOptions;

var iModel = model as IModelSerializable<object>;
Expand All @@ -67,6 +74,7 @@ public static BinaryData Serialize(object model, ModelSerializerOptions? options
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="format"/>.</returns>
/// <exception cref="InvalidOperationException">Throws if <paramref name="model"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerFormat"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="model"/> is null.</exception>
public static BinaryData Serialize(object model, ModelSerializerFormat format)
=> Serialize(model, ModelSerializerOptions.GetOptions(format));

Expand All @@ -78,8 +86,11 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format)
/// <returns>A <typeparamref name="T"/> representation of the <see cref="BinaryData"/>.</returns>
/// <exception cref="InvalidOperationException">Throws if <typeparamref name="T"/> does not have a public or internal parameterless constructor.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerOptions.Format"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="data"/> is null.</exception>
public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerOptions? options = default) where T : IModelSerializable<T>
{
Argument.AssertNotNull(data, nameof(data));

options ??= ModelSerializerOptions.DefaultWireOptions;

return GetInstance<T>().Deserialize(data, options);
Expand All @@ -93,6 +104,7 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format)
/// <returns>A <typeparamref name="T"/> representation of the <see cref="BinaryData"/>.</returns>
/// <exception cref="InvalidOperationException">Throws if <typeparamref name="T"/> does not have a public or internal parameterless constructor.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerFormat"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="data"/> is null.</exception>
public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerFormat format)
where T : IModelSerializable<T>
=> Deserialize<T>(data, ModelSerializerOptions.GetOptions(format));
Expand All @@ -107,8 +119,12 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format)
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not have a public or internal parameterless constructor.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerOptions.Format"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="data"/> or <paramref name="returnType"/> are null.</exception>
public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type returnType, ModelSerializerOptions? options = default)
{
Argument.AssertNotNull(data, nameof(data));
Argument.AssertNotNull(returnType, nameof(returnType));

options ??= ModelSerializerOptions.DefaultWireOptions;

return GetInstance(returnType).Deserialize(data, options);
Expand All @@ -124,6 +140,7 @@ public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(Dy
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not implement <see cref="IModelSerializable{T}"/>.</exception>
/// <exception cref="InvalidOperationException">Throws if <paramref name="returnType"/> does not have a public or internal parameterless constructor.</exception>
/// <exception cref="FormatException">If the model does not support the requested <see cref="ModelSerializerFormat"/>.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="data"/> or <paramref name="returnType"/> are null.</exception>
public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type returnType, ModelSerializerFormat format)
=> Deserialize(data, returnType, ModelSerializerOptions.GetOptions(format));

Expand All @@ -133,8 +150,12 @@ public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(Dy
/// <param name="model">The model to convert.</param>
/// <param name="options">The <see cref="ModelSerializerOptions"/> to use.</param>
/// <returns>A <see cref="BinaryData"/> representation of the model in the <see cref="ModelSerializerFormat"/> specified by the <paramref name="options"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="model"/> or <paramref name="options"/> are null.</exception>
public static BinaryData SerializeCore(IModelJsonSerializable<object> model, ModelSerializerOptions options)
{
Argument.AssertNotNull(model, nameof(model));
Argument.AssertNotNull(options, nameof(options));

using ModelWriter writer = new ModelWriter(model, options);
return writer.ToBinaryData();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Azure.Core.Serialization

/// <summary>
/// Format used to serialize this model when sending as a request to an Azure service.
/// It will not serialize read-only properties or additional properties.
/// It may not serialize read-only properties or additional properties.
/// The content-type will vary between JSON, XML, etc., depending on the service.
///
/// Most use cases should prefer a more complete format like <see cref="ModelSerializerFormat.Json"/> that includes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,32 @@
using System;
using System.Text.Json;
using Azure.Core.Serialization;
using Azure.Core.Tests.ModelSerializationTests.Models;
using NUnit.Framework;

namespace Azure.Core.Tests.ModelSerialization
{
public class ModelSerializerTests
{
[Test]
public void ArgumentExceptions()
{
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize<BaseWithNoUnknown>(null));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize(null, typeof(BaseWithNoUnknown)));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize(new BinaryData(new byte[] { }), null));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Serialize<BaseWithNoUnknown>(null));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Serialize(null));

Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize<BaseWithNoUnknown>(null, ModelSerializerFormat.Wire));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize(null, typeof(BaseWithNoUnknown), ModelSerializerFormat.Wire));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Deserialize(new BinaryData(new byte[] { }), null, ModelSerializerFormat.Wire));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Serialize<BaseWithNoUnknown>(null, ModelSerializerFormat.Wire));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.Serialize(null, ModelSerializerFormat.Wire));

Assert.Throws<ArgumentNullException>(() => ModelSerializer.SerializeCore(null, new ModelSerializerOptions()));
Assert.Throws<ArgumentNullException>(() => ModelSerializer.SerializeCore(new ModelX(), null));
}

[Test]
public void ValidateErrorIfUnknownDoesntExist()
{
Expand Down