Closed rcdailey closed 1 year ago
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis See info in area-owners.md if you want to be subscribed.
Author: | rcdailey |
---|---|
Assignees: | - |
Labels: | `area-System.Text.Json` |
Milestone: | - |
Unless I'm missing something, I think your modifiers are causing the properties to be serialized.
They don't have the attribute, so HasAttribute
would return false
and you say to serialize iif it's false
Ok that's interesting. I thought the ShouldSerialize
property supplemented the existing conditions like whether or not a property is null. So I am overriding that setting? How do I make ShouldSerialize
only kick in after the other logic has been checked? I do not want to overwrite previous logic.
I might be wrong. I'm not sure of the exact rules... Just an observer and that's what popped out at me
I verified that you are right. I commented out the modifiers and it worked just fine. I don't fully understand how I'm supposed to update the Modifiers without breaking the rest of the logic. I migrated from Newtonsoft.Json recently and so far I'm finding System.Text.Json much more confusing and frustrating to use.
For now, I modified my logic to this and I think it works:
public static class JsonSerializationModifiers
{
public static void IgnoreNoSerializeAttribute(JsonTypeInfo type)
{
var propertiesToRemove = type.Properties
.Where(x => x.AttributeProvider?.IsDefined(typeof(JsonNoSerializeAttribute), false) ?? false)
.ToList();
foreach (var prop in propertiesToRemove)
{
prop.ShouldSerialize = (_, _) => false;
}
}
}
It's still really confusing, though. Maybe one of the devs can drop in to clarify the behavior and how this should be done.
@pinkfloydx33 is right, JsonIgnoreConditionAttribute
declarations get mapped to the ShouldSerialize
delegate, so overwriting that would result in these being lost. You could try chaining the old delegate with your custom logic like so:
var shouldSerialize = prop.ShouldSerialize;
prop.ShouldSerialize = (obj, value) => shouldSerialize?.Invoke(obj, value) != false && MyCustomLogic(obj, value);
Description
When serializing types that have properties set to
null
, those properties still get serialized out withnull
values instead of being omitted.Reproduction Steps
I don't have steps and I struggled to reproduce this in a simple MCVE, so I'm just going to link to my open source project. I created a branch named
json-serializing-nullable-fields-issue
that demonstrates the issue. You can look at the diff to see the new unit test I introduced that you can run to repro the issue.See the test named
DemoNullableNotWorking()
(below):If you inspect
boxed
in your debugger, you'll see the entire serialized JSON string. Look at the"items"
array for an element like this:Link to my repo and the relevant test file is below:
https://github.com/recyclarr/recyclarr/blob/json-serializing-nullable-fields-issue/src/tests/Recyclarr.Cli.Tests/Pipelines/QualityProfile/PipelinePhases/QualityProfileConfigPhaseTest.cs#L274
Expected behavior
Properties
"id"
and"name"
should not be serialized because they arenull
.Actual behavior
Null values are serialized when they shouldn't be.
Regression?
No response
Known Workarounds
No response
Configuration
.NET 7
Other information
No response