-
Notifications
You must be signed in to change notification settings - Fork 4.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: Create number from string in System.Text.Json.Nodes #111548
Comments
This doesn't create a JSON number. It creates a string containing only digits. You want JsonValue.Create(123); // number node Moreover, there are implicit casts that do this for you. JsonNode value = 123; |
@gregsdennis Apologies, that was a typo that has been fixed. Please see the rest of the proposal for info on why that API isn't enough. |
Also pertinent to this discussion is that the For example // the element holds the value as a span of the source string
// and separately recognizes it as a JSON number
var value = JsonDocument.Parse("123").RootElement;
// the value is only converted to the requested type here
var asInt32 = value.GetInt32();
//or
var asInt16 = value.GetInt16(); |
Assigned to @PranavSenthilnathan for triage and consideration. |
The risks you shared for allowing arbitrary formatting (e.g. hex) in JsonNodes are concerning. Is perf the only downside to first processing the input string with custom formatting aware logic and then calling For perf, what are the bottlenecks that you run into? Currently we materialize a |
@PranavSenthilnathan Hi. Since posting this I've realized that it's better to standardize the number before putting it into a However, having to use |
Could the generic math feature added in public static JsonValue? Create<T>(T? value, JsonNodeOptions? options = null) where T : INumberBase<T>; |
Background and motivation
System.Text.Json.Nodes.JsonNode
is a very powerful API to build up aJsonElement
dynamically. However, it has some limitations that prevent custom parsers for JSON-compatible formats outsideSystem.Text.Json
(e.g. JSON5, HJSON, HOCON) from achieving true interoperability withSystem.Text.Json
.A primitive value node can be created like this:
However, there is no way to create a number value from a string without first parsing it into a fixed-size value. This is a problem for values outside of the range limits of those values (e.g. numbers larger than 2^63-1).
This means you're left with three options:
JsonSerializer.Deserialize<JsonNode>("123")
. However, this is not performant (the number has to be re-parsed) and it doesn't support numbers in non-standard formats, meaning parsers for formats like JSON5 and HJSON must normalise the number (e.g. hexadecimal must be converted to decimal), and you lose data.JsonValue.Create(int.Parse("123"))
. Again, this is not performant, but the primary issue is that it doesn't support very large or very precise numbers.JsonNumberHandling.AllowReadingFromString
. This can be done usingJsonValue.Create("123")
. This is likely the best option, but it provides no way to distinguish between strings and numbers (e.g. there will be no difference between123
and"123"
).API Proposal
API Usage
Alternative Designs
Risks
If the API is misused, valid JsonNodes could contain poorly-formatted or invalid values. Different APIs using JsonNode may have different ideas on what values are valid. For example, some implementations may create number nodes with trailing decimal points (
5.
), while others throw an exception trying to deserialize this.Use Cases
See my HJSON/JSON5 parser: https://github.com/Joy-less/HjsonSharp
The text was updated successfully, but these errors were encountered: