diff --git a/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs b/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs index 981522dd264c..2a057f420e42 100644 --- a/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs +++ b/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs @@ -19,8 +19,11 @@ public static class ModelSerializer /// The to use. /// A representation of the model in the specified by the . /// If the model does not support the requested . + /// If is null. public static BinaryData Serialize(T model, ModelSerializerOptions? options = default) where T : IModelSerializable { + Argument.AssertNotNull(model, nameof(model)); + options ??= ModelSerializerOptions.DefaultWireOptions; return model.Serialize(options); @@ -34,6 +37,7 @@ public static BinaryData Serialize(T model, ModelSerializerOptions? options = /// The to use. /// A representation of the model in the specified by the . /// If the model does not support the requested . + /// If is null. public static BinaryData Serialize(T model, ModelSerializerFormat format) where T : IModelSerializable => Serialize(model, ModelSerializerOptions.GetOptions(format)); @@ -46,8 +50,11 @@ public static BinaryData Serialize(T model, ModelSerializerFormat format) /// A representation of the model in the specified by the . /// Throws if does not implement . /// If the model does not support the requested . + /// If is null. public static BinaryData Serialize(object model, ModelSerializerOptions? options = default) { + Argument.AssertNotNull(model, nameof(model)); + options ??= ModelSerializerOptions.DefaultWireOptions; var iModel = model as IModelSerializable; @@ -67,6 +74,7 @@ public static BinaryData Serialize(object model, ModelSerializerOptions? options /// A representation of the model in the specified by the . /// Throws if does not implement . /// If the model does not support the requested . + /// If is null. public static BinaryData Serialize(object model, ModelSerializerFormat format) => Serialize(model, ModelSerializerOptions.GetOptions(format)); @@ -78,8 +86,11 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// A representation of the . /// Throws if does not have a public or internal parameterless constructor. /// If the model does not support the requested . + /// If is null. public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerOptions? options = default) where T : IModelSerializable { + Argument.AssertNotNull(data, nameof(data)); + options ??= ModelSerializerOptions.DefaultWireOptions; return GetInstance().Deserialize(data, options); @@ -93,6 +104,7 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// A representation of the . /// Throws if does not have a public or internal parameterless constructor. /// If the model does not support the requested . + /// If is null. public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerFormat format) where T : IModelSerializable => Deserialize(data, ModelSerializerOptions.GetOptions(format)); @@ -107,8 +119,12 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// Throws if does not implement . /// Throws if does not have a public or internal parameterless constructor. /// If the model does not support the requested . + /// If or are null. 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); @@ -124,6 +140,7 @@ public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(Dy /// Throws if does not implement . /// Throws if does not have a public or internal parameterless constructor. /// If the model does not support the requested . + /// If or are null. public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type returnType, ModelSerializerFormat format) => Deserialize(data, returnType, ModelSerializerOptions.GetOptions(format)); @@ -133,8 +150,12 @@ public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(Dy /// The model to convert. /// The to use. /// A representation of the model in the specified by the . + /// If or are null. public static BinaryData SerializeCore(IModelJsonSerializable model, ModelSerializerOptions options) { + Argument.AssertNotNull(model, nameof(model)); + Argument.AssertNotNull(options, nameof(options)); + using ModelWriter writer = new ModelWriter(model, options); return writer.ToBinaryData(); } diff --git a/sdk/core/Azure.Core/src/Serialization/ModelSerializerFormat.cs b/sdk/core/Azure.Core/src/Serialization/ModelSerializerFormat.cs index 56446aeb909f..7a4b8a7ce7f8 100644 --- a/sdk/core/Azure.Core/src/Serialization/ModelSerializerFormat.cs +++ b/sdk/core/Azure.Core/src/Serialization/ModelSerializerFormat.cs @@ -22,7 +22,7 @@ namespace Azure.Core.Serialization /// /// 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 that includes diff --git a/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializerTests.cs b/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializerTests.cs index bd6e713affb2..0225e20ec098 100644 --- a/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializerTests.cs +++ b/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializerTests.cs @@ -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(() => ModelSerializer.Deserialize(null)); + Assert.Throws(() => ModelSerializer.Deserialize(null, typeof(BaseWithNoUnknown))); + Assert.Throws(() => ModelSerializer.Deserialize(new BinaryData(new byte[] { }), null)); + Assert.Throws(() => ModelSerializer.Serialize(null)); + Assert.Throws(() => ModelSerializer.Serialize(null)); + + Assert.Throws(() => ModelSerializer.Deserialize(null, ModelSerializerFormat.Wire)); + Assert.Throws(() => ModelSerializer.Deserialize(null, typeof(BaseWithNoUnknown), ModelSerializerFormat.Wire)); + Assert.Throws(() => ModelSerializer.Deserialize(new BinaryData(new byte[] { }), null, ModelSerializerFormat.Wire)); + Assert.Throws(() => ModelSerializer.Serialize(null, ModelSerializerFormat.Wire)); + Assert.Throws(() => ModelSerializer.Serialize(null, ModelSerializerFormat.Wire)); + + Assert.Throws(() => ModelSerializer.SerializeCore(null, new ModelSerializerOptions())); + Assert.Throws(() => ModelSerializer.SerializeCore(new ModelX(), null)); + } + [Test] public void ValidateErrorIfUnknownDoesntExist() {