Skip to content
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

System.Text.Json Overflow throw exception #48350

Closed
LetMeSleepAlready opened this issue Feb 16, 2021 · 5 comments
Closed

System.Text.Json Overflow throw exception #48350

LetMeSleepAlready opened this issue Feb 16, 2021 · 5 comments

Comments

@LetMeSleepAlready
Copy link

According to https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-handle-overflow one can capture object-unknown fields inside the deserialized object by using JsonExtensionData

Without adding such an extension to all my objects, how can I make the deserializer throw an exception when an unknown field is encountered? I find it strange that upon an extra comma an exception is/can be thrown, but not on a completely unknown field.

I have not found any parameter where I can set this up, or somehow an efficient extension that I could add for this. For me this feature (throw exception, or in some other way capture these errors without changing all my objects) is relevant to be able to move away from hand-crafted json-Schemas and instead rely in DataAnnotations completely.

In light of that, I have also not found a way to validate the annotations while deserializing. This seems the right spot to do so however, as the json deserializer is already handling each individual object in the object-tree. Something that System.ComponentModel.DataAnnotations.Validator.TryValidateObject will not do (it only does 1st level properties)

Any guidance is appreciated.

@dotnet-issue-labeler dotnet-issue-labeler bot added area-System.Text.Json untriaged New issue has not been triaged by the area owner labels Feb 16, 2021
@ghost
Copy link

ghost commented Feb 16, 2021

Tagging subscribers to this area: @eiriktsarpalis, @layomia
See info in area-owners.md if you want to be subscribed.

Issue Details

According to https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-handle-overflow one can capture object-unknown fields inside the deserialized object by using JsonExtensionData

Without adding such an extension to all my objects, how can I make the deserializer throw an exception when an unknown field is encountered? I find it strange that upon an extra comma an exception is/can be thrown, but not on a completely unknown field.

I have not found any parameter where I can set this up, or somehow an efficient extension that I could add for this. For me this feature (throw exception, or in some other way capture these errors without changing all my objects) is relevant to be able to move away from hand-crafted json-Schemas and instead rely in DataAnnotations completely.

In light of that, I have also not found a way to validate the annotations while deserializing. This seems the right spot to do so however, as the json deserializer is already handling each individual object in the object-tree. Something that System.ComponentModel.DataAnnotations.Validator.TryValidateObject will not do (it only does 1st level properties)

Any guidance is appreciated.

Author: LetMeSleepAlready
Assignees: -
Labels:

area-System.Text.Json, untriaged

Milestone: -

@layomia
Copy link
Contributor

layomia commented Feb 16, 2021

This is describing a feature to throw an exception when a JSON property doesn't match with a CLR property. It is technically doable, but I'd like to understand the motivation here a bit more. Do you have a real-world scenario where this is useful? Is there existing functionality in other JSON serializers in or outside the .NET ecosystem that provides similar functionality?

@layomia layomia removed the untriaged New issue has not been triaged by the area owner label Feb 16, 2021
@layomia layomia added this to the Future milestone Feb 16, 2021
@LetMeSleepAlready
Copy link
Author

Right, fair enough question.

I am working on an api (ordering, money, you probably understand the restriction there on error margin), where certain fields are optional. However, this optionality completely changes the result of the order. As such, a typo where a fieldname is mistyped or whatever will go unnoticed in code, but not in the end result. I can not return an error because the code simply never knows that 'something' was not as intended.
It will severely hinder testing trajects with our customers if we can not detect this in the testing phase automatically. I would need to manually check the results of each order to figure out whether or not all fields were typed correctly. But also in production 'people do stuff' that they shouldn't (quick fixes and the like, those never work out well...).

I am currently able to do this with Json.Net like so:

JsonSerializer serializer = new JsonSerializer();
serializer.MissingMemberHandling = MissingMemberHandling.Error; // System.Text.Json does not handle this
JsonTextReader reader = new JsonTextReader(textStream);
var returnObject = serializer.Deserialize<T>(reader);

In System.Text.Json it could be as simple as:

var returnObject = System.Text.Json.JsonSerializer.Deserialize<T>(textStream.ReadToEnd(), new System.Text.Json.JsonSerializerOptions
{
   AllowTrailingCommas = false,
   AllowExtraMembers= false // defaults to true
});

I don't even care to find all errors.. single error => BAM incorrect format and I return the error message to the customer.

Having this extra validation won't do a complete data annotations validation of course, but at least it will make sure that the format in the Json corresponds to the format in the CLR object.

This feature would make me get one step closer to phasing out json.net. At least one step..

@LetMeSleepAlready
Copy link
Author

Also, from https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to?pivots=dotnet-5-0

MissingMemberHandling

Newtonsoft.Json can be configured to throw exceptions during deserialization if the JSON includes properties that are missing in the target type. System.Text.Json ignores extra properties in the JSON, except when you use the [JsonExtensionData] attribute. There's no workaround for the missing member feature.

This would then be solved :)

@eiriktsarpalis
Copy link
Member

Duplicate of #37483

@eiriktsarpalis eiriktsarpalis marked this as a duplicate of #37483 Oct 21, 2021
@ghost ghost locked as resolved and limited conversation to collaborators Nov 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants