Skip to content

Conversation

WanjohiSammy
Copy link
Member

@WanjohiSammy WanjohiSammy commented Jul 2, 2025

Issues

This pull request fixes

Description

The change ensures that untyped values of various primitive types are correctly deserialized and materialized, supporting a broader range of types.

The previous implementation only handled bool, string, and defaulted all other types to decimal. This was insufficient for untyped properties that could be of unresolved types such as int, long, double, and collections.

This change introduces a new boolean flag PreserveUntypedNumericAsDecimal to enhance control over how untyped numeric values are handled during JSON parsing.

  • Default behavior: When set to true, untyped numeric values are preserved as decimal to maintain precision.
  • Alternative behavior: When set to false, numeric values are inferred and converted to specific types (int, long, double, float) based on their runtime type.

Checklist (Uncheck if it is not completed)

  • Test cases added
  • Build and test with one-click build and test script passed

Additional work necessary

If documentation update is needed, please add "Docs Needed" label to the issue and provide details about the required document change in the issue.

Repository notes

Team members can start a CI build by adding a comment with the text /AzurePipelines run to a PR. A bot may respond indicating that there is no pipeline associated with the pull request. This can be ignored if the build is triggered.

Team members should not trigger a build this way for pull requests coming from forked repositories. They should instead trigger the build manually by setting the "branch" to refs/pull/{prId}/merge where {prId} is the ID of the PR.

@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

Copy link

No pipelines are associated with this pull request.

@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

Copy link

No pipelines are associated with this pull request.

@WanjohiSammy WanjohiSammy changed the title Resolve Untypes Resolve issues with Deserialization of Untyped Types Aug 22, 2025
@WanjohiSammy WanjohiSammy marked this pull request as ready for review August 22, 2025 09:22
@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

Copy link

No pipelines are associated with this pull request.

@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

Copy link

No pipelines are associated with this pull request.

xuzhg
xuzhg previously approved these changes Aug 25, 2025
payloadTypeReference,
this.MessageReaderSettings.PrimitiveTypeResolver,
this.MessageReaderSettings.ReadUntypedAsString,
!this.MessageReaderSettings.ThrowIfTypeConflictsWithMetadata);
Copy link
Member

Choose a reason for hiding this comment

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

If it's for 9.x, do we need to keep back compatible?

@gathogojr
Copy link
Contributor

@WanjohiSammy I’d like to highlight two specific comments from the thread on the issue you have referenced that are particularly relevant to this PR:

Regarding backward compatibility, we typically manage such changes using the LibraryCompatibility enum. You can see how this is structured here:
https://github.com/OData/odata.net/blob/main/src/Microsoft.OData.Core/ODataLibraryCompatibility.cs

To align with this approach, I suggest introducing a new enum member, e.g., ReadUntypedNumericAsDecimal, with a value like 1 << 5. This flag can then be included in the Version6 and Version7 enum members, and you can define Version8 = ReadUntypedNumericAsDecimal. Toggling the flag will preserve the old behaviour in 6.x, 7.x, and 8.x.

Since ODataMessageReaderSettings already exposes a LibraryCompatibility property, this approach wouldn’t require introducing a new setting.

Finally, please refer to how compatibility flags are evaluated and toggled across the library to ensure consistency with existing patterns.

bool readUntypedAsString,
bool generateTypeIfMissing)
bool generateTypeIfMissing,
bool readUntypedNumericAsDecimal = true)
Copy link
Contributor

@gathogojr gathogojr Sep 9, 2025

Choose a reason for hiding this comment

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

Given that this method is internal, and we have updated the call points to pass the relevant value, do we need to set a default parameter value?

Copy link
Member Author

Choose a reason for hiding this comment

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

Resolved

@gathogojr
Copy link
Contributor

Just to confirm, if I create a new instance of ODataMessageReaderSettings, without doing much else, will the new behaviour be applied?

@WanjohiSammy
Copy link
Member Author

WanjohiSammy commented Sep 12, 2025

Just to confirm, if I create a new instance of ODataMessageReaderSettings, without doing much else, will the new behavior be applied?

Yes, this is correct, the new behavior will be applied.

I have added tests: https://github.com/OData/odata.net/pull/3283/files#diff-503ffc0454f3d70fe4153d243d53eb35d79aaddfc1d9dcd09e742f4aa88d9317

@WanjohiSammy WanjohiSammy force-pushed the fix/resolve-untype-values branch from ffc1bdd to 991925b Compare September 22, 2025 16:35
@WanjohiSammy WanjohiSammy force-pushed the fix/resolve-untype-values branch from 991925b to 2f26a40 Compare September 22, 2025 16:42
@WanjohiSammy WanjohiSammy force-pushed the fix/resolve-untype-values branch from 2f26a40 to a28eb6e Compare September 26, 2025 07:04
@WanjohiSammy
Copy link
Member Author

/AzurePipelines run

Copy link

No pipelines are associated with this pull request.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants