Fix reflection XmlSerializer choice identifier with XmlEnum aliases#130445
Open
StephenMolloy wants to merge 1 commit into
Open
Conversation
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>
Contributor
There was a problem hiding this comment.
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
ReflectionXmlSerializationReaderto 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. |
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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