diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs
index acbd82d2f33..9e380357e68 100644
--- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/SampleTypeSpecContext.cs
@@ -30,6 +30,9 @@ namespace SampleTypeSpec
[ModelReaderWriterBuildable(typeof(Thing))]
[ModelReaderWriterBuildable(typeof(UnknownAnimal))]
[ModelReaderWriterBuildable(typeof(UnknownPet))]
+ [ModelReaderWriterBuildable(typeof(XmlAdvancedModel))]
+ [ModelReaderWriterBuildable(typeof(XmlItem))]
+ [ModelReaderWriterBuildable(typeof(XmlNestedModel))]
public partial class SampleTypeSpecContext : ModelReaderWriterContext
{
}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.Serialization.cs
new file mode 100644
index 00000000000..21a8c34ce20
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.Serialization.cs
@@ -0,0 +1,483 @@
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace SampleTypeSpec
+{
+ /// An advanced XML model for testing various property types and XML features.
+ public partial class XmlAdvancedModel : IJsonModel
+ {
+ /// Initializes a new instance of for deserialization.
+ internal XmlAdvancedModel()
+ {
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlAdvancedModel)} does not support writing '{format}' format.");
+ }
+ writer.WritePropertyName("name"u8);
+ writer.WriteStringValue(Name);
+ writer.WritePropertyName("age"u8);
+ writer.WriteNumberValue(Age);
+ writer.WritePropertyName("enabled"u8);
+ writer.WriteBooleanValue(Enabled);
+ writer.WritePropertyName("score"u8);
+ writer.WriteNumberValue(Score);
+ if (Optional.IsDefined(OptionalString))
+ {
+ writer.WritePropertyName("optionalString"u8);
+ writer.WriteStringValue(OptionalString);
+ }
+ if (Optional.IsDefined(OptionalInt))
+ {
+ writer.WritePropertyName("optionalInt"u8);
+ writer.WriteNumberValue(OptionalInt.Value);
+ }
+ if (Optional.IsDefined(NullableString))
+ {
+ writer.WritePropertyName("nullableString"u8);
+ writer.WriteStringValue(NullableString);
+ }
+ else
+ {
+ writer.WriteNull("nullableString"u8);
+ }
+ writer.WritePropertyName("id"u8);
+ writer.WriteStringValue(Id);
+ writer.WritePropertyName("version"u8);
+ writer.WriteNumberValue(Version);
+ writer.WritePropertyName("isActive"u8);
+ writer.WriteBooleanValue(IsActive);
+ writer.WritePropertyName("RenamedProperty"u8);
+ writer.WriteStringValue(OriginalName);
+ writer.WritePropertyName("xml-id"u8);
+ writer.WriteStringValue(XmlIdentifier);
+ writer.WritePropertyName("content"u8);
+ writer.WriteStringValue(Content);
+ writer.WritePropertyName("unwrappedStrings"u8);
+ writer.WriteStartArray();
+ foreach (string item in UnwrappedStrings)
+ {
+ if (item == null)
+ {
+ writer.WriteNullValue();
+ continue;
+ }
+ writer.WriteStringValue(item);
+ }
+ writer.WriteEndArray();
+ writer.WritePropertyName("unwrappedCounts"u8);
+ writer.WriteStartArray();
+ foreach (int item in UnwrappedCounts)
+ {
+ writer.WriteNumberValue(item);
+ }
+ writer.WriteEndArray();
+ writer.WritePropertyName("unwrappedItems"u8);
+ writer.WriteStartArray();
+ foreach (XmlItem item in UnwrappedItems)
+ {
+ writer.WriteObjectValue(item, options);
+ }
+ writer.WriteEndArray();
+ writer.WritePropertyName("wrappedColors"u8);
+ writer.WriteStartArray();
+ foreach (string item in WrappedColors)
+ {
+ if (item == null)
+ {
+ writer.WriteNullValue();
+ continue;
+ }
+ writer.WriteStringValue(item);
+ }
+ writer.WriteEndArray();
+ writer.WritePropertyName("ItemCollection"u8);
+ writer.WriteStartArray();
+ foreach (XmlItem item in Items)
+ {
+ writer.WriteObjectValue(item, options);
+ }
+ writer.WriteEndArray();
+ writer.WritePropertyName("nestedModel"u8);
+ writer.WriteObjectValue(NestedModel, options);
+ if (Optional.IsDefined(OptionalNestedModel))
+ {
+ writer.WritePropertyName("optionalNestedModel"u8);
+ writer.WriteObjectValue(OptionalNestedModel, options);
+ }
+ writer.WritePropertyName("metadata"u8);
+ writer.WriteStartObject();
+ foreach (var item in Metadata)
+ {
+ writer.WritePropertyName(item.Key);
+ if (item.Value == null)
+ {
+ writer.WriteNullValue();
+ continue;
+ }
+ writer.WriteStringValue(item.Value);
+ }
+ writer.WriteEndObject();
+ writer.WritePropertyName("createdAt"u8);
+ writer.WriteStringValue(CreatedAt, "O");
+ writer.WritePropertyName("duration"u8);
+ writer.WriteStringValue(Duration, "P");
+ writer.WritePropertyName("data"u8);
+ writer.WriteBase64StringValue(Data.ToArray(), "D");
+ if (options.Format != "W" && _additionalBinaryDataProperties != null)
+ {
+ foreach (var item in _additionalBinaryDataProperties)
+ {
+ writer.WritePropertyName(item.Key);
+#if NET6_0_OR_GREATER
+ writer.WriteRawValue(item.Value);
+#else
+ using (JsonDocument document = JsonDocument.Parse(item.Value))
+ {
+ JsonSerializer.Serialize(writer, document.RootElement);
+ }
+#endif
+ }
+ }
+ }
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ XmlAdvancedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options);
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ protected virtual XmlAdvancedModel JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlAdvancedModel)} does not support reading '{format}' format.");
+ }
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeXmlAdvancedModel(document.RootElement, options);
+ }
+
+ /// The JSON element to deserialize.
+ /// The client options for reading and writing models.
+ internal static XmlAdvancedModel DeserializeXmlAdvancedModel(JsonElement element, ModelReaderWriterOptions options)
+ {
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string name = default;
+ int age = default;
+ bool enabled = default;
+ float score = default;
+ string optionalString = default;
+ int? optionalInt = default;
+ string nullableString = default;
+ string id = default;
+ int version = default;
+ bool isActive = default;
+ string originalName = default;
+ string xmlIdentifier = default;
+ string content = default;
+ IList unwrappedStrings = default;
+ IList unwrappedCounts = default;
+ IList unwrappedItems = default;
+ IList wrappedColors = default;
+ IList items = default;
+ XmlNestedModel nestedModel = default;
+ XmlNestedModel optionalNestedModel = default;
+ IDictionary metadata = default;
+ DateTimeOffset createdAt = default;
+ TimeSpan duration = default;
+ BinaryData data = default;
+ IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary();
+ foreach (var prop in element.EnumerateObject())
+ {
+ if (prop.NameEquals("name"u8))
+ {
+ name = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("age"u8))
+ {
+ age = prop.Value.GetInt32();
+ continue;
+ }
+ if (prop.NameEquals("enabled"u8))
+ {
+ enabled = prop.Value.GetBoolean();
+ continue;
+ }
+ if (prop.NameEquals("score"u8))
+ {
+ score = prop.Value.GetSingle();
+ continue;
+ }
+ if (prop.NameEquals("optionalString"u8))
+ {
+ optionalString = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("optionalInt"u8))
+ {
+ if (prop.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ optionalInt = prop.Value.GetInt32();
+ continue;
+ }
+ if (prop.NameEquals("nullableString"u8))
+ {
+ if (prop.Value.ValueKind == JsonValueKind.Null)
+ {
+ nullableString = null;
+ continue;
+ }
+ nullableString = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("id"u8))
+ {
+ id = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("version"u8))
+ {
+ version = prop.Value.GetInt32();
+ continue;
+ }
+ if (prop.NameEquals("isActive"u8))
+ {
+ isActive = prop.Value.GetBoolean();
+ continue;
+ }
+ if (prop.NameEquals("RenamedProperty"u8))
+ {
+ originalName = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("xml-id"u8))
+ {
+ xmlIdentifier = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("content"u8))
+ {
+ content = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("unwrappedStrings"u8))
+ {
+ List array = new List();
+ foreach (var item in prop.Value.EnumerateArray())
+ {
+ if (item.ValueKind == JsonValueKind.Null)
+ {
+ array.Add(null);
+ }
+ else
+ {
+ array.Add(item.GetString());
+ }
+ }
+ unwrappedStrings = array;
+ continue;
+ }
+ if (prop.NameEquals("unwrappedCounts"u8))
+ {
+ List array = new List();
+ foreach (var item in prop.Value.EnumerateArray())
+ {
+ array.Add(item.GetInt32());
+ }
+ unwrappedCounts = array;
+ continue;
+ }
+ if (prop.NameEquals("unwrappedItems"u8))
+ {
+ List array = new List();
+ foreach (var item in prop.Value.EnumerateArray())
+ {
+ array.Add(XmlItem.DeserializeXmlItem(item, options));
+ }
+ unwrappedItems = array;
+ continue;
+ }
+ if (prop.NameEquals("wrappedColors"u8))
+ {
+ List array = new List();
+ foreach (var item in prop.Value.EnumerateArray())
+ {
+ if (item.ValueKind == JsonValueKind.Null)
+ {
+ array.Add(null);
+ }
+ else
+ {
+ array.Add(item.GetString());
+ }
+ }
+ wrappedColors = array;
+ continue;
+ }
+ if (prop.NameEquals("ItemCollection"u8))
+ {
+ List array = new List();
+ foreach (var item in prop.Value.EnumerateArray())
+ {
+ array.Add(XmlItem.DeserializeXmlItem(item, options));
+ }
+ items = array;
+ continue;
+ }
+ if (prop.NameEquals("nestedModel"u8))
+ {
+ nestedModel = XmlNestedModel.DeserializeXmlNestedModel(prop.Value, options);
+ continue;
+ }
+ if (prop.NameEquals("optionalNestedModel"u8))
+ {
+ if (prop.Value.ValueKind == JsonValueKind.Null)
+ {
+ continue;
+ }
+ optionalNestedModel = XmlNestedModel.DeserializeXmlNestedModel(prop.Value, options);
+ continue;
+ }
+ if (prop.NameEquals("metadata"u8))
+ {
+ Dictionary dictionary = new Dictionary();
+ foreach (var prop0 in prop.Value.EnumerateObject())
+ {
+ if (prop0.Value.ValueKind == JsonValueKind.Null)
+ {
+ dictionary.Add(prop0.Name, null);
+ }
+ else
+ {
+ dictionary.Add(prop0.Name, prop0.Value.GetString());
+ }
+ }
+ metadata = dictionary;
+ continue;
+ }
+ if (prop.NameEquals("createdAt"u8))
+ {
+ createdAt = prop.Value.GetDateTimeOffset("O");
+ continue;
+ }
+ if (prop.NameEquals("duration"u8))
+ {
+ duration = prop.Value.GetTimeSpan("P");
+ continue;
+ }
+ if (prop.NameEquals("data"u8))
+ {
+ data = BinaryData.FromBytes(prop.Value.GetBytesFromBase64("D"));
+ continue;
+ }
+ if (options.Format != "W")
+ {
+ additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
+ }
+ }
+ return new XmlAdvancedModel(
+ name,
+ age,
+ enabled,
+ score,
+ optionalString,
+ optionalInt,
+ nullableString,
+ id,
+ version,
+ isActive,
+ originalName,
+ xmlIdentifier,
+ content,
+ unwrappedStrings,
+ unwrappedCounts,
+ unwrappedItems,
+ wrappedColors,
+ items,
+ nestedModel,
+ optionalNestedModel,
+ metadata,
+ createdAt,
+ duration,
+ data,
+ additionalBinaryDataProperties);
+ }
+
+ /// The client options for reading and writing models.
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
+
+ /// The client options for reading and writing models.
+ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default);
+ default:
+ throw new FormatException($"The model {nameof(XmlAdvancedModel)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ XmlAdvancedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual XmlAdvancedModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data))
+ {
+ return DeserializeXmlAdvancedModel(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(XmlAdvancedModel)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The client options for reading and writing models.
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+
+ /// The to deserialize the from.
+ public static explicit operator XmlAdvancedModel(ClientResult result)
+ {
+ using PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content);
+ return DeserializeXmlAdvancedModel(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.cs
new file mode 100644
index 00000000000..86357abb2b1
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlAdvancedModel.cs
@@ -0,0 +1,206 @@
+//
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace SampleTypeSpec
+{
+ /// An advanced XML model for testing various property types and XML features.
+ public partial class XmlAdvancedModel
+ {
+ /// Keeps track of any properties unknown to the library.
+ private protected readonly IDictionary _additionalBinaryDataProperties;
+
+ /// Initializes a new instance of .
+ /// A simple string property.
+ /// An integer property.
+ /// A boolean property.
+ /// A float property.
+ /// A nullable string.
+ /// A string as XML attribute.
+ /// An integer as XML attribute.
+ /// A boolean as XML attribute.
+ /// A property with a custom XML element name.
+ /// An attribute with a custom XML name.
+ /// Text content in the element (unwrapped string).
+ /// An unwrapped array of strings - items appear directly without wrapper.
+ /// An unwrapped array of integers.
+ /// An unwrapped array of models.
+ /// A wrapped array of strings (default).
+ /// A wrapped array with custom wrapper name.
+ /// A nested model property.
+ /// A dictionary property.
+ /// A date-time property.
+ /// A duration property.
+ /// A bytes property.
+ internal XmlAdvancedModel(string name, int age, bool enabled, float score, string nullableString, string id, int version, bool isActive, string originalName, string xmlIdentifier, string content, IEnumerable unwrappedStrings, IEnumerable unwrappedCounts, IEnumerable unwrappedItems, IEnumerable wrappedColors, IEnumerable items, XmlNestedModel nestedModel, IDictionary metadata, DateTimeOffset createdAt, TimeSpan duration, BinaryData data)
+ {
+ Name = name;
+ Age = age;
+ Enabled = enabled;
+ Score = score;
+ NullableString = nullableString;
+ Id = id;
+ Version = version;
+ IsActive = isActive;
+ OriginalName = originalName;
+ XmlIdentifier = xmlIdentifier;
+ Content = content;
+ UnwrappedStrings = unwrappedStrings.ToList();
+ UnwrappedCounts = unwrappedCounts.ToList();
+ UnwrappedItems = unwrappedItems.ToList();
+ WrappedColors = wrappedColors.ToList();
+ Items = items.ToList();
+ NestedModel = nestedModel;
+ Metadata = metadata;
+ CreatedAt = createdAt;
+ Duration = duration;
+ Data = data;
+ }
+
+ /// Initializes a new instance of .
+ /// A simple string property.
+ /// An integer property.
+ /// A boolean property.
+ /// A float property.
+ /// An optional string.
+ /// An optional integer.
+ /// A nullable string.
+ /// A string as XML attribute.
+ /// An integer as XML attribute.
+ /// A boolean as XML attribute.
+ /// A property with a custom XML element name.
+ /// An attribute with a custom XML name.
+ /// Text content in the element (unwrapped string).
+ /// An unwrapped array of strings - items appear directly without wrapper.
+ /// An unwrapped array of integers.
+ /// An unwrapped array of models.
+ /// A wrapped array of strings (default).
+ /// A wrapped array with custom wrapper name.
+ /// A nested model property.
+ /// An optional nested model.
+ /// A dictionary property.
+ /// A date-time property.
+ /// A duration property.
+ /// A bytes property.
+ /// Keeps track of any properties unknown to the library.
+ internal XmlAdvancedModel(string name, int age, bool enabled, float score, string optionalString, int? optionalInt, string nullableString, string id, int version, bool isActive, string originalName, string xmlIdentifier, string content, IList unwrappedStrings, IList unwrappedCounts, IList unwrappedItems, IList wrappedColors, IList items, XmlNestedModel nestedModel, XmlNestedModel optionalNestedModel, IDictionary metadata, DateTimeOffset createdAt, TimeSpan duration, BinaryData data, IDictionary additionalBinaryDataProperties)
+ {
+ Name = name;
+ Age = age;
+ Enabled = enabled;
+ Score = score;
+ OptionalString = optionalString;
+ OptionalInt = optionalInt;
+ NullableString = nullableString;
+ Id = id;
+ Version = version;
+ IsActive = isActive;
+ OriginalName = originalName;
+ XmlIdentifier = xmlIdentifier;
+ Content = content;
+ UnwrappedStrings = unwrappedStrings;
+ UnwrappedCounts = unwrappedCounts;
+ UnwrappedItems = unwrappedItems;
+ WrappedColors = wrappedColors;
+ Items = items;
+ NestedModel = nestedModel;
+ OptionalNestedModel = optionalNestedModel;
+ Metadata = metadata;
+ CreatedAt = createdAt;
+ Duration = duration;
+ Data = data;
+ _additionalBinaryDataProperties = additionalBinaryDataProperties;
+ }
+
+ /// A simple string property.
+ public string Name { get; }
+
+ /// An integer property.
+ public int Age { get; }
+
+ /// A boolean property.
+ public bool Enabled { get; }
+
+ /// A float property.
+ public float Score { get; }
+
+ /// An optional string.
+ public string OptionalString { get; }
+
+ /// An optional integer.
+ public int? OptionalInt { get; }
+
+ /// A nullable string.
+ public string NullableString { get; }
+
+ /// A string as XML attribute.
+ public string Id { get; }
+
+ /// An integer as XML attribute.
+ public int Version { get; }
+
+ /// A boolean as XML attribute.
+ public bool IsActive { get; }
+
+ /// A property with a custom XML element name.
+ public string OriginalName { get; }
+
+ /// An attribute with a custom XML name.
+ public string XmlIdentifier { get; }
+
+ /// Text content in the element (unwrapped string).
+ public string Content { get; }
+
+ /// An unwrapped array of strings - items appear directly without wrapper.
+ public IList UnwrappedStrings { get; }
+
+ /// An unwrapped array of integers.
+ public IList UnwrappedCounts { get; }
+
+ /// An unwrapped array of models.
+ public IList UnwrappedItems { get; }
+
+ /// A wrapped array of strings (default).
+ public IList WrappedColors { get; }
+
+ /// A wrapped array with custom wrapper name.
+ public IList Items { get; }
+
+ /// A nested model property.
+ public XmlNestedModel NestedModel { get; }
+
+ /// An optional nested model.
+ public XmlNestedModel OptionalNestedModel { get; }
+
+ /// A dictionary property.
+ public IDictionary Metadata { get; }
+
+ /// A date-time property.
+ public DateTimeOffset CreatedAt { get; }
+
+ /// A duration property.
+ public TimeSpan Duration { get; }
+
+ ///
+ /// A bytes property
+ ///
+ /// To assign a byte[] to this property use .
+ /// The byte[] will be serialized to a Base64 encoded string.
+ ///
+ ///
+ /// Examples:
+ ///
+ /// -
+ /// BinaryData.FromBytes(new byte[] { 1, 2, 3 }).
+ /// Creates a payload of "AQID".
+ ///
+ ///
+ ///
+ ///
+ public BinaryData Data { get; }
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.Serialization.cs
new file mode 100644
index 00000000000..4ff55dda314
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.Serialization.cs
@@ -0,0 +1,155 @@
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace SampleTypeSpec
+{
+ /// An item model for XML array testing.
+ public partial class XmlItem : IJsonModel
+ {
+ /// Initializes a new instance of for deserialization.
+ internal XmlItem()
+ {
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlItem)} does not support writing '{format}' format.");
+ }
+ writer.WritePropertyName("itemName"u8);
+ writer.WriteStringValue(ItemName);
+ writer.WritePropertyName("itemValue"u8);
+ writer.WriteNumberValue(ItemValue);
+ writer.WritePropertyName("itemId"u8);
+ writer.WriteStringValue(ItemId);
+ if (options.Format != "W" && _additionalBinaryDataProperties != null)
+ {
+ foreach (var item in _additionalBinaryDataProperties)
+ {
+ writer.WritePropertyName(item.Key);
+#if NET6_0_OR_GREATER
+ writer.WriteRawValue(item.Value);
+#else
+ using (JsonDocument document = JsonDocument.Parse(item.Value))
+ {
+ JsonSerializer.Serialize(writer, document.RootElement);
+ }
+#endif
+ }
+ }
+ }
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ XmlItem IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options);
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ protected virtual XmlItem JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlItem)} does not support reading '{format}' format.");
+ }
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeXmlItem(document.RootElement, options);
+ }
+
+ /// The JSON element to deserialize.
+ /// The client options for reading and writing models.
+ internal static XmlItem DeserializeXmlItem(JsonElement element, ModelReaderWriterOptions options)
+ {
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string itemName = default;
+ int itemValue = default;
+ string itemId = default;
+ IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary();
+ foreach (var prop in element.EnumerateObject())
+ {
+ if (prop.NameEquals("itemName"u8))
+ {
+ itemName = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("itemValue"u8))
+ {
+ itemValue = prop.Value.GetInt32();
+ continue;
+ }
+ if (prop.NameEquals("itemId"u8))
+ {
+ itemId = prop.Value.GetString();
+ continue;
+ }
+ if (options.Format != "W")
+ {
+ additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
+ }
+ }
+ return new XmlItem(itemName, itemValue, itemId, additionalBinaryDataProperties);
+ }
+
+ /// The client options for reading and writing models.
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
+
+ /// The client options for reading and writing models.
+ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default);
+ default:
+ throw new FormatException($"The model {nameof(XmlItem)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ XmlItem IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual XmlItem PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data))
+ {
+ return DeserializeXmlItem(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(XmlItem)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The client options for reading and writing models.
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.cs
new file mode 100644
index 00000000000..e291e9324a7
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlItem.cs
@@ -0,0 +1,49 @@
+//
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+
+namespace SampleTypeSpec
+{
+ /// An item model for XML array testing.
+ public partial class XmlItem
+ {
+ /// Keeps track of any properties unknown to the library.
+ private protected readonly IDictionary _additionalBinaryDataProperties;
+
+ /// Initializes a new instance of .
+ /// The item name.
+ /// The item value.
+ /// Item ID as attribute.
+ internal XmlItem(string itemName, int itemValue, string itemId)
+ {
+ ItemName = itemName;
+ ItemValue = itemValue;
+ ItemId = itemId;
+ }
+
+ /// Initializes a new instance of .
+ /// The item name.
+ /// The item value.
+ /// Item ID as attribute.
+ /// Keeps track of any properties unknown to the library.
+ internal XmlItem(string itemName, int itemValue, string itemId, IDictionary additionalBinaryDataProperties)
+ {
+ ItemName = itemName;
+ ItemValue = itemValue;
+ ItemId = itemId;
+ _additionalBinaryDataProperties = additionalBinaryDataProperties;
+ }
+
+ /// The item name.
+ public string ItemName { get; }
+
+ /// The item value.
+ public int ItemValue { get; }
+
+ /// Item ID as attribute.
+ public string ItemId { get; }
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.Serialization.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.Serialization.cs
new file mode 100644
index 00000000000..9f463bc25fb
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.Serialization.cs
@@ -0,0 +1,147 @@
+//
+
+#nullable disable
+
+using System;
+using System.ClientModel.Primitives;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace SampleTypeSpec
+{
+ /// A nested model for XML testing.
+ public partial class XmlNestedModel : IJsonModel
+ {
+ /// Initializes a new instance of for deserialization.
+ internal XmlNestedModel()
+ {
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ writer.WriteStartObject();
+ JsonModelWriteCore(writer, options);
+ writer.WriteEndObject();
+ }
+
+ /// The JSON writer.
+ /// The client options for reading and writing models.
+ protected virtual void JsonModelWriteCore(Utf8JsonWriter writer, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlNestedModel)} does not support writing '{format}' format.");
+ }
+ writer.WritePropertyName("value"u8);
+ writer.WriteStringValue(Value);
+ writer.WritePropertyName("nestedId"u8);
+ writer.WriteNumberValue(NestedId);
+ if (options.Format != "W" && _additionalBinaryDataProperties != null)
+ {
+ foreach (var item in _additionalBinaryDataProperties)
+ {
+ writer.WritePropertyName(item.Key);
+#if NET6_0_OR_GREATER
+ writer.WriteRawValue(item.Value);
+#else
+ using (JsonDocument document = JsonDocument.Parse(item.Value))
+ {
+ JsonSerializer.Serialize(writer, document.RootElement);
+ }
+#endif
+ }
+ }
+ }
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ XmlNestedModel IJsonModel.Create(ref Utf8JsonReader reader, ModelReaderWriterOptions options) => JsonModelCreateCore(ref reader, options);
+
+ /// The JSON reader.
+ /// The client options for reading and writing models.
+ protected virtual XmlNestedModel JsonModelCreateCore(ref Utf8JsonReader reader, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ if (format != "J")
+ {
+ throw new FormatException($"The model {nameof(XmlNestedModel)} does not support reading '{format}' format.");
+ }
+ using JsonDocument document = JsonDocument.ParseValue(ref reader);
+ return DeserializeXmlNestedModel(document.RootElement, options);
+ }
+
+ /// The JSON element to deserialize.
+ /// The client options for reading and writing models.
+ internal static XmlNestedModel DeserializeXmlNestedModel(JsonElement element, ModelReaderWriterOptions options)
+ {
+ if (element.ValueKind == JsonValueKind.Null)
+ {
+ return null;
+ }
+ string value = default;
+ int nestedId = default;
+ IDictionary additionalBinaryDataProperties = new ChangeTrackingDictionary();
+ foreach (var prop in element.EnumerateObject())
+ {
+ if (prop.NameEquals("value"u8))
+ {
+ value = prop.Value.GetString();
+ continue;
+ }
+ if (prop.NameEquals("nestedId"u8))
+ {
+ nestedId = prop.Value.GetInt32();
+ continue;
+ }
+ if (options.Format != "W")
+ {
+ additionalBinaryDataProperties.Add(prop.Name, BinaryData.FromString(prop.Value.GetRawText()));
+ }
+ }
+ return new XmlNestedModel(value, nestedId, additionalBinaryDataProperties);
+ }
+
+ /// The client options for reading and writing models.
+ BinaryData IPersistableModel.Write(ModelReaderWriterOptions options) => PersistableModelWriteCore(options);
+
+ /// The client options for reading and writing models.
+ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ return ModelReaderWriter.Write(this, options, SampleTypeSpecContext.Default);
+ default:
+ throw new FormatException($"The model {nameof(XmlNestedModel)} does not support writing '{options.Format}' format.");
+ }
+ }
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ XmlNestedModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
+
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual XmlNestedModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data))
+ {
+ return DeserializeXmlNestedModel(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(XmlNestedModel)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The client options for reading and writing models.
+ string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.cs
new file mode 100644
index 00000000000..ff4f7c80a97
--- /dev/null
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/Models/XmlNestedModel.cs
@@ -0,0 +1,42 @@
+//
+
+#nullable disable
+
+using System;
+using System.Collections.Generic;
+
+namespace SampleTypeSpec
+{
+ /// A nested model for XML testing.
+ public partial class XmlNestedModel
+ {
+ /// Keeps track of any properties unknown to the library.
+ private protected readonly IDictionary _additionalBinaryDataProperties;
+
+ /// Initializes a new instance of .
+ /// The value of the nested model.
+ /// An attribute on the nested model.
+ internal XmlNestedModel(string value, int nestedId)
+ {
+ Value = value;
+ NestedId = nestedId;
+ }
+
+ /// Initializes a new instance of .
+ /// The value of the nested model.
+ /// An attribute on the nested model.
+ /// Keeps track of any properties unknown to the library.
+ internal XmlNestedModel(string value, int nestedId, IDictionary additionalBinaryDataProperties)
+ {
+ Value = value;
+ NestedId = nestedId;
+ _additionalBinaryDataProperties = additionalBinaryDataProperties;
+ }
+
+ /// The value of the nested model.
+ public string Value { get; }
+
+ /// An attribute on the nested model.
+ public int NestedId { get; }
+ }
+}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.RestClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.RestClient.cs
index 6037a87bb26..8b916e68004 100644
--- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.RestClient.cs
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.RestClient.cs
@@ -403,5 +403,17 @@ internal PipelineMessage CreateDynamicModelOperationRequest(BinaryContent conten
message.Apply(options);
return message;
}
+
+ internal PipelineMessage CreateGetXmlAdvancedModelRequest(RequestOptions options)
+ {
+ ClientUriBuilder uri = new ClientUriBuilder();
+ uri.Reset(_endpoint);
+ uri.AppendPath("/xmlAdvanced", false);
+ PipelineMessage message = Pipeline.CreateMessage(uri.ToUri(), "GET", PipelineMessageClassifier200);
+ PipelineRequest request = message.Request;
+ request.Headers.Set("Accept", "application/xml");
+ message.Apply(options);
+ return message;
+ }
}
}
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs
index 3fe80eeac86..a93e481c5b5 100644
--- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecClient.cs
@@ -3033,6 +3033,110 @@ public virtual async Task DynamicModelOperationAsync(DynamicModel
}
}
+ ///
+ /// [Protocol Method] Get an advanced XML model with various property types
+ ///
+ /// -
+ /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios.
+ ///
+ ///
+ ///
+ /// The request options, which can override default behaviors of the client pipeline on a per-call basis.
+ /// Service returned a non-success status code.
+ /// The response returned from the service.
+ public virtual ClientResult GetXmlAdvancedModel(RequestOptions options)
+ {
+ try
+ {
+ System.Console.WriteLine("Entering method GetXmlAdvancedModel.");
+ using PipelineMessage message = CreateGetXmlAdvancedModelRequest(options);
+ return ClientResult.FromResponse(Pipeline.ProcessMessage(message, options));
+ }
+ catch (Exception ex)
+ {
+ System.Console.WriteLine($"An exception was thrown in method GetXmlAdvancedModel: {ex}");
+ throw;
+ }
+ finally
+ {
+ System.Console.WriteLine("Exiting method GetXmlAdvancedModel.");
+ }
+ }
+
+ ///
+ /// [Protocol Method] Get an advanced XML model with various property types
+ ///
+ /// -
+ /// This protocol method allows explicit creation of the request and processing of the response for advanced scenarios.
+ ///
+ ///
+ ///
+ /// The request options, which can override default behaviors of the client pipeline on a per-call basis.
+ /// Service returned a non-success status code.
+ /// The response returned from the service.
+ public virtual async Task GetXmlAdvancedModelAsync(RequestOptions options)
+ {
+ try
+ {
+ System.Console.WriteLine("Entering method GetXmlAdvancedModelAsync.");
+ using PipelineMessage message = CreateGetXmlAdvancedModelRequest(options);
+ return ClientResult.FromResponse(await Pipeline.ProcessMessageAsync(message, options).ConfigureAwait(false));
+ }
+ catch (Exception ex)
+ {
+ System.Console.WriteLine($"An exception was thrown in method GetXmlAdvancedModelAsync: {ex}");
+ throw;
+ }
+ finally
+ {
+ System.Console.WriteLine("Exiting method GetXmlAdvancedModelAsync.");
+ }
+ }
+
+ /// Get an advanced XML model with various property types.
+ /// The cancellation token that can be used to cancel the operation.
+ /// Service returned a non-success status code.
+ public virtual ClientResult GetXmlAdvancedModel(CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ System.Console.WriteLine("Entering method GetXmlAdvancedModel.");
+ ClientResult result = GetXmlAdvancedModel(cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null);
+ return ClientResult.FromValue((XmlAdvancedModel)result, result.GetRawResponse());
+ }
+ catch (Exception ex)
+ {
+ System.Console.WriteLine($"An exception was thrown in method GetXmlAdvancedModel: {ex}");
+ throw;
+ }
+ finally
+ {
+ System.Console.WriteLine("Exiting method GetXmlAdvancedModel.");
+ }
+ }
+
+ /// Get an advanced XML model with various property types.
+ /// The cancellation token that can be used to cancel the operation.
+ /// Service returned a non-success status code.
+ public virtual async Task> GetXmlAdvancedModelAsync(CancellationToken cancellationToken = default)
+ {
+ try
+ {
+ System.Console.WriteLine("Entering method GetXmlAdvancedModelAsync.");
+ ClientResult result = await GetXmlAdvancedModelAsync(cancellationToken.CanBeCanceled ? new RequestOptions { CancellationToken = cancellationToken } : null).ConfigureAwait(false);
+ return ClientResult.FromValue((XmlAdvancedModel)result, result.GetRawResponse());
+ }
+ catch (Exception ex)
+ {
+ System.Console.WriteLine($"An exception was thrown in method GetXmlAdvancedModelAsync: {ex}");
+ throw;
+ }
+ finally
+ {
+ System.Console.WriteLine("Exiting method GetXmlAdvancedModelAsync.");
+ }
+ }
+
/// Initializes a new instance of AnimalOperations.
public virtual AnimalOperations GetAnimalOperationsClient()
{
diff --git a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs
index ff9639bb364..ba951e61c45 100644
--- a/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs
+++ b/docs/samples/client/csharp/SampleService/SampleClient/src/Generated/SampleTypeSpecModelFactory.cs
@@ -240,6 +240,88 @@ public static AnotherDynamicModel AnotherDynamicModel(string bar = default)
return new AnotherDynamicModel(bar, additionalBinaryDataProperties: null);
}
+ /// An advanced XML model for testing various property types and XML features.
+ /// A simple string property.
+ /// An integer property.
+ /// A boolean property.
+ /// A float property.
+ /// An optional string.
+ /// An optional integer.
+ /// A nullable string.
+ /// A string as XML attribute.
+ /// An integer as XML attribute.
+ /// A boolean as XML attribute.
+ /// A property with a custom XML element name.
+ /// An attribute with a custom XML name.
+ /// Text content in the element (unwrapped string).
+ /// An unwrapped array of strings - items appear directly without wrapper.
+ /// An unwrapped array of integers.
+ /// An unwrapped array of models.
+ /// A wrapped array of strings (default).
+ /// A wrapped array with custom wrapper name.
+ /// A nested model property.
+ /// An optional nested model.
+ /// A dictionary property.
+ /// A date-time property.
+ /// A duration property.
+ /// A bytes property.
+ /// A new instance for mocking.
+ public static XmlAdvancedModel XmlAdvancedModel(string name = default, int age = default, bool enabled = default, float score = default, string optionalString = default, int? optionalInt = default, string nullableString = default, string id = default, int version = default, bool isActive = default, string originalName = default, string xmlIdentifier = default, string content = default, IEnumerable unwrappedStrings = default, IEnumerable unwrappedCounts = default, IEnumerable unwrappedItems = default, IEnumerable wrappedColors = default, IEnumerable items = default, XmlNestedModel nestedModel = default, XmlNestedModel optionalNestedModel = default, IDictionary metadata = default, DateTimeOffset createdAt = default, TimeSpan duration = default, BinaryData data = default)
+ {
+ unwrappedStrings ??= new ChangeTrackingList();
+ unwrappedCounts ??= new ChangeTrackingList();
+ unwrappedItems ??= new ChangeTrackingList();
+ wrappedColors ??= new ChangeTrackingList();
+ items ??= new ChangeTrackingList();
+ metadata ??= new ChangeTrackingDictionary();
+
+ return new XmlAdvancedModel(
+ name,
+ age,
+ enabled,
+ score,
+ optionalString,
+ optionalInt,
+ nullableString,
+ id,
+ version,
+ isActive,
+ originalName,
+ xmlIdentifier,
+ content,
+ unwrappedStrings.ToList(),
+ unwrappedCounts.ToList(),
+ unwrappedItems.ToList(),
+ wrappedColors.ToList(),
+ items.ToList(),
+ nestedModel,
+ optionalNestedModel,
+ metadata,
+ createdAt,
+ duration,
+ data,
+ additionalBinaryDataProperties: null);
+ }
+
+ /// An item model for XML array testing.
+ /// The item name.
+ /// The item value.
+ /// Item ID as attribute.
+ /// A new instance for mocking.
+ public static XmlItem XmlItem(string itemName = default, int itemValue = default, string itemId = default)
+ {
+ return new XmlItem(itemName, itemValue, itemId, additionalBinaryDataProperties: null);
+ }
+
+ /// A nested model for XML testing.
+ /// The value of the nested model.
+ /// An attribute on the nested model.
+ /// A new instance for mocking.
+ public static XmlNestedModel XmlNestedModel(string value = default, int nestedId = default)
+ {
+ return new XmlNestedModel(value, nestedId, additionalBinaryDataProperties: null);
+ }
+
///
/// Base animal with discriminator
/// Please note this is the abstract base class. The derived classes available for instantiation are: and .
diff --git a/docs/samples/client/csharp/SampleService/main.tsp b/docs/samples/client/csharp/SampleService/main.tsp
index e93467b99b1..f107f78d68e 100644
--- a/docs/samples/client/csharp/SampleService/main.tsp
+++ b/docs/samples/client/csharp/SampleService/main.tsp
@@ -1,5 +1,6 @@
import "@typespec/rest";
import "@typespec/http";
+import "@typespec/xml";
import "@typespec/http-client-csharp";
import "@azure-tools/typespec-client-generator-core";
import "@azure-tools/typespec-azure-core";
@@ -20,6 +21,7 @@ namespace SampleTypeSpec;
using TypeSpec.Http;
using TypeSpec.Versioning;
using TypeSpec.HttpClient.CSharp;
+using TypeSpec.Xml;
using Azure.ClientGenerator.Core;
alias SampleOAuth2 = OAuth2Auth<[
@@ -309,6 +311,118 @@ model AnotherDynamicModel {
bar: string;
}
+@doc("An advanced XML model for testing various property types and XML features.")
+@Xml.name("AdvancedXmlModel")
+model XmlAdvancedModel {
+ @doc("A simple string property")
+ name: string;
+
+ @doc("An integer property")
+ age: int32;
+
+ @doc("A boolean property")
+ enabled: boolean;
+
+ @doc("A float property")
+ score: float32;
+
+ @doc("An optional string")
+ optionalString?: string;
+
+ @doc("An optional integer")
+ optionalInt?: int32;
+
+ @doc("A nullable string")
+ nullableString: string | null;
+
+ @doc("A string as XML attribute")
+ @attribute
+ id: string;
+
+ @doc("An integer as XML attribute")
+ @attribute
+ version: int32;
+
+ @doc("A boolean as XML attribute")
+ @attribute
+ isActive: boolean;
+
+ @doc("A property with a custom XML element name")
+ @Xml.name("RenamedProperty")
+ originalName: string;
+
+ @doc("An attribute with a custom XML name")
+ @attribute
+ @Xml.name("xml-id")
+ xmlIdentifier: string;
+
+
+ @doc("Text content in the element (unwrapped string)")
+ @unwrapped
+ content: string;
+
+ @doc("An unwrapped array of strings - items appear directly without wrapper")
+ @unwrapped
+ unwrappedStrings: string[];
+
+ @doc("An unwrapped array of integers")
+ @unwrapped
+ unwrappedCounts: int32[];
+
+ @doc("An unwrapped array of models")
+ @unwrapped
+ unwrappedItems: XmlItem[];
+
+ @doc("A wrapped array of strings (default)")
+ wrappedColors: string[];
+
+ @doc("A wrapped array with custom wrapper name")
+ @Xml.name("ItemCollection")
+ items: XmlItem[];
+
+ @doc("A nested model property")
+ nestedModel: XmlNestedModel;
+
+ @doc("An optional nested model")
+ optionalNestedModel?: XmlNestedModel;
+
+ @doc("A dictionary property")
+ metadata: Record;
+
+ @doc("A date-time property")
+ createdAt: utcDateTime;
+
+ @doc("A duration property")
+ duration: duration;
+
+ @doc("A bytes property")
+ data: bytes;
+}
+
+@doc("A nested model for XML testing")
+model XmlNestedModel {
+ @doc("The value of the nested model")
+ value: string;
+
+ @doc("An attribute on the nested model")
+ @attribute
+ nestedId: int32;
+}
+
+@doc("An item model for XML array testing")
+@Xml.name("Item")
+model XmlItem {
+ @doc("The item name")
+ itemName: string;
+
+ @doc("The item value")
+ itemValue: int32;
+
+ @doc("Item ID as attribute")
+ @attribute
+ itemId: string;
+}
+
union DaysOfWeekExtensibleEnum {
string,
Monday: "Monday",
@@ -513,6 +627,14 @@ op EmbeddedParameters(@bodyRoot body: ModelWithEmbeddedNonBodyParameters): void;
@post
op DynamicModelOperation(@body body: DynamicModel): void;
+@route("xmlAdvanced")
+@doc("Get an advanced XML model with various property types")
+@get
+op GetXmlAdvancedModel(): {
+ @header contentType: "application/xml";
+ @body body: XmlAdvancedModel;
+};
+
@doc("Base animal with discriminator")
@discriminator("kind")
model Animal {
diff --git a/packages/http-client-csharp/eng/scripts/Spector-Helper.psm1 b/packages/http-client-csharp/eng/scripts/Spector-Helper.psm1
index eb11f366015..8340e859ebe 100644
--- a/packages/http-client-csharp/eng/scripts/Spector-Helper.psm1
+++ b/packages/http-client-csharp/eng/scripts/Spector-Helper.psm1
@@ -1,7 +1,7 @@
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..')
$failingSpecs = @(
- Join-Path 'http' 'payload' 'xml'
+ #Join-Path 'http' 'payload' 'xml'
Join-Path 'http' 'type' 'model' 'flatten'
Join-Path 'http' 'type' 'model' 'templated'
Join-Path 'http' 'client' 'naming' # pending until https://github.com/microsoft/typespec/issues/5653 is resolved
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Primitives/ScmKnownParameters.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Primitives/ScmKnownParameters.cs
index bfbefd24fbb..9ff28ed9363 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Primitives/ScmKnownParameters.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Primitives/ScmKnownParameters.cs
@@ -21,7 +21,6 @@ internal static class ScmKnownParameters
public static readonly ParameterProvider XmlWriter = new("writer", FormattableStringHelpers.Empty, typeof(XmlWriter));
public static readonly ParameterProvider NameHint = new("nameHint", FormattableStringHelpers.Empty, typeof(string));
- public static readonly ParameterProvider XElement = new("element", FormattableStringHelpers.Empty, typeof(XElement));
public static readonly ParameterProvider Utf8JsonWriter = new("writer", FormattableStringHelpers.Empty, typeof(Utf8JsonWriter));
public static readonly ParameterProvider Utf8JsonReader = new("reader", FormattableStringHelpers.Empty, typeof(Utf8JsonReader), isRef: true);
public static readonly ParameterProvider JsonOptions = new("options", FormattableStringHelpers.Empty, typeof(JsonSerializerOptions));
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensions.Xml.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensions.Xml.cs
new file mode 100644
index 00000000000..1e004e0e115
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensions.Xml.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Xml.Linq;
+using Microsoft.TypeSpec.Generator.ClientModel.Snippets;
+using Microsoft.TypeSpec.Generator.Expressions;
+using Microsoft.TypeSpec.Generator.Primitives;
+using Microsoft.TypeSpec.Generator.Providers;
+using Microsoft.TypeSpec.Generator.Snippets;
+using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
+
+namespace Microsoft.TypeSpec.Generator.ClientModel.Providers
+{
+ public sealed partial class ModelSerializationExtensionsDefinition
+ {
+ private readonly ParameterProvider _xElementParameter =
+ new ParameterProvider("element", FormattableStringHelpers.Empty, typeof(XElement));
+
+ private MethodProvider[] BuildXmlExtensionMethods()
+ {
+ if (!ScmCodeModelGenerator.Instance.InputLibrary.HasXmlModelSerialization)
+ {
+ return [];
+ }
+
+ return
+ [
+ BuildXmlGetDateTimeOffsetValueMethodProvider()
+ ];
+ }
+
+ private MethodProvider BuildXmlGetDateTimeOffsetValueMethodProvider()
+ {
+ var signature = new MethodSignature(
+ Name: _getDateTimeOffsetMethodName,
+ Modifiers: _methodModifiers,
+ Parameters: [_xElementParameter, _formatParameter],
+ ReturnType: typeof(DateTimeOffset),
+ Description: null,
+ ReturnDescription: null);
+
+ var element = _xElementParameter.As();
+ var body = new SwitchExpression(
+ _formatParameter,
+ new SwitchCaseExpression(Literal("U"), DateTimeOffsetSnippets.FromUnixTimeSeconds(element.CastTo(typeof(long)))),
+ SwitchCaseExpression.Default(TypeFormattersSnippets.ParseDateTimeOffset(element.Value(), _formatParameter)));
+
+ return new MethodProvider(signature, body, this, XmlDocProvider.Empty);
+ }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensionsDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensionsDefinition.cs
index 5a839f27088..2b1ecb328f4 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensionsDefinition.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/ModelSerializationExtensionsDefinition.cs
@@ -8,7 +8,6 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
@@ -23,7 +22,7 @@
namespace Microsoft.TypeSpec.Generator.ClientModel.Providers
{
- public sealed class ModelSerializationExtensionsDefinition : TypeProvider
+ public sealed partial class ModelSerializationExtensionsDefinition : TypeProvider
{
public const string WireOptionsFieldName = "WireOptions";
public const string JsonDocumentOptionsFieldName = "JsonDocumentOptions";
@@ -158,7 +157,8 @@ protected override MethodProvider[] BuildMethods()
BuildWriteObjectValueMethodGeneric(),
BuildWriteObjectValueMethodProvider(),
BuildGetUtf8BytesMethodProvider(),
- .. BuildDynamicModelHelpers()
+ .. BuildDynamicModelHelpers(),
+ .. BuildXmlExtensionMethods()
];
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Dynamic.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Dynamic.cs
index c62dfd0df8b..609019fa210 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Dynamic.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Dynamic.cs
@@ -503,14 +503,14 @@ private static string BuildJsonPathForElement(string propertySerializedName, Lis
private static ValueExpression GetDeserializationMethodInvocationForType(
ModelProvider model,
- ScopedApi jsonElementVariable,
+ ScopedApi element,
ValueExpression? dataVariable = null,
ValueExpression? optionsVariable = null)
{
optionsVariable ??= ModelSerializationExtensionsSnippets.Wire;
return model is ScmModelProvider { IsDynamicModel: true }
- ? model.Type.Deserialize(jsonElementVariable, dataVariable, optionsVariable)
- : model.Type.Deserialize(jsonElementVariable, null, optionsVariable);
+ ? model.Type.Deserialize(element, dataVariable, optionsVariable)
+ : model.Type.Deserialize(element, null, optionsVariable);
}
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Xml.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Xml.cs
new file mode 100644
index 00000000000..0fe3743b20d
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.Xml.cs
@@ -0,0 +1,448 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Linq;
+using Microsoft.TypeSpec.Generator.ClientModel.Snippets;
+using Microsoft.TypeSpec.Generator.Expressions;
+using Microsoft.TypeSpec.Generator.Primitives;
+using Microsoft.TypeSpec.Generator.Providers;
+using Microsoft.TypeSpec.Generator.Snippets;
+using Microsoft.TypeSpec.Generator.Statements;
+using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
+
+namespace Microsoft.TypeSpec.Generator.ClientModel.Providers
+{
+ public partial class MrwSerializationTypeDefinition
+ {
+ private readonly ParameterProvider _xElementDeserializationParam = new("element", $"The xml element to deserialize.", typeof(XElement));
+
+ ///
+ /// Represents a property that can be deserialized from XML, categorized by its serialization type.
+ ///
+ private record XmlPropertyInfo(
+ CSharpType PropertyType,
+ VariableExpression PropertyExpression,
+ XmlWireInformation XmlWireInfo);
+
+ ///
+ /// Categorized XML properties for deserialization.
+ ///
+ private record XmlPropertyCategories(
+ List? AttributeProperties,
+ List? ElementProperties,
+ XmlPropertyInfo? TextContentProperty);
+
+ internal MethodProvider BuildXmlDeserializationMethod()
+ {
+ var methodName = $"{DeserializationMethodNamePrefix}{_model.Name}";
+ var signatureModifiers = MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static;
+ var parameters = new List
+ {
+ _xElementDeserializationParam,
+ _serializationOptionsParameter,
+ };
+
+ return new MethodProvider(
+ new MethodSignature(methodName, null, signatureModifiers, _model.Type, null, parameters),
+ BuildXmlDeserializationMethodBody(),
+ this);
+ }
+
+ private MethodBodyStatement[] BuildXmlDeserializationMethodBody()
+ {
+ var elementParameter = _xElementDeserializationParam.As();
+ var valueKindEqualsNullReturn = _isStruct
+ ? Return(Default)
+ : Return(Null);
+
+ var categorizedProperties = CategorizeXmlProperties();
+ var statements = new List
+ {
+ new IfStatement(elementParameter.Equal(Null)) { valueKindEqualsNullReturn },
+ MethodBodyStatement.EmptyLine,
+ GetPropertyVariableDeclarations(),
+ MethodBodyStatement.EmptyLine
+ };
+
+ if (categorizedProperties.AttributeProperties?.Count > 0)
+ {
+ statements.Add(CreateXmlDeserializeForEachStatement(
+ elementParameter,
+ categorizedProperties.AttributeProperties,
+ isAttributes: true));
+ statements.Add(MethodBodyStatement.EmptyLine);
+ }
+
+ if (categorizedProperties.ElementProperties?.Count > 0)
+ {
+ statements.Add(CreateXmlDeserializeForEachStatement(
+ elementParameter,
+ categorizedProperties.ElementProperties,
+ isAttributes: false));
+ }
+
+ if (categorizedProperties.TextContentProperty != null)
+ {
+ statements.Add(categorizedProperties.TextContentProperty.PropertyExpression.Assign(elementParameter.Value()).Terminate());
+ statements.Add(MethodBodyStatement.EmptyLine);
+ }
+
+ statements.Add(Return(New.Instance(_model.Type, GetSerializationCtorParameterValues())));
+
+ return [.. statements];
+ }
+
+ private XmlPropertyCategories CategorizeXmlProperties()
+ {
+ List? attributeProperties = null;
+ List? elementProperties = null;
+ XmlPropertyInfo? textContentProperty = null;
+
+ var parameters = SerializationConstructor.Signature.Parameters;
+
+ for (int i = 0; i < parameters.Count; i++)
+ {
+ var parameter = parameters[i];
+ if (parameter.Property == null && parameter.Field == null)
+ {
+ continue;
+ }
+
+ var wireInfo = parameter.Property?.WireInfo ?? parameter.Field?.WireInfo;
+ var xmlWireInfo = wireInfo?.XmlWireInformation;
+ if (xmlWireInfo == null || wireInfo?.IsHttpMetadata == true)
+ {
+ continue;
+ }
+
+ var propertyType = parameter.Property?.Type ?? parameter.Field?.Type;
+ var propertyExpression = parameter.Property?.AsVariableExpression ?? parameter.Field?.AsVariableExpression;
+ if (propertyType == null || propertyExpression == null)
+ {
+ continue;
+ }
+
+ var propertyInfo = new XmlPropertyInfo(propertyType, propertyExpression, xmlWireInfo);
+
+ // Categorize by XML serialization type
+ if (xmlWireInfo.Attribute == true)
+ {
+ (attributeProperties ??= []).Add(propertyInfo);
+ continue;
+ }
+ if (xmlWireInfo.Unwrapped == true && !propertyType.IsCollection)
+ {
+ textContentProperty = propertyInfo;
+ continue;
+ }
+
+ (elementProperties ??= []).Add(propertyInfo);
+ }
+
+ return new XmlPropertyCategories(attributeProperties, elementProperties, textContentProperty);
+ }
+
+ private ForEachStatement CreateXmlDeserializeForEachStatement(
+ ScopedApi elementParameter,
+ List properties,
+ bool isAttributes)
+ {
+ return isAttributes switch
+ {
+ true => new ForEachStatement("attr", elementParameter.Attributes(), out var attr)
+ {
+ CreateXmlDeserializeAttributeStatements(attr.As(), properties)
+ },
+ false => new ForEachStatement("child", elementParameter.Elements(), out var child)
+ {
+ CreateXmlDeserializeElementStatements(child.As(), properties)
+ }
+ };
+ }
+
+ private MethodBodyStatement CreateXmlDeserializeElementStatements(
+ ScopedApi childElement,
+ List elementProperties)
+ {
+ var statements = new List();
+ var localNameVariable = new VariableExpression(typeof(string), "localName");
+
+ statements.Add(Declare(localNameVariable, childElement.GetLocalName()));
+
+ foreach (var prop in elementProperties)
+ {
+ var checkIfLocalNameEquals = new IfStatement(localNameVariable.Equal(Literal(prop.XmlWireInfo.Name)))
+ {
+ CreateXmlDeserializePropertyAssignment(childElement, prop.PropertyType, prop.PropertyExpression, prop.XmlWireInfo),
+ Continue
+ };
+
+ statements.Add(checkIfLocalNameEquals);
+ }
+
+ return statements;
+ }
+
+ private MethodBodyStatement CreateXmlDeserializePropertyAssignment(
+ ScopedApi childElement,
+ CSharpType propertyType,
+ VariableExpression propertyExpression,
+ XmlWireInformation xmlWireInfo)
+ {
+ if (propertyType.IsList || propertyType.IsArray)
+ {
+ return CreateXmlDeserializeListAssignment(childElement, propertyType, propertyExpression, xmlWireInfo);
+ }
+
+ if (propertyType.IsDictionary)
+ {
+ return CreateXmlDeserializeDictionaryAssignment(childElement, propertyType, propertyExpression, xmlWireInfo);
+ }
+
+ var deserializedValue = CreateXmlDeserializeValueExpression(childElement, propertyType);
+ return propertyExpression.Assign(deserializedValue).Terminate();
+ }
+
+ private MethodBodyStatement CreateXmlDeserializeListAssignment(
+ ScopedApi childElement,
+ CSharpType listType,
+ VariableExpression listExpression,
+ XmlWireInformation xmlWireInfo)
+ {
+ var elementType = listType.ElementType;
+ if (xmlWireInfo.Unwrapped == true)
+ {
+ return new MethodBodyStatements(
+ [
+ new IfStatement(listExpression.Equal(Null))
+ {
+ listExpression.Assign(New.Instance(listType.PropertyInitializationType)).Terminate(),
+ },
+ DeserializeXmlValue(childElement, elementType, out var itemValue),
+ listExpression.Invoke("Add", itemValue).Terminate()
+ ]);
+ }
+ else
+ {
+ var itemsName = xmlWireInfo.ItemsName;
+ var arrayDeclaration = Declare("array", New.List(listType.ElementType), out var listVariable);
+ var foreachStatement = ForEachStatement.Create("e", childElement.Elements(Literal(itemsName)), out ScopedApi item)
+ .Add(new MethodBodyStatement[]
+ {
+ DeserializeXmlValue(item, elementType, out var deserializedItem),
+ listVariable.Add(deserializedItem)
+ });
+
+ return new MethodBodyStatements(
+ [
+ arrayDeclaration,
+ foreachStatement,
+ listExpression.Assign(listVariable).Terminate()
+ ]);
+ }
+ }
+
+ private MethodBodyStatement CreateXmlDeserializeDictionaryAssignment(
+ ScopedApi childElement,
+ CSharpType dictionaryType,
+ VariableExpression dictionaryExpression,
+ XmlWireInformation xmlWireInfo)
+ {
+ var valueType = dictionaryType.ElementType;
+ if (xmlWireInfo.Unwrapped == true)
+ {
+ return new MethodBodyStatements(
+ [
+ new IfStatement(dictionaryExpression.Equal(Null))
+ {
+ dictionaryExpression.Assign(New.Dictionary(dictionaryType.Arguments[0], dictionaryType.Arguments[1])).Terminate(),
+ },
+ CreateXmlDeserializeDictionaryValueStatement(valueType, dictionaryExpression, childElement)
+ ]);
+ }
+
+ var dictionaryDeclaration = Declare(
+ "dictionary",
+ New.Dictionary(dictionaryType.Arguments[0], dictionaryType.Arguments[1]),
+ out var dictVariable);
+
+ var foreachStatement = ForEachStatement.Create("e", childElement.Elements(), out ScopedApi item)
+ .Add(new MethodBodyStatement[]
+ {
+ CreateXmlDeserializeDictionaryValueStatement(valueType, dictVariable, item)
+ });
+
+ return new MethodBodyStatements(
+ [
+ dictionaryDeclaration,
+ foreachStatement,
+ dictionaryExpression.Assign(dictVariable).Terminate()
+ ]);
+ }
+
+ private MethodBodyStatement CreateXmlDeserializeDictionaryValueStatement(
+ CSharpType valueType,
+ ValueExpression dictionary,
+ ScopedApi element)
+ {
+ return new MethodBodyStatement[]
+ {
+ DeserializeXmlValue(element, valueType, out var value),
+ dictionary.Invoke("Add", element.GetLocalName(), value).Terminate()
+ };
+ }
+
+ private MethodBodyStatement DeserializeXmlValue(
+ ScopedApi element,
+ CSharpType valueType,
+ out ValueExpression value)
+ {
+ if (valueType.IsList || valueType.IsArray)
+ {
+ var listDeclaration = Declare("list", New.List(valueType.ElementType), out var listVariable);
+ var foreachStatement = ForEachStatement.Create("item", element.Elements(), out ScopedApi item)
+ .Add(new MethodBodyStatement[]
+ {
+ DeserializeXmlValue(item, valueType.ElementType, out var deserializedItem),
+ listVariable.Add(deserializedItem)
+ });
+
+ value = listVariable;
+ return new MethodBodyStatement[] { listDeclaration, foreachStatement };
+ }
+
+ if (valueType.IsDictionary)
+ {
+ var dictDeclaration = Declare("dict", New.Dictionary(valueType.Arguments[0], valueType.Arguments[1]), out var dictVariable);
+ var foreachStatement = ForEachStatement.Create("item", element.Elements(), out ScopedApi item)
+ .Add(CreateXmlDeserializeDictionaryValueStatement(valueType.ElementType, dictVariable, item));
+
+ value = dictVariable;
+ return new MethodBodyStatement[] { dictDeclaration, foreachStatement };
+ }
+
+ value = CreateXmlDeserializeValueExpression(element, valueType);
+ return MethodBodyStatement.Empty;
+ }
+
+ private ValueExpression CreateXmlDeserializeValueExpression(ScopedApi element, CSharpType valueType)
+ {
+ var underlyingType = valueType.IsNullable && valueType.Arguments.Count > 0
+ ? valueType.Arguments[0]
+ : valueType;
+
+ if (underlyingType.IsEnum && underlyingType.UnderlyingEnumType != null)
+ {
+ var underlyingExpression = CreateXmlDeserializePrimitiveExpression(element, underlyingType.UnderlyingEnumType);
+ return underlyingType.ToEnum(underlyingExpression);
+ }
+
+ if (!underlyingType.IsFrameworkType)
+ {
+ return GetDeserializationMethodInvocationForType(underlyingType, element, null, _serializationOptionsParameter);
+ }
+
+ return CreateXmlDeserializePrimitiveExpression(element, valueType);
+ }
+
+ private static ValueExpression CreateXmlDeserializePrimitiveExpression(
+ ScopedApi element,
+ CSharpType valueType)
+ {
+ // TO-DO: Use serialization extensions if needed for special cases
+ return valueType.FrameworkType switch
+ {
+ Type t when t == typeof(byte) => element.CastTo(typeof(int)).CastTo(typeof(byte)),
+ Type t when t == typeof(sbyte) => element.CastTo(typeof(int)).CastTo(typeof(sbyte)),
+ Type t when t == typeof(short) => element.CastTo(typeof(int)).CastTo(typeof(short)),
+ Type t when t == typeof(ushort) => element.CastTo(typeof(int)).CastTo(typeof(ushort)),
+ Type t when t == typeof(byte[]) => Static(typeof(Convert)).Invoke(nameof(Convert.FromBase64String), [element.CastTo(typeof(string))]),
+ Type t when t == typeof(BinaryData) => New.Instance(typeof(BinaryData), Static(typeof(Convert)).Invoke(nameof(Convert.FromBase64String), [element.CastTo(typeof(string))])),
+ _ => element.CastTo(valueType)
+ };
+ }
+
+ private static MethodBodyStatement CreateXmlDeserializeAttributeStatements(
+ ScopedApi attrVariable,
+ List attributeProperties)
+ {
+ var statements = new List
+ {
+ Declare("localName", typeof(string), attrVariable.GetLocalName(), out var localNameVar)
+ };
+
+ foreach (var prop in attributeProperties)
+ {
+ var deserializedValue = attrVariable.CastTo(prop.PropertyType);
+ var checkIfLocalNameEquals = new IfStatement(localNameVar.Equal(Literal(prop.XmlWireInfo.Name)))
+ {
+ prop.PropertyExpression.Assign(deserializedValue).Terminate(),
+ Continue
+ };
+
+ statements.Add(checkIfLocalNameEquals);
+ }
+
+ return statements;
+ }
+
+ private SwitchCaseStatement CreatePersistableModelCreateCoreXmlSwitchCase(CSharpType typeForDeserialize)
+ {
+ return new SwitchCaseStatement(
+ ModelReaderWriterOptionsSnippets.XmlFormat,
+ new MethodBodyStatement[]
+ {
+ new UsingScopeStatement(typeof(Stream), "dataStream", _dataParameter.As().ToStream(), out var streamVar)
+ {
+ Return(GetDeserializationMethodInvocationForType(
+ typeForDeserialize,
+ XElementSnippets.Load(streamVar.As(), XmlLinqSnippets.PreserveWhitespace),
+ _dataParameter,
+ _serializationOptionsParameter))
+ },
+ });
+ }
+
+ private MethodProvider BuildXmlExplicitFromClientResult()
+ {
+ var result = new ParameterProvider(
+ ScmCodeModelGenerator.Instance.TypeFactory.ClientResponseApi.ResponseParameterName,
+ $"The {ScmCodeModelGenerator.Instance.TypeFactory.ClientResponseApi.ClientResponseType:C} to deserialize the {Type:C} from.",
+ ScmCodeModelGenerator.Instance.TypeFactory.ClientResponseApi.ClientResponseType);
+ var modifiers = MethodSignatureModifiers.Public | MethodSignatureModifiers.Static |
+ MethodSignatureModifiers.Explicit | MethodSignatureModifiers.Operator;
+
+ var response = result.ToApi();
+ MethodBodyStatement responseDeclaration;
+
+ if (response.Original == response.GetRawResponse().Original)
+ {
+ responseDeclaration = MethodBodyStatement.Empty;
+ }
+ else
+ {
+ responseDeclaration = UsingDeclare("response", ScmCodeModelGenerator.Instance.TypeFactory.HttpResponseApi.HttpResponseType, result.ToApi().GetRawResponse(), out var responseVar);
+ response = responseVar.ToApi();
+ }
+
+ MethodBodyStatement[] methodBody =
+ [
+ responseDeclaration,
+ UsingDeclare("stream", typeof(Stream), response.Property(nameof(HttpResponseApi.ContentStream)), out var streamVar),
+ new IfStatement(streamVar.Equal(Null)) { Return(Default) },
+ MethodBodyStatement.EmptyLine,
+ Return(GetDeserializationMethodInvocationForType(
+ _model,
+ XElementSnippets.Load(streamVar.As(), XmlLinqSnippets.PreserveWhitespace)))
+ ];
+
+ return new MethodProvider(
+ new MethodSignature(Type.Name, null, modifiers, Type, null, [result]),
+ methodBody,
+ this);
+ }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
index 4a36125f9e1..cded6c1d816 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Providers/MrwSerializationTypeDefinition.cs
@@ -34,6 +34,7 @@ public partial class MrwSerializationTypeDefinition : TypeProvider
private const string JsonModelCreateCoreMethodName = "JsonModelCreateCore";
private const string PersistableModelWriteCoreMethodName = "PersistableModelWriteCore";
private const string PersistableModelCreateCoreMethodName = "PersistableModelCreateCore";
+ private const string DeserializationMethodNamePrefix = "Deserialize";
private const string WriteAction = "writing";
private const string ReadAction = "reading";
private readonly ParameterProvider _utf8JsonWriterParameter = new("writer", $"The JSON writer.", typeof(Utf8JsonWriter));
@@ -57,6 +58,8 @@ public partial class MrwSerializationTypeDefinition : TypeProvider
private readonly Lazy _additionalBinaryDataProperty;
private readonly PropertyProvider? _jsonPatchProperty;
private readonly bool _isStruct;
+ private readonly bool _supportsJson;
+ private readonly bool _supportsXml;
private ConstructorProvider? _serializationConstructor;
// Flag to determine if the model should override the serialization methods
private readonly bool _shouldOverrideMethods;
@@ -73,6 +76,8 @@ public MrwSerializationTypeDefinition(InputModelType inputModel, ModelProvider m
: null;
_inputModel = inputModel;
_isStruct = _model.DeclarationModifiers.HasFlag(TypeSignatureModifiers.Struct);
+ _supportsJson = inputModel.Usage.HasFlag(InputModelTypeUsage.Json);
+ _supportsXml = inputModel.Usage.HasFlag(InputModelTypeUsage.Xml);
// Initialize the serialization interfaces
var interfaceType = inputModel.IsUnknownDiscriminatorModel ? ScmCodeModelGenerator.Instance.TypeFactory.CreateModel(inputModel.BaseModel!)! : _model;
_jsonModelTInterface = new CSharpType(typeof(IJsonModel<>), interfaceType.Type);
@@ -165,45 +170,63 @@ protected override ConstructorProvider[] BuildConstructors()
/// A list of serialization and deserialization methods for the model.
protected override MethodProvider[] BuildMethods()
{
- var jsonModelWriteCoreMethod = BuildJsonModelWriteCoreMethod();
- var methods = new List()
+ var methods = new List();
+
+ if (_supportsJson || _supportsXml)
{
- // Add JsonModel serialization methods
- BuildJsonModelWriteMethod(jsonModelWriteCoreMethod),
- jsonModelWriteCoreMethod,
+ // TO-DO: Add all persistable model methods when XML support is complete.
+ methods.Add(BuildPersistableModelCreateCoreMethod());
+ if (!_inputModel.IsUnknownDiscriminatorModel)
+ {
+ if (ScmCodeModelGenerator.Instance.TypeFactory.RootOutputModels.Contains(_inputModel))
+ {
+ methods.Add(GetExplicitFromClientResultMethod(_supportsXml));
+ }
+ }
+ }
+
+ // Add JsonModel serialization methods only if the model supports JSON
+ if (_supportsJson)
+ {
+ var jsonModelWriteCoreMethod = BuildJsonModelWriteCoreMethod();
+ methods.Add(BuildJsonModelWriteMethod(jsonModelWriteCoreMethod));
+ methods.Add(jsonModelWriteCoreMethod);
// Add JsonModel deserialization methods
- BuildJsonModelCreateMethod(),
- BuildJsonModelCreateCoreMethod(),
- BuildDeserializationMethod(),
+ methods.Add(BuildJsonModelCreateMethod());
+ methods.Add(BuildJsonModelCreateCoreMethod());
+ methods.Add(BuildDeserializationMethod());
// Add PersistableModel serialization methods
- BuildPersistableModelWriteMethod(),
- BuildPersistableModelWriteCoreMethod(),
- BuildPersistableModelCreateMethod(),
- BuildPersistableModelCreateCoreMethod(),
- BuildPersistableModelGetFormatFromOptionsMethod(),
- };
+ methods.Add(BuildPersistableModelWriteMethod());
+ methods.Add(BuildPersistableModelWriteCoreMethod());
+ methods.Add(BuildPersistableModelCreateMethod());
+ methods.Add(BuildPersistableModelGetFormatFromOptionsMethod());
- if (!_inputModel.IsUnknownDiscriminatorModel)
- {
- //cast operators
- if (ScmCodeModelGenerator.Instance.TypeFactory.RootInputModels.Contains(_inputModel))
+ if (!_inputModel.IsUnknownDiscriminatorModel)
{
- methods.Add(BuildImplicitToBinaryContent());
+ //cast operators
+ if (ScmCodeModelGenerator.Instance.TypeFactory.RootInputModels.Contains(_inputModel))
+ {
+ methods.Add(BuildImplicitToBinaryContent());
+ }
}
- if (ScmCodeModelGenerator.Instance.TypeFactory.RootOutputModels.Contains(_inputModel))
+ if (_isStruct)
{
- methods.Add(BuildExplicitFromClientResult());
+ methods.Add(BuildJsonModelWriteMethodObjectDeclaration());
+ methods.Add(BuildJsonModelCreateMethodObjectDeclaration());
+ methods.Add(BuildPersistableModelWriteMethodObjectDeclaration());
+ methods.Add(BuildPersistableModelGetFormatFromOptionsObjectDeclaration());
+ methods.Add(BuildPersistableModelCreateMethodObjectDeclaration());
}
}
- if (_isStruct)
+ if (_supportsXml)
{
- methods.Add(BuildJsonModelWriteMethodObjectDeclaration());
- methods.Add(BuildJsonModelCreateMethodObjectDeclaration());
- methods.Add(BuildPersistableModelWriteMethodObjectDeclaration());
- methods.Add(BuildPersistableModelGetFormatFromOptionsObjectDeclaration());
- methods.Add(BuildPersistableModelCreateMethodObjectDeclaration());
+ var xmlDeserializationMethod = BuildXmlDeserializationMethod();
+ if (xmlDeserializationMethod != null)
+ {
+ methods.Add(xmlDeserializationMethod);
+ }
}
if (_model is ScmModelProvider { IsDynamicModel: true, HasDynamicProperties: true })
@@ -214,6 +237,16 @@ protected override MethodProvider[] BuildMethods()
return [.. methods];
}
+ private MethodProvider GetExplicitFromClientResultMethod(bool supportsXml)
+ {
+ if (supportsXml)
+ {
+ return BuildXmlExplicitFromClientResult();
+ }
+
+ return BuildExplicitFromClientResult();
+ }
+
private MethodProvider BuildExplicitFromClientResult()
{
var result = new ParameterProvider(
@@ -287,16 +320,18 @@ private MethodProvider BuildImplicitToBinaryContent()
/// An array of types that the model implements.
protected override CSharpType[] BuildImplements()
{
- int interfaceCount = _jsonModelObjectInterface != null ? 2 : 1;
- CSharpType[] interfaces = new CSharpType[interfaceCount];
- interfaces[0] = _jsonModelTInterface;
+ var interfaces = new List();
- if (_jsonModelObjectInterface != null)
+ if (_supportsJson)
{
- interfaces[1] = _jsonModelObjectInterface;
+ interfaces.Add(_jsonModelTInterface);
+ if (_jsonModelObjectInterface != null)
+ {
+ interfaces.Add(_jsonModelObjectInterface);
+ }
}
- return interfaces;
+ return [.. interfaces];
}
///
@@ -507,7 +542,7 @@ internal MethodProvider BuildJsonModelCreateCoreMethod()
///
internal MethodProvider BuildDeserializationMethod()
{
- var methodName = $"Deserialize{_model.Name}";
+ var methodName = $"{DeserializationMethodNamePrefix}{_model.Name}";
var signatureModifiers = MethodSignatureModifiers.Internal | MethodSignatureModifiers.Static;
List parameters = _model is ScmModelProvider { IsDynamicModel: true }
? [_jsonElementDeserializationParam, _dataParameter, _serializationOptionsParameter]
@@ -838,19 +873,30 @@ private MethodBodyStatement[] BuildPersistableModelWriteCoreMethodBody()
private MethodBodyStatement[] BuildPersistableModelCreateCoreMethodBody()
{
var typeForDeserialize = _model.IsUnknownDiscriminatorModel ? _model.Type.BaseType! : _model.Type;
- var switchCase = new SwitchCaseStatement(
- ModelReaderWriterOptionsSnippets.JsonFormat,
- new MethodBodyStatement[]
- {
- new UsingScopeStatement(typeof(JsonDocument), "document", JsonDocumentSnippets.Parse(_dataParameter, ModelSerializationExtensionsSnippets.JsonDocumentOptions), out var jsonDocumentVar)
+ var switchCases = new List();
+
+ if (_supportsJson)
+ {
+ switchCases.Add(new SwitchCaseStatement(
+ ModelReaderWriterOptionsSnippets.JsonFormat,
+ new MethodBodyStatement[]
{
- Return(GetDeserializationMethodInvocationForType(
- typeForDeserialize,
- jsonDocumentVar.As().RootElement(),
- _dataParameter,
- _serializationOptionsParameter))
- },
- });
+ new UsingScopeStatement(typeof(JsonDocument), "document", JsonDocumentSnippets.Parse(_dataParameter, ModelSerializationExtensionsSnippets.JsonDocumentOptions), out var jsonDocumentVar)
+ {
+ Return(GetDeserializationMethodInvocationForType(
+ typeForDeserialize,
+ jsonDocumentVar.As().RootElement(),
+ _dataParameter,
+ _serializationOptionsParameter))
+ },
+ }));
+ }
+
+ if (_supportsXml)
+ {
+ switchCases.Add(CreatePersistableModelCreateCoreXmlSwitchCase(typeForDeserialize));
+ }
+
var typeOfT = _persistableModelTInterface.Arguments[0];
var defaultCase = SwitchCaseStatement.Default(
ThrowValidationFailException(_mrwOptionsParameterSnippet.Format(), typeOfT, ReadAction));
@@ -858,7 +904,7 @@ private MethodBodyStatement[] BuildPersistableModelCreateCoreMethodBody()
return
[
GetConcreteFormat(_mrwOptionsParameterSnippet, _persistableModelTInterface, out VariableExpression format),
- new SwitchStatement(format, [switchCase, defaultCase])
+ new SwitchStatement(format, [.. switchCases, defaultCase])
];
}
@@ -2254,14 +2300,14 @@ private static bool TypeRequiresNullCheckInSerialization(CSharpType type)
internal static ValueExpression GetDeserializationMethodInvocationForType(
CSharpType modelType,
- ScopedApi jsonElementVariable,
- ValueExpression dataVariable,
+ ScopedApi element,
+ ValueExpression? dataVariable,
ValueExpression? optionsVariable = null)
{
return ScmCodeModelGenerator.Instance.TypeFactory.CSharpTypeMap.TryGetValue(modelType, out var provider) &&
provider is ModelProvider modelProvider
- ? GetDeserializationMethodInvocationForType(modelProvider, jsonElementVariable, dataVariable, optionsVariable)
- : modelType.Deserialize(jsonElementVariable, null, optionsVariable);
+ ? GetDeserializationMethodInvocationForType(modelProvider, element, dataVariable, optionsVariable)
+ : modelType.Deserialize(element, null, optionsVariable);
}
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmCodeModelGenerator.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmCodeModelGenerator.cs
index 0d9f0b3a36e..4dfc7e0146a 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmCodeModelGenerator.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmCodeModelGenerator.cs
@@ -42,6 +42,7 @@ protected override void Configure()
AddMetadataReference(MetadataReference.CreateFromFile(typeof(ClientResult).Assembly.Location));
AddMetadataReference(MetadataReference.CreateFromFile(typeof(BinaryData).Assembly.Location));
AddMetadataReference(MetadataReference.CreateFromFile(typeof(JsonSerializer).Assembly.Location));
+
AddTypeToKeep(ModelReaderWriterContextDefinition.s_name, isRoot: false);
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmTypeFactory.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmTypeFactory.cs
index 73127364c4e..bd301b41e96 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmTypeFactory.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/ScmTypeFactory.cs
@@ -143,7 +143,7 @@ protected override IReadOnlyList CreateSerializationsCore(InputTyp
{
switch (inputType)
{
- case InputModelType inputModel when inputModel.Usage.HasFlag(InputModelTypeUsage.Json):
+ case InputModelType inputModel when (inputModel.Usage & (InputModelTypeUsage.Json | InputModelTypeUsage.Xml)) != 0:
if (typeProvider is ModelProvider modelProvider)
{
return [new MrwSerializationTypeDefinition(inputModel, modelProvider)];
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/ModelReaderWriterOptionsSnippets.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/ModelReaderWriterOptionsSnippets.cs
index 614719f2f29..f7b4ba31709 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/ModelReaderWriterOptionsSnippets.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/ModelReaderWriterOptionsSnippets.cs
@@ -14,6 +14,7 @@ internal static class ModelReaderWriterOptionsSnippets
public static ValueExpression Format(this ScopedApi mrwOptions) => mrwOptions.Property(nameof(ModelReaderWriterOptions.Format));
internal static ScopedApi WireFormat => Literal("W");
internal static ScopedApi JsonFormat => Literal("J");
+ internal static ScopedApi XmlFormat => Literal("X");
internal static ScopedApi InitializeWireOptions => New.Instance(typeof(ModelReaderWriterOptions), Wire).As();
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XElementSnippets.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XElementSnippets.cs
new file mode 100644
index 00000000000..8e7ecda2683
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XElementSnippets.cs
@@ -0,0 +1,42 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Collections.Generic;
+using System.Xml.Linq;
+using Microsoft.TypeSpec.Generator.Expressions;
+using Microsoft.TypeSpec.Generator.Snippets;
+using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
+
+namespace Microsoft.TypeSpec.Generator.ClientModel.Snippets
+{
+ ///
+ /// Provides extension methods for generating code that works with and .
+ ///
+ internal static class XElementSnippets
+ {
+ public static ScopedApi Name(this ScopedApi element)
+ => element.Property(nameof(XElement.Name)).As();
+ public static ScopedApi GetLocalName(this ScopedApi element)
+ => Name(element).Property(nameof(XName.LocalName)).As();
+
+ public static ScopedApi> Elements(this ScopedApi element)
+ => element.Invoke(nameof(XElement.Elements)).As>();
+
+ public static ScopedApi> Elements(this ScopedApi element, ValueExpression name)
+ => element.Invoke(nameof(XElement.Elements), name).As>();
+
+ public static ScopedApi Value(this ScopedApi element)
+ => element.Property(nameof(XElement.Value)).As();
+
+ public static ScopedApi> Attributes(this ScopedApi element)
+ => element.Invoke(nameof(XElement.Attributes)).As>();
+ public static ScopedApi Name(this ScopedApi attribute)
+ => attribute.Property(nameof(XAttribute.Name)).As();
+
+ public static ScopedApi GetLocalName(this ScopedApi attribute)
+ => Name(attribute).Property(nameof(XName.LocalName)).As();
+
+ public static ScopedApi Load(params ValueExpression[] args)
+ => Static().Invoke(nameof(XElement.Load), args).As();
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XmlLinqSnippets.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XmlLinqSnippets.cs
new file mode 100644
index 00000000000..fb783735891
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Snippets/XmlLinqSnippets.cs
@@ -0,0 +1,15 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Xml.Linq;
+using Microsoft.TypeSpec.Generator.Snippets;
+using static Microsoft.TypeSpec.Generator.Snippets.Snippet;
+
+namespace Microsoft.TypeSpec.Generator.ClientModel.Snippets
+{
+ public class XmlLinqSnippets
+ {
+ public static ScopedApi PreserveWhitespace
+ => Static().Property(nameof(LoadOptions.PreserveWhitespace)).As();
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs
new file mode 100644
index 00000000000..97e3d4c0ffe
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/test/Providers/MrwSerializationTypeDefinitions/XmlDeserializationTests.cs
@@ -0,0 +1,306 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.Linq;
+using System.Xml.Linq;
+using Microsoft.TypeSpec.Generator.ClientModel.Providers;
+using Microsoft.TypeSpec.Generator.Input;
+using Microsoft.TypeSpec.Generator.Primitives;
+using Microsoft.TypeSpec.Generator.Providers;
+using Microsoft.TypeSpec.Generator.Tests.Common;
+using NUnit.Framework;
+
+namespace Microsoft.TypeSpec.Generator.ClientModel.Tests.Providers.MrwSerializationTypeDefinitions
+{
+ public class XmlDeserializationTests
+ {
+ public XmlDeserializationTests()
+ {
+ MockHelpers.LoadMockGenerator(createSerializationsCore: (inputType, typeProvider)
+ => inputType is InputModelType modelType ? [new MrwSerializationTypeDefinition(modelType, (typeProvider as ModelProvider)!)] : []);
+ }
+
+ [Test]
+ public void XmlDeserializationMethodIsGeneratedForXmlModel()
+ {
+ // Arrange - create a model with XML usage
+ var inputModel = InputFactory.Model(
+ "TestXmlModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("Name", InputPrimitiveType.String)]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+
+ // Assert
+ Assert.IsNotNull(mrwProvider);
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestXmlModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+ Assert.IsNotNull(xmlDeserializationMethod, "XML deserialization method should be generated for models with XML usage");
+
+ // Verify method signature
+ Assert.AreEqual("DeserializeTestXmlModel", xmlDeserializationMethod!.Signature.Name);
+ Assert.AreEqual(2, xmlDeserializationMethod.Signature.Parameters.Count);
+ Assert.AreEqual(typeof(XElement), xmlDeserializationMethod.Signature.Parameters[0].Type.FrameworkType);
+ Assert.IsTrue(xmlDeserializationMethod.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Internal));
+ Assert.IsTrue(xmlDeserializationMethod.Signature.Modifiers.HasFlag(MethodSignatureModifiers.Static));
+ }
+
+ [Test]
+ public void XmlDeserializationMethodIsNotGeneratedForJsonOnlyModel()
+ {
+ // Arrange - create a model with only JSON usage (no XML)
+ var inputModel = InputFactory.Model(
+ "TestJsonModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Output | InputModelTypeUsage.Json,
+ properties: [InputFactory.Property("Name", InputPrimitiveType.String)]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+
+ // Assert
+ Assert.IsNotNull(mrwProvider);
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestJsonModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+ Assert.IsNull(xmlDeserializationMethod, "XML deserialization method should NOT be generated for JSON-only models");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodBodyContainsNullCheck()
+ {
+ // Arrange
+ var inputModel = InputFactory.Model(
+ "TestXmlModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("Name", InputPrimitiveType.String)]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestXmlModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+ Assert.IsTrue(methodBody.Contains("element == null") || methodBody.Contains("element is null"),
+ "Method should contain null check for element parameter");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodBodyContainsPropertyDeserialization()
+ {
+ // Arrange
+ var inputModel = InputFactory.Model(
+ "TestXmlModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("name", InputPrimitiveType.String, isRequired: true)]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestXmlModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+
+ // Should iterate over child elements
+ Assert.IsTrue(methodBody.Contains("foreach") && methodBody.Contains("Elements()"),
+ "Method should iterate over child elements");
+
+ // Should check for property names
+ Assert.IsTrue(methodBody.Contains("localName") || methodBody.Contains("LocalName"),
+ "Method should check element local names");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodReturnsNewInstance()
+ {
+ // Arrange
+ var inputModel = InputFactory.Model(
+ "TestXmlModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("Name", InputPrimitiveType.String)]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestXmlModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+ Assert.IsTrue(methodBody.Contains("return new") && methodBody.Contains("TestXmlModel"),
+ "Method should return a new instance of the model");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodHandlesMultipleProperties()
+ {
+ // Arrange
+ var inputModel = InputFactory.Model(
+ "TestXmlModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties:
+ [
+ InputFactory.Property("id", InputPrimitiveType.String, isRequired: true),
+ InputFactory.Property("name", InputPrimitiveType.String, isRequired: true),
+ InputFactory.Property("count", InputPrimitiveType.Int32)
+ ]);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeTestXmlModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+
+ // Should have checks for all properties
+ Assert.IsTrue(methodBody.Contains("\"id\""), "Method should check for 'id' property");
+ Assert.IsTrue(methodBody.Contains("\"name\""), "Method should check for 'name' property");
+ Assert.IsTrue(methodBody.Contains("\"count\""), "Method should check for 'count' property");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodHandlesNestedModel()
+ {
+ // Arrange
+ var innerModel = InputFactory.Model(
+ "InnerModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("value", InputPrimitiveType.String)]);
+
+ var outerModel = InputFactory.Model(
+ "OuterModel",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [InputFactory.Property("inner", innerModel)]);
+
+ MockHelpers.LoadMockGenerator(
+ inputModels: () => [innerModel, outerModel],
+ createSerializationsCore: (inputType, typeProvider)
+ => inputType is InputModelType modelType ? [new MrwSerializationTypeDefinition(modelType, (typeProvider as ModelProvider)!)] : []);
+
+ // Act
+ var modelProvider = new ModelProvider(outerModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeOuterModel" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+
+ // Should call deserialize on inner model
+ Assert.IsTrue(methodBody.Contains("DeserializeInnerModel"),
+ "Method should call DeserializeInnerModel for nested model property");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodHandlesUnwrappedListProperty()
+ {
+ // Arrange - create a model with an unwrapped list property (items are direct children)
+ var listProperty = new InputModelProperty(
+ name: "colors",
+ summary: null,
+ doc: "List of colors",
+ type: new InputArrayType("colors", "TypeSpec.Array", InputPrimitiveType.String),
+ isRequired: true,
+ isReadOnly: false,
+ isApiVersion: false,
+ defaultValue: null,
+ isHttpMetadata: false,
+ access: null,
+ isDiscriminator: false,
+ serializedName: "colors",
+ serializationOptions: new(
+ json: new("colors"),
+ xml: new("colors", unwrapped: true)));
+
+ var inputModel = InputFactory.Model(
+ "ModelWithUnwrappedList",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [listProperty]);
+
+ MockHelpers.LoadMockGenerator(createSerializationsCore: (inputType, typeProvider)
+ => inputType is InputModelType modelType ? [new MrwSerializationTypeDefinition(modelType, (typeProvider as ModelProvider)!)] : []);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeModelWithUnwrappedList" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+
+ // Unwrapped list should check for null and initialize if needed
+ Assert.IsTrue(methodBody.Contains("colors == null") || methodBody.Contains("colors is null"),
+ $"Unwrapped list should check for null before initializing. Actual:\n{methodBody}");
+
+ // Unwrapped list should be initialized with a new list when null
+ Assert.IsTrue(methodBody.Contains("colors = new"),
+ $"Unwrapped list should be initialized when null. Actual:\n{methodBody}");
+
+ // Unwrapped list should use Add() method directly
+ Assert.IsTrue(methodBody.Contains("colors.Add("),
+ $"Unwrapped list should use Add() method for items. Actual:\n{methodBody}");
+ }
+
+ [Test]
+ public void XmlDeserializationMethodHandlesWrappedListProperty()
+ {
+ // Arrange - create a model with a wrapped list property (items are inside a wrapper element)
+ var listProperty = new InputModelProperty(
+ name: "counts",
+ summary: null,
+ doc: "List of counts",
+ type: new InputArrayType("counts", "TypeSpec.Array", InputPrimitiveType.Int32),
+ isRequired: true,
+ isReadOnly: false,
+ isApiVersion: false,
+ defaultValue: null,
+ isHttpMetadata: false,
+ access: null,
+ isDiscriminator: false,
+ serializedName: "counts",
+ serializationOptions: new(
+ json: new("counts"),
+ xml: new("counts", unwrapped: false, itemsName: "int32")));
+
+ var inputModel = InputFactory.Model(
+ "ModelWithWrappedList",
+ usage: InputModelTypeUsage.Input | InputModelTypeUsage.Xml,
+ properties: [listProperty]);
+
+ MockHelpers.LoadMockGenerator(createSerializationsCore: (inputType, typeProvider)
+ => inputType is InputModelType modelType ? [new MrwSerializationTypeDefinition(modelType, (typeProvider as ModelProvider)!)] : []);
+
+ // Act
+ var modelProvider = new ModelProvider(inputModel);
+ var mrwProvider = modelProvider.SerializationProviders.FirstOrDefault() as MrwSerializationTypeDefinition;
+ var xmlDeserializationMethod = mrwProvider!.Methods.FirstOrDefault(m => m.Signature.Name == "DeserializeModelWithWrappedList" &&
+ m.Signature.Parameters.Any(p => p.Type.Equals(typeof(XElement))));
+
+ // Assert
+ Assert.IsNotNull(xmlDeserializationMethod);
+ var methodBody = xmlDeserializationMethod!.BodyStatements!.ToDisplayString();
+
+ // Wrapped list should iterate over child elements with specific name
+ Assert.IsTrue(methodBody.Contains("Elements(\"int32\")"),
+ "Wrapped list should iterate over child elements with items name 'int32'");
+
+ // Wrapped list should create a temp array and assign it
+ Assert.IsTrue(methodBody.Contains("counts = array"),
+ "Wrapped list should assign temp array to property");
+ }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputLibrary.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputLibrary.cs
index d49942c1e39..01ceed10a25 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputLibrary.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.Input/src/InputLibrary.cs
@@ -45,6 +45,9 @@ internal InputNamespace Load()
private bool? _hasMultiServiceClient;
public bool HasMultiServiceClient => _hasMultiServiceClient ??= GetHasMultiServiceClient();
+ private bool? _hasXmlModelSerialization;
+ public bool HasXmlModelSerialization => _hasXmlModelSerialization ??= GetHasXmlModelSerialization();
+
private bool GetHasMultipartFormDataOperation()
{
foreach (var client in InputNamespace.Clients)
@@ -73,5 +76,25 @@ private bool GetHasMultiServiceClient()
return false;
}
+
+ private bool GetHasXmlModelSerialization()
+ {
+ foreach (var model in InputNamespace.Models)
+ {
+ if (model.Usage.HasFlag(InputModelTypeUsage.Xml))
+ {
+ return true;
+ }
+ }
+
+ foreach (var enumType in InputNamespace.Enums)
+ {
+ if (enumType.Usage.HasFlag(InputModelTypeUsage.Xml))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs
index 68b43a1c015..65a3c166bad 100644
--- a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/PropertyWireInformation.cs
@@ -16,6 +16,8 @@ public class PropertyWireInformation : WireInformation
public bool IsHttpMetadata { get; }
public bool IsApiVersion { get; }
internal FormattableString? Description { get; }
+ public XmlWireInformation? XmlWireInformation { get; }
+
public PropertyWireInformation(SerializationFormat serializationFormat, bool isRequired, bool isReadOnly, bool isNullable, bool isDiscriminator, string serializedName, bool isHttpMetadata, bool isApiVersion)
: base(serializationFormat, serializedName)
{
@@ -43,6 +45,9 @@ internal PropertyWireInformation(InputProperty inputProperty)
IsDiscriminator = modelProperty != null && modelProperty.IsDiscriminator;
Description = DocHelpers.GetFormattableDescription(inputProperty.Summary, inputProperty.Doc);
IsApiVersion = inputProperty.IsApiVersion;
+ XmlWireInformation = modelProperty?.SerializationOptions?.Xml != null
+ ? new XmlWireInformation(modelProperty.SerializationOptions.Xml)
+ : null;
}
}
}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireInformation.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireInformation.cs
new file mode 100644
index 00000000000..a8352ddddfa
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireInformation.cs
@@ -0,0 +1,36 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.TypeSpec.Generator.Input;
+
+namespace Microsoft.TypeSpec.Generator.Primitives
+{
+ public class XmlWireInformation
+ {
+ public XmlWireInformation(InputXmlSerializationOptions xmlOptions)
+ {
+ Name = xmlOptions.Name;
+ Attribute = xmlOptions.Attribute;
+ Namespace = xmlOptions.Namespace != null
+ ? new(xmlOptions.Namespace)
+ : null;
+ Unwrapped = xmlOptions.Unwrapped;
+ ItemsName = xmlOptions.ItemsName;
+ ItemsNamespace = xmlOptions.ItemsNamespace != null
+ ? new(xmlOptions.ItemsNamespace)
+ : null;
+ }
+
+ public string Name { get; }
+
+ public bool? Attribute { get; }
+
+ public XmlWireNamespaceOptions? Namespace { get; }
+
+ public bool? Unwrapped { get; }
+
+ public string? ItemsName { get; }
+
+ public XmlWireNamespaceOptions? ItemsNamespace { get; }
+ }
+}
diff --git a/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireNamespaceOptions.cs b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireNamespaceOptions.cs
new file mode 100644
index 00000000000..7b1645c2db5
--- /dev/null
+++ b/packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator/src/Primitives/XmlWireNamespaceOptions.cs
@@ -0,0 +1,20 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using Microsoft.TypeSpec.Generator.Input;
+
+namespace Microsoft.TypeSpec.Generator.Primitives
+{
+ public class XmlWireNamespaceOptions
+ {
+ public XmlWireNamespaceOptions(InputXmlNamespaceOptions options)
+ {
+ Namespace = options.Namespace;
+ Prefix = options.Prefix;
+ }
+
+ public string Namespace { get; }
+
+ public string Prefix { get; }
+ }
+}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Internal/ModelSerializationExtensions.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Internal/ModelSerializationExtensions.cs
index 099511239df..60766b2c495 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Internal/ModelSerializationExtensions.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Internal/ModelSerializationExtensions.cs
@@ -14,6 +14,7 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
+using System.Xml.Linq;
namespace SampleTypeSpec
{
@@ -342,5 +343,11 @@ public static ReadOnlySpan GetRemainder(this ReadOnlySpan jsonPath,
{
return index >= jsonPath.Length ? ReadOnlySpan.Empty : jsonPath[index] == '.' ? jsonPath.Slice(index) : jsonPath.Slice(index + 2);
}
+
+ public static DateTimeOffset GetDateTimeOffset(this XElement element, string format) => format switch
+ {
+ "U" => DateTimeOffset.FromUnixTimeSeconds((long)element),
+ _ => TypeFormatters.ParseDateTimeOffset(element.Value, format)
+ };
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs
index 36d704a717f..8e21be79945 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Animal.Serialization.cs
@@ -24,6 +24,31 @@ internal Animal()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeAnimal(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(Animal)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator Animal(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeAnimal(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -121,23 +146,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
Animal IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeAnimal(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(Animal)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
@@ -150,13 +158,5 @@ public static implicit operator BinaryContent(Animal animal)
}
return BinaryContent.Create(animal, ModelSerializationExtensions.WireOptions);
}
-
- /// The to deserialize the from.
- public static explicit operator Animal(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeAnimal(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/AnotherDynamicModel.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/AnotherDynamicModel.Serialization.cs
index 05e288342d8..76d814574ca 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/AnotherDynamicModel.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/AnotherDynamicModel.Serialization.cs
@@ -20,6 +20,23 @@ internal AnotherDynamicModel()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual AnotherDynamicModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeAnotherDynamicModel(document.RootElement, data, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(AnotherDynamicModel)} does not support reading '{options.Format}' format.");
+ }
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -119,23 +136,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
AnotherDynamicModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual AnotherDynamicModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeAnotherDynamicModel(document.RootElement, data, options);
- }
- default:
- throw new FormatException($"The model {nameof(AnotherDynamicModel)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs
index 470450f2c6e..e312c1a2ec5 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Dog.Serialization.cs
@@ -21,6 +21,31 @@ internal Dog()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeDog(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(Dog)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator Dog(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeDog(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -124,23 +149,6 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
Dog IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Dog)PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeDog(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(Dog)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
@@ -153,13 +161,5 @@ public static implicit operator BinaryContent(Dog dog)
}
return BinaryContent.Create(dog, ModelSerializationExtensions.WireOptions);
}
-
- /// The to deserialize the from.
- public static explicit operator Dog(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeDog(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/DynamicModel.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/DynamicModel.Serialization.cs
index acf28b88405..64d91d7577a 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/DynamicModel.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/DynamicModel.Serialization.cs
@@ -22,6 +22,23 @@ internal DynamicModel()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual DynamicModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeDynamicModel(document.RootElement, data, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(DynamicModel)} does not support reading '{options.Format}' format.");
+ }
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -725,23 +742,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
DynamicModel IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual DynamicModel PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeDynamicModel(document.RootElement, data, options);
- }
- default:
- throw new FormatException($"The model {nameof(DynamicModel)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Friend.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Friend.Serialization.cs
index 715466fac81..9368f2860ec 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Friend.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Friend.Serialization.cs
@@ -22,6 +22,31 @@ internal Friend()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual Friend PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeFriend(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(Friend)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator Friend(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeFriend(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -121,23 +146,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
Friend IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual Friend PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeFriend(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(Friend)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
@@ -150,13 +158,5 @@ public static implicit operator BinaryContent(Friend friend)
}
return BinaryContent.Create(friend, ModelSerializationExtensions.WireOptions);
}
-
- /// The to deserialize the from.
- public static explicit operator Friend(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeFriend(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/GetWidgetMetricsResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/GetWidgetMetricsResponse.Serialization.cs
index d7a261e2e5b..203f73fcd66 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/GetWidgetMetricsResponse.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/GetWidgetMetricsResponse.Serialization.cs
@@ -21,6 +21,31 @@ internal GetWidgetMetricsResponse()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual GetWidgetMetricsResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeGetWidgetMetricsResponse(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(GetWidgetMetricsResponse)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator GetWidgetMetricsResponse(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeGetWidgetMetricsResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -128,32 +153,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
GetWidgetMetricsResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual GetWidgetMetricsResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeGetWidgetMetricsResponse(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(GetWidgetMetricsResponse)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator GetWidgetMetricsResponse(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeGetWidgetMetricsResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenHeaderResponseResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenHeaderResponseResponse.Serialization.cs
index 753e36cf347..39b7850d230 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenHeaderResponseResponse.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenHeaderResponseResponse.Serialization.cs
@@ -21,6 +21,31 @@ internal ListWithContinuationTokenHeaderResponseResponse()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ListWithContinuationTokenHeaderResponseResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeListWithContinuationTokenHeaderResponseResponse(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ListWithContinuationTokenHeaderResponseResponse)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator ListWithContinuationTokenHeaderResponseResponse(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeListWithContinuationTokenHeaderResponseResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -130,32 +155,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ListWithContinuationTokenHeaderResponseResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ListWithContinuationTokenHeaderResponseResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeListWithContinuationTokenHeaderResponseResponse(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ListWithContinuationTokenHeaderResponseResponse)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator ListWithContinuationTokenHeaderResponseResponse(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeListWithContinuationTokenHeaderResponseResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenResponse.Serialization.cs
index 1f3bdc3a151..5768d610033 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenResponse.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithContinuationTokenResponse.Serialization.cs
@@ -21,6 +21,31 @@ internal ListWithContinuationTokenResponse()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ListWithContinuationTokenResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeListWithContinuationTokenResponse(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ListWithContinuationTokenResponse)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator ListWithContinuationTokenResponse(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeListWithContinuationTokenResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -141,32 +166,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ListWithContinuationTokenResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ListWithContinuationTokenResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeListWithContinuationTokenResponse(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ListWithContinuationTokenResponse)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator ListWithContinuationTokenResponse(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeListWithContinuationTokenResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithNextLinkResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithNextLinkResponse.Serialization.cs
index a7b7a76b808..c7de729f4a5 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithNextLinkResponse.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithNextLinkResponse.Serialization.cs
@@ -21,6 +21,31 @@ internal ListWithNextLinkResponse()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ListWithNextLinkResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeListWithNextLinkResponse(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ListWithNextLinkResponse)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator ListWithNextLinkResponse(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeListWithNextLinkResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -145,32 +170,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ListWithNextLinkResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ListWithNextLinkResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeListWithNextLinkResponse(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ListWithNextLinkResponse)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator ListWithNextLinkResponse(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeListWithNextLinkResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithStringNextLinkResponse.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithStringNextLinkResponse.Serialization.cs
index d67a1f445b4..74606f9283c 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithStringNextLinkResponse.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ListWithStringNextLinkResponse.Serialization.cs
@@ -21,6 +21,31 @@ internal ListWithStringNextLinkResponse()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ListWithStringNextLinkResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeListWithStringNextLinkResponse(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ListWithStringNextLinkResponse)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator ListWithStringNextLinkResponse(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeListWithStringNextLinkResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -141,32 +166,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ListWithStringNextLinkResponse IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ListWithStringNextLinkResponse PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeListWithStringNextLinkResponse(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ListWithStringNextLinkResponse)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator ListWithStringNextLinkResponse(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializeListWithStringNextLinkResponse(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithEmbeddedNonBodyParameters.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithEmbeddedNonBodyParameters.Serialization.cs
index 89013095b0b..3278bcbccd6 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithEmbeddedNonBodyParameters.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithEmbeddedNonBodyParameters.Serialization.cs
@@ -21,6 +21,23 @@ internal ModelWithEmbeddedNonBodyParameters()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ModelWithEmbeddedNonBodyParameters PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeModelWithEmbeddedNonBodyParameters(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ModelWithEmbeddedNonBodyParameters)} does not support reading '{options.Format}' format.");
+ }
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -130,23 +147,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ModelWithEmbeddedNonBodyParameters IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ModelWithEmbeddedNonBodyParameters PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeModelWithEmbeddedNonBodyParameters(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ModelWithEmbeddedNonBodyParameters)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs
index 9871324e6a1..7671388ac90 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/ModelWithRequiredNullableProperties.Serialization.cs
@@ -20,6 +20,23 @@ internal ModelWithRequiredNullableProperties()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual ModelWithRequiredNullableProperties PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeModelWithRequiredNullableProperties(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(ModelWithRequiredNullableProperties)} does not support reading '{options.Format}' format.");
+ }
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -171,23 +188,6 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
ModelWithRequiredNullableProperties IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual ModelWithRequiredNullableProperties PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializeModelWithRequiredNullableProperties(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(ModelWithRequiredNullableProperties)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/PageThing.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/PageThing.Serialization.cs
index c1c6b331996..dda7f8cd2dc 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/PageThing.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/PageThing.Serialization.cs
@@ -21,6 +21,31 @@ internal PageThing()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected virtual PageThing PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializePageThing(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(PageThing)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator PageThing(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializePageThing(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -130,32 +155,7 @@ protected virtual BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
PageThing IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected virtual PageThing PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializePageThing(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(PageThing)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
-
- /// The to deserialize the from.
- public static explicit operator PageThing(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializePageThing(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs
index e7d61d27402..9f6c2a6fd5d 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/Pet.Serialization.cs
@@ -20,6 +20,31 @@ internal Pet()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializePet(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(Pet)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator Pet(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializePet(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -99,23 +124,6 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
Pet IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (Pet)PersistableModelCreateCore(data, options);
- /// The data to parse.
- /// The client options for reading and writing models.
- protected override Animal PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
- {
- string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
- switch (format)
- {
- case "J":
- using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
- {
- return DeserializePet(document.RootElement, options);
- }
- default:
- throw new FormatException($"The model {nameof(Pet)} does not support reading '{options.Format}' format.");
- }
- }
-
/// The client options for reading and writing models.
string IPersistableModel.GetFormatFromOptions(ModelReaderWriterOptions options) => "J";
@@ -128,13 +136,5 @@ public static implicit operator BinaryContent(Pet pet)
}
return BinaryContent.Create(pet, ModelSerializationExtensions.WireOptions);
}
-
- /// The to deserialize the from.
- public static explicit operator Pet(ClientResult result)
- {
- PipelineResponse response = result.GetRawResponse();
- using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
- return DeserializePet(document.RootElement, ModelSerializationExtensions.WireOptions);
- }
}
}
diff --git a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/RenamedModelCustom.Serialization.cs b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/RenamedModelCustom.Serialization.cs
index 667d863ca58..ec084524432 100644
--- a/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/RenamedModelCustom.Serialization.cs
+++ b/packages/http-client-csharp/generator/TestProjects/Local/Sample-TypeSpec/src/Generated/Models/RenamedModelCustom.Serialization.cs
@@ -22,6 +22,31 @@ internal RenamedModelCustom()
{
}
+ /// The data to parse.
+ /// The client options for reading and writing models.
+ protected override Friend PersistableModelCreateCore(BinaryData data, ModelReaderWriterOptions options)
+ {
+ string format = options.Format == "W" ? ((IPersistableModel)this).GetFormatFromOptions(options) : options.Format;
+ switch (format)
+ {
+ case "J":
+ using (JsonDocument document = JsonDocument.Parse(data, ModelSerializationExtensions.JsonDocumentOptions))
+ {
+ return DeserializeRenamedModelCustom(document.RootElement, options);
+ }
+ default:
+ throw new FormatException($"The model {nameof(RenamedModelCustom)} does not support reading '{options.Format}' format.");
+ }
+ }
+
+ /// The to deserialize the from.
+ public static explicit operator RenamedModelCustom(ClientResult result)
+ {
+ PipelineResponse response = result.GetRawResponse();
+ using JsonDocument document = JsonDocument.Parse(response.Content, ModelSerializationExtensions.JsonDocumentOptions);
+ return DeserializeRenamedModelCustom(document.RootElement, ModelSerializationExtensions.WireOptions);
+ }
+
/// The JSON writer.
/// The client options for reading and writing models.
void IJsonModel.Write(Utf8JsonWriter writer, ModelReaderWriterOptions options)
@@ -113,23 +138,6 @@ protected override BinaryData PersistableModelWriteCore(ModelReaderWriterOptions
/// The client options for reading and writing models.
RenamedModelCustom IPersistableModel.Create(BinaryData data, ModelReaderWriterOptions options) => (RenamedModelCustom)PersistableModelCreateCore(data, options);
- ///