Skip to content

Fix reflection XmlSerializer choice identifier with XmlEnum aliases#130445

Open
StephenMolloy wants to merge 1 commit into
dotnet:mainfrom
StephenMolloy:130017-Reflection-Serializer-Choice-Identifier-Name-Flexibility
Open

Fix reflection XmlSerializer choice identifier with XmlEnum aliases#130445
StephenMolloy wants to merge 1 commit into
dotnet:mainfrom
StephenMolloy:130017-Reflection-Serializer-Choice-Identifier-Name-Flexibility

Conversation

@StephenMolloy

Copy link
Copy Markdown
Member

The reflection-based XmlSerializer (ReflectionXmlSerializationReader) resolved an [XmlChoiceIdentifier] enum value during deserialization by comparing the choice enum member identifiers directly against the matched XML element name. That only works when the enum member name equals the element name, so a choice enum using [XmlEnum] aliases (e.g. [XmlEnum("Number")] NumberChoice) failed to round-trip: the choice field was left at its default instead of the value implied by the element.

Resolve the choice value positionally instead, using the element index already computed when matching the element and reading the corresponding choice.MemberIds[elementIndex]. This mirrors exactly how the IL-generated reader resolves the choice and reuses the alias-aware MemberIds table that XmlReflectionImporter builds up front, so [XmlEnum] aliases are honored.

Add a regression test (Xml_TypeWithAliasedChoiceIdentifier) plus the supporting AliasedChoiceType enum and TypeWithAliasedChoiceIdentifier type, covering the previously untested combination of [XmlChoiceIdentifier] with [XmlEnum] aliases. The test runs against both the reflection reader and the ReflectionOnly serializer configurations.

Fixes #130017

The reflection-based XmlSerializer (ReflectionXmlSerializationReader)
resolved an [XmlChoiceIdentifier] enum value during deserialization by
comparing the choice enum member identifiers directly against the matched
XML element name. That only works when the enum member name equals the
element name, so a choice enum using [XmlEnum] aliases (e.g.
[XmlEnum("Number")] NumberChoice) failed to round-trip: the choice field
was left at its default instead of the value implied by the element.

Resolve the choice value positionally instead, using the element index
already computed when matching the element and reading the corresponding
choice.MemberIds[elementIndex]. This mirrors exactly how the IL-generated
reader resolves the choice and reuses the alias-aware MemberIds table that
XmlReflectionImporter builds up front, so [XmlEnum] aliases are honored.

Add a regression test (Xml_TypeWithAliasedChoiceIdentifier) plus the
supporting AliasedChoiceType enum and TypeWithAliasedChoiceIdentifier type,
covering the previously untested combination of [XmlChoiceIdentifier] with
[XmlEnum] aliases. The test runs against both the reflection reader and the
ReflectionOnly serializer configurations.

Fixes dotnet#130017

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@StephenMolloy StephenMolloy added this to the 11.0.0 milestone Jul 10, 2026
@StephenMolloy StephenMolloy self-assigned this Jul 10, 2026
Copilot AI review requested due to automatic review settings July 10, 2026 00:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a deserialization bug in the reflection-based XmlSerializer reader where [XmlChoiceIdentifier] values were derived by comparing enum member identifiers to XML element names (which breaks when the enum uses [XmlEnum] aliases). The reader now resolves the choice identifier by using the already-computed matched element index to select choice.MemberIds[elementIndex], aligning behavior with the IL-generated reader.

Changes:

  • Update ReflectionXmlSerializationReader to set choice identifiers based on the matched element index (rather than element name string comparison).
  • Add new serialization test types covering [XmlChoiceIdentifier] + [XmlEnum] alias usage.
  • Add a regression test that round-trips an aliased choice identifier and validates both the item and choice enum value.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
src/libraries/System.Private.Xml/src/System/Xml/Serialization/ReflectionXmlSerializationReader.cs Switch choice identifier assignment to use positional MemberIds[elementIndex], ensuring alias-aware resolution matches ILGen behavior.
src/libraries/System.Runtime.Serialization.Xml/tests/SerializationTypes.RuntimeOnly.cs Add AliasedChoiceType and TypeWithAliasedChoiceIdentifier test types to model aliased choice identifiers.
src/libraries/System.Private.Xml/tests/XmlSerializer/XmlSerializerTests.RuntimeOnly.cs Add regression test validating round-trip of aliased choice identifier through SerializeAndDeserialize.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reflection-based XmlSerializer resolves [XmlChoiceIdentifier] enum incorrectly with [XmlEnum] aliases

2 participants