-
Notifications
You must be signed in to change notification settings - Fork 226
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't generate prop if custom prop exists in base (#4682)
This PR address the following bugs: - If a model contains a spec property that was also added as a custom model in it's base model, the derived model will not generate the property. - if a custom property is added to a base model and it includes the `CodeGenSerialization` attribute, that property is included in serialization ctor for the derived model. fixes: #4629
- Loading branch information
1 parent
3660144
commit ff1725c
Showing
11 changed files
with
434 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
...initions/TestData/ModelCustomizationTests/CanSerializeCustomPropertyFromBase/BaseModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using Sample; | ||
using System; | ||
using System.Collections.Generic; | ||
using Microsoft.Generator.CSharp.Customization; | ||
|
||
namespace Sample.Models; | ||
|
||
[CodeGenSerialization(nameof(Prop1), DeserializationValueHook = nameof(DeserializationMethod))] | ||
public partial class BaseModel | ||
{ | ||
internal string Prop1 { get; set; } | ||
|
||
private static void DeserializationMethod(JsonProperty property, ref string fieldValue) | ||
=> fieldValue = property.Value.GetString(); | ||
} |
136 changes: 136 additions & 0 deletions
136
...tData/SerializationCustomizationTests/CanCustomizeSerializationMethodForPropertyInBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// <auto-generated/> | ||
|
||
#nullable disable | ||
|
||
using System; | ||
using System.ClientModel; | ||
using System.ClientModel.Primitives; | ||
using System.Collections.Generic; | ||
using System.Text.Json; | ||
using Sample; | ||
|
||
namespace Sample.Models | ||
{ | ||
/// <summary></summary> | ||
public partial class MockInputModel : global::System.ClientModel.Primitives.IJsonModel<global::Sample.Models.MockInputModel> | ||
{ | ||
internal MockInputModel() | ||
{ | ||
} | ||
|
||
void global::System.ClientModel.Primitives.IJsonModel<global::Sample.Models.MockInputModel>.Write(global::System.Text.Json.Utf8JsonWriter writer, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
writer.WriteStartObject(); | ||
this.JsonModelWriteCore(writer, options); | ||
writer.WriteEndObject(); | ||
} | ||
|
||
/// <param name="writer"> The JSON writer. </param> | ||
/// <param name="options"> The client options for reading and writing models. </param> | ||
protected override void JsonModelWriteCore(global::System.Text.Json.Utf8JsonWriter writer, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
string format = (options.Format == "W") ? ((global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>)this).GetFormatFromOptions(options) : options.Format; | ||
if ((format != "J")) | ||
{ | ||
throw new global::System.FormatException($"The model {nameof(global::Sample.Models.MockInputModel)} does not support writing '{format}' format."); | ||
} | ||
base.JsonModelWriteCore(writer, options); | ||
writer.WritePropertyName("otherProp"u8); | ||
writer.WriteNumberValue(OtherProp); | ||
} | ||
|
||
global::Sample.Models.MockInputModel global::System.ClientModel.Primitives.IJsonModel<global::Sample.Models.MockInputModel>.Create(ref global::System.Text.Json.Utf8JsonReader reader, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) => ((global::Sample.Models.MockInputModel)this.JsonModelCreateCore(ref reader, options)); | ||
|
||
/// <param name="reader"> The JSON reader. </param> | ||
/// <param name="options"> The client options for reading and writing models. </param> | ||
protected override global::Sample.Models.BaseModel JsonModelCreateCore(ref global::System.Text.Json.Utf8JsonReader reader, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
string format = (options.Format == "W") ? ((global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>)this).GetFormatFromOptions(options) : options.Format; | ||
if ((format != "J")) | ||
{ | ||
throw new global::System.FormatException($"The model {nameof(global::Sample.Models.MockInputModel)} does not support reading '{format}' format."); | ||
} | ||
using global::System.Text.Json.JsonDocument document = global::System.Text.Json.JsonDocument.ParseValue(ref reader); | ||
return global::Sample.Models.MockInputModel.DeserializeMockInputModel(document.RootElement, options); | ||
} | ||
|
||
internal static global::Sample.Models.MockInputModel DeserializeMockInputModel(global::System.Text.Json.JsonElement element, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
if ((element.ValueKind == global::System.Text.Json.JsonValueKind.Null)) | ||
{ | ||
return null; | ||
} | ||
int otherProp = default; | ||
int prop1 = default; | ||
global::System.Collections.Generic.IDictionary<string, global::System.BinaryData> additionalBinaryDataProperties = new global::Sample.ChangeTrackingDictionary<string, global::System.BinaryData>(); | ||
foreach (var prop in element.EnumerateObject()) | ||
{ | ||
if (prop.NameEquals("otherProp"u8)) | ||
{ | ||
otherProp = prop.Value.GetInt32(); | ||
continue; | ||
} | ||
if (prop.NameEquals("prop1"u8)) | ||
{ | ||
DeserializationMethod(prop, ref prop1); | ||
continue; | ||
} | ||
if ((options.Format != "W")) | ||
{ | ||
additionalBinaryDataProperties.Add(prop.Name, global::System.BinaryData.FromString(prop.Value.GetRawText())); | ||
} | ||
} | ||
return new global::Sample.Models.MockInputModel(otherProp, prop1, additionalBinaryDataProperties); | ||
} | ||
|
||
global::System.BinaryData global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>.Write(global::System.ClientModel.Primitives.ModelReaderWriterOptions options) => this.PersistableModelWriteCore(options); | ||
|
||
/// <param name="options"> The client options for reading and writing models. </param> | ||
protected override global::System.BinaryData PersistableModelWriteCore(global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
string format = (options.Format == "W") ? ((global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>)this).GetFormatFromOptions(options) : options.Format; | ||
switch (format) | ||
{ | ||
case "J": | ||
return global::System.ClientModel.Primitives.ModelReaderWriter.Write(this, options); | ||
default: | ||
throw new global::System.FormatException($"The model {nameof(global::Sample.Models.MockInputModel)} does not support writing '{options.Format}' format."); | ||
} | ||
} | ||
|
||
global::Sample.Models.MockInputModel global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>.Create(global::System.BinaryData data, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) => ((global::Sample.Models.MockInputModel)this.PersistableModelCreateCore(data, options)); | ||
|
||
/// <param name="data"> The data to parse. </param> | ||
/// <param name="options"> The client options for reading and writing models. </param> | ||
protected override global::Sample.Models.BaseModel PersistableModelCreateCore(global::System.BinaryData data, global::System.ClientModel.Primitives.ModelReaderWriterOptions options) | ||
{ | ||
string format = (options.Format == "W") ? ((global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>)this).GetFormatFromOptions(options) : options.Format; | ||
switch (format) | ||
{ | ||
case "J": | ||
using (global::System.Text.Json.JsonDocument document = global::System.Text.Json.JsonDocument.Parse(data)) | ||
{ | ||
return global::Sample.Models.MockInputModel.DeserializeMockInputModel(document.RootElement, options); | ||
} | ||
default: | ||
throw new global::System.FormatException($"The model {nameof(global::Sample.Models.MockInputModel)} does not support reading '{options.Format}' format."); | ||
} | ||
} | ||
|
||
string global::System.ClientModel.Primitives.IPersistableModel<global::Sample.Models.MockInputModel>.GetFormatFromOptions(global::System.ClientModel.Primitives.ModelReaderWriterOptions options) => "J"; | ||
|
||
/// <param name="mockInputModel"> The <see cref="global::Sample.Models.MockInputModel"/> to serialize into <see cref="global::System.ClientModel.BinaryContent"/>. </param> | ||
public static implicit operator BinaryContent(global::Sample.Models.MockInputModel mockInputModel) | ||
{ | ||
return global::System.ClientModel.BinaryContent.Create(mockInputModel, global::Sample.ModelSerializationExtensions.WireOptions); | ||
} | ||
|
||
/// <param name="result"> The <see cref="global::System.ClientModel.ClientResult"/> to deserialize the <see cref="global::Sample.Models.MockInputModel"/> from. </param> | ||
public static explicit operator MockInputModel(global::System.ClientModel.ClientResult result) | ||
{ | ||
using global::System.ClientModel.Primitives.PipelineResponse response = result.GetRawResponse(); | ||
using global::System.Text.Json.JsonDocument document = global::System.Text.Json.JsonDocument.Parse(response.Content); | ||
return global::Sample.Models.MockInputModel.DeserializeMockInputModel(document.RootElement, global::Sample.ModelSerializationExtensions.WireOptions); | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
...alizationCustomizationTests/CanCustomizeSerializationMethodForPropertyInBase/BaseModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
using Microsoft.Generator.CSharp.Customization; | ||
|
||
namespace Sample.Models | ||
{ | ||
[CodeGenSerialization(nameof(Prop1), SerializationValueHook = nameof(SerializationMethod), DeserializationValueHook = nameof(DeserializationMethod))] | ||
public partial class BaseModel | ||
{ | ||
private void SerializationMethod(Utf8JsonWriter writer, ModelReaderWriterOptions options) | ||
=> writer.WriteObjectValue(Prop1, options); | ||
|
||
private static void DeserializationMethod(JsonProperty property, ref string fieldValue) | ||
=> fieldValue = property.Value.GetString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.