diff --git a/sdk/core/Azure.Core/perf/Serializations/ModelXmlModel.cs b/sdk/core/Azure.Core/perf/Serializations/ModelXmlModel.cs index 9ca689ce948a..c6beb83843b6 100644 --- a/sdk/core/Azure.Core/perf/Serializations/ModelXmlModel.cs +++ b/sdk/core/Azure.Core/perf/Serializations/ModelXmlModel.cs @@ -3,7 +3,7 @@ using System.Xml; using System.Xml.Linq; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; namespace Azure.Core.Perf.Serializations { diff --git a/sdk/core/Azure.Core/src/Serialization/IModelJsonSerializable.cs b/sdk/core/Azure.Core/src/Serialization/IModelJsonSerializable.cs index 9724527eb805..81a87ce56b00 100644 --- a/sdk/core/Azure.Core/src/Serialization/IModelJsonSerializable.cs +++ b/sdk/core/Azure.Core/src/Serialization/IModelJsonSerializable.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +using System; using System.Text.Json; namespace Azure.Core.Serialization @@ -16,6 +17,8 @@ public interface IModelJsonSerializable : IModelSerializable /// /// The to serialize into. /// The to use. + /// If the model does not support the requested . + /// If format is passed in and the model does not use JSON for its wire format. #pragma warning disable AZC0014 // Avoid using banned types in public API void Serialize(Utf8JsonWriter writer, ModelSerializerOptions options); #pragma warning restore AZC0014 // Avoid using banned types in public API @@ -26,6 +29,8 @@ public interface IModelJsonSerializable : IModelSerializable /// The to read. /// The to use. /// A representation of the JSON value. + /// If the model does not support the requested . + /// If format is passed in and the model does not use JSON for its wire format. #pragma warning disable AZC0014 // Avoid using banned types in public API T Deserialize(ref Utf8JsonReader reader, ModelSerializerOptions options); #pragma warning restore AZC0014 // Avoid using banned types in public API diff --git a/sdk/core/Azure.Core/src/Serialization/IModelSerializable.cs b/sdk/core/Azure.Core/src/Serialization/IModelSerializable.cs index e0107c075ce0..13723465f02e 100644 --- a/sdk/core/Azure.Core/src/Serialization/IModelSerializable.cs +++ b/sdk/core/Azure.Core/src/Serialization/IModelSerializable.cs @@ -17,7 +17,7 @@ public interface IModelSerializable /// /// The to use. /// A binary representation of the serialized model. - /// If the model does not support the requested . + /// If the model does not support the requested . BinaryData Serialize(ModelSerializerOptions options); /// @@ -26,7 +26,7 @@ public interface IModelSerializable /// The to parse. /// The to use. /// A representation of the data. - /// If the model does not support the requested . + /// If the model does not support the requested . T Deserialize(BinaryData data, ModelSerializerOptions options); } } diff --git a/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs b/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs index dbd10c3caae7..22fd21195dd3 100644 --- a/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs +++ b/sdk/core/Azure.Core/src/Serialization/ModelSerializer.cs @@ -18,6 +18,7 @@ public static class ModelSerializer /// The model to convert. /// The to use. /// A representation of the model in the specified by the + /// If the model does not support the requested . public static BinaryData Serialize(T model, ModelSerializerOptions? options = default) where T : IModelSerializable { options ??= ModelSerializerOptions.DefaultWireOptions; @@ -32,6 +33,7 @@ public static BinaryData Serialize(T model, ModelSerializerOptions? options = /// The model to convert. /// The to use. /// A representation of the model in the specified by the + /// If the model does not support the requested . public static BinaryData Serialize(T model, ModelSerializerFormat format) where T : IModelSerializable => Serialize(model, ModelSerializerOptions.GetOptions(format)); @@ -43,6 +45,7 @@ public static BinaryData Serialize(T model, ModelSerializerFormat format) /// The to use. /// A representation of the model in the specified by the /// Throws if does not implement . + /// If the model does not support the requested . public static BinaryData Serialize(object model, ModelSerializerOptions? options = default) { options ??= ModelSerializerOptions.DefaultWireOptions; @@ -63,6 +66,7 @@ public static BinaryData Serialize(object model, ModelSerializerOptions? options /// The to use. /// A representation of the model in the specified by the /// Throws if does not implement . + /// If the model does not support the requested . public static BinaryData Serialize(object model, ModelSerializerFormat format) => Serialize(model, ModelSerializerOptions.GetOptions(format)); @@ -72,7 +76,8 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// The to convert. /// The to use. /// A representation of the . - /// Throws if does not have a public or internal default constructor. + /// Throws if does not have a public or internal parameterless constructor. + /// If the model does not support the requested . public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerOptions? options = default) where T : IModelSerializable { options ??= ModelSerializerOptions.DefaultWireOptions; @@ -86,7 +91,8 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// The to convert. /// The to use. /// A representation of the . - /// Throws if does not have a public or internal default constructor. + /// Throws if does not have a public or internal parameterless constructor. + /// If the model does not support the requested . public static T Deserialize<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] T>(BinaryData data, ModelSerializerFormat format) where T : IModelSerializable => Deserialize(data, ModelSerializerOptions.GetOptions(format)); @@ -99,7 +105,8 @@ public static BinaryData Serialize(object model, ModelSerializerFormat format) /// The to use. /// A representation of the . /// Throws if does not implement . - /// Throws if does not have a public or internal default constructor. + /// Throws if does not have a public or internal parameterless constructor. + /// If the model does not support the requested . public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type returnType, ModelSerializerOptions? options = default) { options ??= ModelSerializerOptions.DefaultWireOptions; @@ -115,7 +122,8 @@ public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(Dy /// The to use. /// A representation of the . /// Throws if does not implement . - /// Throws if does not have a public or internal default constructor. + /// Throws if does not have a public or internal parameterless constructor. + /// If the model does not support the requested . public static object Deserialize(BinaryData data, [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type returnType, ModelSerializerFormat format) => Deserialize(data, returnType, ModelSerializerOptions.GetOptions(format)); diff --git a/sdk/core/Azure.Core/src/Serialization/ModelWriter.cs b/sdk/core/Azure.Core/src/Serialization/ModelWriter.cs index 9d899b25226e..b3721ffec506 100644 --- a/sdk/core/Azure.Core/src/Serialization/ModelWriter.cs +++ b/sdk/core/Azure.Core/src/Serialization/ModelWriter.cs @@ -35,6 +35,8 @@ public sealed partial class ModelWriter : IDisposable /// /// The model to serialize. /// The to use. + /// If the model does not support the requested . + /// If format is passed in and the model does not use JSON for its wire format. public ModelWriter(IModelJsonSerializable model, ModelSerializerOptions options) { _model = model; diff --git a/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializationContentTests.cs b/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializationContentTests.cs index 774ab89c6ecf..458fbdc875b6 100644 --- a/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializationContentTests.cs +++ b/sdk/core/Azure.Core/tests/ModelSerialization/ModelSerializationContentTests.cs @@ -3,7 +3,7 @@ using System; using Azure.Core.Serialization; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.ModelSerialization diff --git a/sdk/core/Azure.Core/tests/ModelSerialization/ModelWriterTests.cs b/sdk/core/Azure.Core/tests/ModelSerialization/ModelWriterTests.cs index f67685b90a83..0456af241f5c 100644 --- a/sdk/core/Azure.Core/tests/ModelSerialization/ModelWriterTests.cs +++ b/sdk/core/Azure.Core/tests/ModelSerialization/ModelWriterTests.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using Azure.Core.Serialization; using Azure.Core.Tests.Common; +using Azure.Core.Tests.ModelSerializationTests.Models; using Azure.Core.Tests.ResourceManager.Resources; using NUnit.Framework; @@ -24,6 +25,22 @@ public class ModelWriterTests private static readonly string _json = File.ReadAllText(TestData.GetLocation("ResourceProviderData.json")); private static readonly ResourceProviderData _resourceProviderData = ModelSerializer.Deserialize(BinaryData.FromString(_json)); + [Test] + public void ThrowsIfUnsupportedFormat() + { + ModelXml model = ModelSerializer.Deserialize(BinaryData.FromString(File.ReadAllText(TestData.GetLocation("ModelXml.xml")))); + ModelWriter writer = new ModelWriter(model, new ModelSerializerOptions("x")); + Assert.Throws(() => writer.ToBinaryData()); + } + + [Test] + public void ThrowsIfMismatch() + { + ModelXml model = ModelSerializer.Deserialize(BinaryData.FromString(File.ReadAllText(TestData.GetLocation("ModelXml.xml")))); + ModelWriter writer = new ModelWriter(model, ModelSerializerOptions.DefaultWireOptions); + Assert.Throws(() => writer.ToBinaryData()); + } + [Test] public async Task HappyPath() { diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ChildModelXml.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ChildModelXml.cs similarity index 98% rename from sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ChildModelXml.cs rename to sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ChildModelXml.cs index fda8cb0d209b..fb844e1ff160 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ChildModelXml.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ChildModelXml.cs @@ -10,7 +10,7 @@ using System.Xml.Serialization; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { [XmlRoot("ChildTag")] public class ChildModelXml : IXmlSerializable, IModelSerializable, IModelJsonSerializable, IUtf8JsonSerializable diff --git a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/BaseModel.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/BaseModel.cs index 3f352db2e00c..c1f2be750b29 100644 --- a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/BaseModel.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/BaseModel.cs @@ -6,7 +6,7 @@ using System.Text.Json; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { [UnknownSubclass(typeof(UnknownBaseModel))] public abstract class BaseModel : IUtf8JsonSerializable, IModelJsonSerializable diff --git a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelX.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelX.cs index 90357a754ffb..eff0102b1088 100644 --- a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelX.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelX.cs @@ -6,7 +6,7 @@ using System.Text.Json; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { public class ModelX : BaseModel, IUtf8JsonSerializable, IModelJsonSerializable { diff --git a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelY.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelY.cs index 8c08f7805f98..4930f369f4d9 100644 --- a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelY.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/ModelY.cs @@ -6,7 +6,7 @@ using System.Text.Json; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { public class ModelY : BaseModel, IUtf8JsonSerializable, IModelJsonSerializable { diff --git a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/UnknownBaseModel.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/UnknownBaseModel.cs index f9acf226839c..cf6b8c65ada5 100644 --- a/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/UnknownBaseModel.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/DiscriminatorSet/UnknownBaseModel.cs @@ -6,7 +6,7 @@ using System.Text.Json; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { internal class UnknownBaseModel : BaseModel, IUtf8JsonSerializable, IModelJsonSerializable { diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXml.cs b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ModelXml.cs similarity index 99% rename from sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXml.cs rename to sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ModelXml.cs index f5d840643a87..db52385a1929 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXml.cs +++ b/sdk/core/Azure.Core/tests/common/ModelSerializationTests/Models/ModelXml.cs @@ -10,7 +10,7 @@ using System.Xml.Serialization; using Azure.Core.Serialization; -namespace Azure.Core.Tests.Public.ModelSerializationTests.Models +namespace Azure.Core.Tests.ModelSerializationTests.Models { [XmlRoot("Tag")] public class ModelXml : IXmlSerializable, IModelSerializable, IModelJsonSerializable, IUtf8JsonSerializable diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/BaseModelTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/BaseModelTests.cs index 969c44906c6d..c01f977fa351 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/BaseModelTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/BaseModelTests.cs @@ -4,7 +4,7 @@ using System; using System.Linq; using Azure.Core.Serialization; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.Public.ModelSerializationTests diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelTests.cs index e0c9ebbff156..a1f33d555f96 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelTests.cs @@ -214,6 +214,26 @@ public void ThrowsIfUnknownFormat() } } + [Test] + public void ThrowsIfWireIsNotJson() + { + if (ModelInstance is IModelJsonSerializable jsonModel && IsXmlWireFormat) + { + Assert.Throws(() => jsonModel.Serialize(new Utf8JsonWriter(new MemoryStream()), new ModelSerializerOptions(ModelSerializerFormat.Wire))); + Utf8JsonReader reader = new Utf8JsonReader(new byte[] { }); + bool exceptionCaught = false; + try + { + jsonModel.Deserialize(ref reader, new ModelSerializerOptions(ModelSerializerFormat.Wire)); + } + catch (InvalidOperationException) + { + exceptionCaught = true; + } + Assert.IsTrue(exceptionCaught, "Expected InvalidOperationException to be thrown when deserializing wire format as json"); + } + } + [Test] public void CastNull() { diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXTests.cs index 007a3cb62c68..6a1ffad7a7db 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXTests.cs @@ -2,12 +2,8 @@ // Licensed under the MIT License. using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Azure.Core.Serialization; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.Public.ModelSerializationTests diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlCrossLibraryTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlCrossLibraryTests.cs index 0d69e2b6d4bd..a7d22d92f471 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlCrossLibraryTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlCrossLibraryTests.cs @@ -55,9 +55,8 @@ protected override string GetExpectedResult(ModelSerializerFormat format) if (format.Equals(ModelSerializerFormat.Json)) expectedSerializedString += ",\"readOnlyProperty\":\"ReadOnly\""; expectedSerializedString += ",\"childTag\":{\"childValue\":\"ChildRed\""; - //TODO this is broken until we update the IXmlSerializable interface to include ModelSerializerOptions - //if (format.Equals(ModelSerializerFormat.Json)) - // expectedSerializedString += ",\"childReadOnlyProperty\":\"ChildReadOnly\""; + if (format.Equals(ModelSerializerFormat.Json)) + expectedSerializedString += ",\"childReadOnlyProperty\":\"ChildReadOnly\""; expectedSerializedString += "}}"; return expectedSerializedString; } diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlTests.cs index 23f2d31c05e1..6889f5071a63 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/ModelXmlTests.cs @@ -8,7 +8,7 @@ using System.Xml; using Azure.Core.Serialization; using Azure.Core.Tests.Common; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.Public.ModelSerializationTests diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXmlCrossLibrary.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXmlCrossLibrary.cs index 67d3c5854b33..2c5bd935ba71 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXmlCrossLibrary.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/Models/ModelXmlCrossLibrary.cs @@ -10,6 +10,7 @@ using System.Xml.Linq; using System.Xml.Serialization; using Azure.Core.Serialization; +using Azure.Core.Tests.ModelSerializationTests.Models; namespace Azure.Core.Tests.Public.ModelSerializationTests.Models { @@ -105,7 +106,7 @@ private void Serialize(Utf8JsonWriter writer, ModelSerializerOptions options) writer.WriteStringValue(ReadOnlyProperty); } writer.WritePropertyName("childTag"u8); - writer.WriteObjectValue(ChildModelXml); + ((IModelJsonSerializable)ChildModelXml).Serialize(writer, options); writer.WriteEndObject(); } @@ -187,7 +188,7 @@ internal static ModelXmlCrossLibrary DeserializeModelXmlCrossLibrary(JsonElement } if (property.NameEquals("childTag"u8)) { - childModelXml = ChildModelXml.DeserializeChildModelXml(property.Value, options); + childModelXml = ModelSerializer.Deserialize(BinaryData.FromString(property.Value.GetRawText()), options);// ChildModelXml.DeserializeChildModelXml(property.Value, options); continue; } } diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UnknownBaseModelTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UnknownBaseModelTests.cs index 8b0ae4378c0b..3aa836b63a75 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UnknownBaseModelTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UnknownBaseModelTests.cs @@ -4,7 +4,7 @@ using System; using System.Linq; using Azure.Core.Serialization; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.Public.ModelSerializationTests diff --git a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UsingJsonSerializerTests.cs b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UsingJsonSerializerTests.cs index 918b14bc66d3..4d1a05616025 100644 --- a/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UsingJsonSerializerTests.cs +++ b/sdk/core/Azure.Core/tests/public/ModelSerializationTests/UsingJsonSerializerTests.cs @@ -3,7 +3,7 @@ using System.Text.Json; using Azure.Core.Serialization; -using Azure.Core.Tests.Public.ModelSerializationTests.Models; +using Azure.Core.Tests.ModelSerializationTests.Models; using NUnit.Framework; namespace Azure.Core.Tests.Public.ModelSerializationTests