Skip to content

Commit

Permalink
[http-client-csharp] fix: use correct discriminator prop name during …
Browse files Browse the repository at this point in the history
…deserialization (#4953)

fixes : #4949
  • Loading branch information
jorgerangel-msft authored Nov 1, 2024
1 parent b47d039 commit 597d794
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,9 @@ private MethodBodyStatement[] BuildAbstractDeserializationMethodBody()
{
var unknownVariant = _model.DerivedModels.First(m => m.IsUnknownDiscriminatorModel);
bool onlyContainsUnknownDerivedModel = _model.DerivedModels.Count == 1;
var discriminator = _model.CanonicalView.Properties.Where(p => p.IsDiscriminator).FirstOrDefault();
var deserializeDiscriminatedModelsConditions = BuildDiscriminatedModelsCondition(
discriminator,
GetAbstractSwitchCases(unknownVariant),
onlyContainsUnknownDerivedModel,
_jsonElementParameterSnippet);
Expand All @@ -457,13 +459,16 @@ private MethodBodyStatement[] BuildAbstractDeserializationMethodBody()
}

private static MethodBodyStatement BuildDiscriminatedModelsCondition(
PropertyProvider? discriminatorProperty,
SwitchCaseStatement[] abstractSwitchCases,
bool onlyContainsUnknownDerivedModel,
ScopedApi<JsonElement> jsonElementParameterSnippet)
{
if (!onlyContainsUnknownDerivedModel)
if (!onlyContainsUnknownDerivedModel && discriminatorProperty?.WireInfo?.SerializedName != null)
{
return new IfStatement(jsonElementParameterSnippet.TryGetProperty("kind", out var discriminator))
return new IfStatement(jsonElementParameterSnippet.TryGetProperty(
discriminatorProperty.WireInfo.SerializedName,
out var discriminator))
{
new SwitchStatement(discriminator.GetString(), abstractSwitchCases)
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,5 +172,33 @@ public void DerivedShouldPassLiteralForKindToBase()
Assert.IsFalse(initializer!.Arguments.Any(a => a.ToDisplayString().Contains("kind")));
Assert.IsTrue(initializer!.Arguments.Any(a => a.ToDisplayString() == "\"cat\""));
}

// This test validates that the correct discriminator property name is used when deserializing
[Test]
public void DiscriminatorDeserializationUsesCorrectDiscriminatorPropName()
{
var treeModel = InputFactory.Model(
"tree",
discriminatedKind: "tree",
properties:
[]);
var baseModel = InputFactory.Model(
"plant",
properties:
[
InputFactory.Property("foo", InputPrimitiveType.String, isRequired: true, isDiscriminator: true),
],
discriminatedModels: new Dictionary<string, InputModelType>() { { "tree", treeModel } });

MockHelpers.LoadMockPlugin(inputModels: () => [baseModel, treeModel]);
var baseModelProvider = ClientModelPlugin.Instance.OutputLibrary.TypeProviders.OfType<ModelProvider>()
.FirstOrDefault(t => t.Name == "Plant");
Assert.IsNotNull(baseModelProvider);

var deserializationMethod = baseModelProvider!.SerializationProviders.FirstOrDefault()!.Methods
.FirstOrDefault(m => m.Signature.Name == "DeserializePlant");
Assert.IsTrue(deserializationMethod?.BodyStatements!.ToDisplayString().Contains(
$"if (element.TryGetProperty(\"foo\"u8, out global::System.Text.Json.JsonElement discriminator))"));
}
}
}

0 comments on commit 597d794

Please sign in to comment.