Repository navigation
System.Text.Json option to ignore default values during serialization #779
Description
Activity
Currently there is no support for Ignoring Default Values while Serialization in
System.Text.Json, which is required for ignoring default value for value types (Data type), as mentioned earlier by @karthickthangasamy the same support is available in Json.NET, this can be achieved by adding an APIIgnoreDefaultValuesto the Json Serializer Options and then validating a condition to check if the IgnoreDefaultValues API is set true and the value is default value before serializing only for the value types since it cannot be provided for reference types.Proposed API
IgnoreDefaultValuesAPI is proposed similar to existing APIIgnoreNullValues/// <summary> /// Determines whether default values are ignored during serialization and deserialization. /// The default value is false. /// </summary> /// <exception cref="InvalidOperationException"> /// Thrown if this property is set after serialization or deserialization has occurred. /// </exception> public bool IgnoreDefaultValues { get { return _ignoreDefaultValues; } set { VerifyMutable(); _ignoreDefaultValues = value; } }
bool includeProperty = true; // Check default value property. if (options.IgnoreDefaultValues) { DefaultValueAttribute defaultValueAttribute = JsonPropertyInfo.GetAttribute<DefaultValueAttribute>(jsonPropertyInfo.PropertyInfo); currentValue = jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue); includeProperty = (defaultValueAttribute != null && object.Equals(currentValue, defaultValueAttribute.Value)) == false; } if (includeProperty) { jsonPropertyInfo.Write(ref state, writer); }
Details
- Added API
IgnoreDefaultValuesfor getting input from user if default values are to be ignored while JSON serialization using JsonSerializerOptions in System.Text.Json. - Implemented the same by validating if IgnoreDefaultValues API is set to true by user and the value to be serialized is a default value and if so the same is ignored and move to next property while serialization.
Pull Request
A PR with the proposed changes is available: #42288
Reacted by Karthick T and KameshRajendran- Added API
@layomia following on from https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/api-review-process.md, who is the owner of this suggestion? Is there anything we can we do to help move this through discussion?
From @SanderSade in #681:
JSON.NET has DefaultValueHandling enumeration, which allows users to determine how the default values are handled during de/serialization.
Similar functionality would be very useful in System.Text.Json, as DefaultValueHandling.Ignore/IgnoreAndPopulate would allow considerable reduction of JSON size in many cases.
- addeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Dec 11, 2019 @nickevansuk we are planning for 5.0 and this issue is being discussed. The next step is to create a formal API proposal. The proposal should include API modifications, rationale, usage scenarios and code examples, and raise any open questions. This would be a good way to help move this along. Here is an example of a good one: https://github.com/dotnet/corefx/issues/4547#issue-117426449.
This proposal should be added to this thread, and we'll merge it into the description of this issue for greater visibility. I'll own the feature and drive it through framework core API review.
Some things to consider for this issue:
- granularity: should the option be global (on JsonSerializerOptions), per-property (probably leveraging the
JsonIgnoreConditionenum being proposed in https://github.com/dotnet/corefx/issues/40600), or both? - scope: should the option be applied to serialization, deserialization, or both?
- how to indicate the default value
- this could be with an attribute: Should the
DefaultValueAttributein System.ComponentModel be used, or should System.Text.Json implement a new one. Plays into the larger question of whether S.T.Json should use [external attributes](https://github.com/dotnet/corefx/issues/38758, https://github.com/dotnet/corefx/issues/41578). - there could be a new "catch all" attribute like Newtonsoft's
JsonPropertyAttributewhich could contain properties likeDefaultValue,IgnoreCondition, and prevent numerous attributes being added to satisfy other features (e.g. something likeJsonIncludeAttributeto support properties with non-public setter/getters - https://github.com/dotnet/corefx/issues/38163). - presumably, the default value would fallback to
default(typeof(PropertyInQuestion))if none is provided.
- this could be with an attribute: Should the
- granularity: should the option be global (on JsonSerializerOptions), per-property (probably leveraging the
Regarding:
"granularity: should the option be global (on JsonSerializerOptions), per-property (probably leveraging the JsonIgnoreCondition enum being proposed in dotnet/corefx#40600), or both?"If the granularity is per-property, this could probably be used to solve:
#512Is there an ETA for this feature in an upcoming release? My JSON class has many bools and it would be nice to default them all to false which would greatly reduce the serialized size.
Reacted by Karthick T and MatthiasDon't want to point out obvious but for the time being one can make value type fields nullable and use
IgnoreNullValues = trueto get around this limitation.Reacted by 100の人 (エスパー・イーシア)Don't want to point out obvious but for the time being one can make value type fields nullable and use
IgnoreNullValues = trueto get around this limitation.Yes I did consider this. My models are used with a Razor engine application and bool? will not bind to checkboxes unfortunately.
- removeduntriagedNew issue has not been triaged by the area ownerNew issue has not been triaged by the area owner
on Feb 20, 2020 - addedapi-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementation
on Feb 20, 2020 in progress ... woot !
- addedapi-approvedAPI was approved in API review, it can be implementedAPI was approved in API review, it can be implementedand removedapi-suggestionEarly API idea and discussion, it is NOT ready for implementationEarly API idea and discussion, it is NOT ready for implementation
on May 11, 2020 - changed the title
[-]System.Text.Json option to ignore default values in serialization & deserialization[/-][+]System.Text.Json option to ignore default values during serialization[/+]on May 11, 2020 Currently, with
WhenWritingDefault, it doesn't serialize, for instance,inttype with the default value. There's should be an option to skip nullable types but still serialize non-nullable types. I don't need to receive anything in JSON that isnullbut I do want to receive fields with values of0. In JavaScript apps, having somethingundefinedor0makes a big difference. In a nutshell,WhenWritingDefaultmakesintfields of0to becomeundefinedin JavaScript client. For now, I useint?instead ofintas a workaround which is not a good solution.Reacted by Loïc SharmaI ran into the same issue as @rubo when updating my app to .NET 5. The current
JsonIgnoreCondition.WhenWritingDefaultis a breaking change that feels a little too strong. Would it be possible to add aJsonIgnoreCondition.WhenNullthat skipsnullvalues but writes defaults like0andfalse? This comment indicates thatJsonIgnoreCondition.WhenNullwas removed - why is that?For context, my app implements the NuGet protocol. This protocol requires some integer and boolean properties even if they have default values (for example, the search API must return a
downloadsvalue even if a package has 0 downloads). However, this protocol also has optional properties that should be omitted if they have a value ofnull(for example, the package metadata API should omit thedeprecationproperty if a package is not deprecated). AddingJsonIgnoreAttributes everywhere as needed is rather inconvenient.@rubo, @loic-sharma this will be addressed with #39152.
Reacted by Ruben BuniatyanReacted by Loïc Sharma and Karthick T- ghost locked as resolved and limited conversation to collaborators
on Dec 12, 2020
Updated by @layomia. I'm pasting the API approved in #35649, along with API review notes. An option to ignore defaults on deserialization was not added, as we couldn't identify a reasonable scenario that requires this. This proposal does not include a way to specify a custom default. This is discussed in #36236.
Video
WhenWritingDefaultValuestoWhenWritingDefault.JsonSerializerOptions.DefaultIgnoreConditionshould throwArgumentExceptionrather thanInvalidOperationExceptionOriginal proposal (click to view)
There is no option to ignore the
DefaultValuesfor the properties inSystem.Text.Json.The
JSON.NETcontains this options to ignore default values.https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_DefaultValueHandling.htm
Usecase scenario:
For updating the Blazor component model, need to send the values which has only changes to component and refresh the UI, even for initial rendering of component itself, we will the default values.