-
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
Implicit vs Explicit Null (aka Null vs Not-Set) - JSON and WebAPI Related #53868
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
You could use a wrapper type, and #35649 from preventing it getting written out: [JsonIgnore(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault)]
[JsonConverter(typeof(OptionalConverterFactory))]
public Optional<long?> Parent { get; set; } |
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsBackground and MotivationDear .NET Team, Here is some background on the problem: For example, with the following request:
We can expect a query like this to execute:
And with this request:
We can expect a query like this to execute:
However, in C# today, it takes a lot of special work to ensure that happens. Likely, both requests will result in the same query running. This is because a developer would likely write the following code:
And in the above, there will be no difference at all between what happens regardless of if Parent is null because it was not provided or it is null because it is explicitly set to null. As a result of this, a lot of .NET JSON "Update" APIs require that developers pass in every single property of their object again or risk it being set to null/default(t). To work around this, I have started seeing developers keep track of what properties have had their setters invoked and being smart about only updating those properties. Proposed APIThe .NET Team can greatly simplify this challenge by introducing a new source generator: When applied to a class, code like this:
Becomes:
I hope the above information is clear and that you can see the value in this addition. Alternative DesignsI expect that we will see some developers who will start to interrogate the JSON dom directly once dotnet/designs#163 is fully released. This has the limitation of tying a framework specifically to json and will likely be error prone due to working with magic strings. RisksNone Other NotesThe Json serializer could be enhanced such that if a serialized object implements ITrackSetProperties, it will only serialize set properties instead of all properties.
|
@Joe4evr , while that is possible, that results messy json being written out and necessary. You would essentially have the following:
|
That's not the case if you write the converter properly: |
I personally think that the proposed solution doesn't scale well, and is incredibly awkward to use. However, it is absolutely a scenario that happens often enough that I think System.Text.Json should provide a built-in solution. The Along those lines then, how about something like this? namespace System.Text.Json.Serialization;
public struct Optional<T>
{
public bool IsPresent { get; }
public T Value { get; }
public static Optional<T> NotPresent => default;
public Optional(T value) { throw null; }
public T GetValueOrDefault(T @default) { throw null; }
public static implicit operator Optional<T>(T value) { throw null; }
public static explicit operator T(Optional<T> optional) { throw null; }
// Override Equals, GetHashCode, ToString, equality operators, etc.
} Then, internally, there'd be a built-in converter factory for On the naming of |
@Joe4evr @FiniteReality - Right now, it seems like I have to specify:
on every single property of type
All my code thus far:
|
Hi @TonyValenti, I see you also opened #54269. Am I right to assume that the other issue supersedes this request and if so, should we close this one? |
Is there another way to accomplish this that you can see? Any chance the JsonIgnore enhancement can be wrapped into .net 6x? |
I haven't looked into the details but the JsonIgnore enhancement seems like a reasonable addition. If you agree we should probably just close this one.
It's unlikely at this point given the size of our backlog, sorry. |
It's unlikely that we would implement a construct as proposed in the original post, however offering a means to control ignored property behavior on the type/converter level is certainly something we would consider supporting going forward. Closing this issue in favor of #54269 and related issue requests. |
Background and Motivation
Dear .NET Team,
I do a lot of work in web systems for .NET and I've noticed a common problem that lots of web API developers bump into.
I believe that .net can easily solve this problem via a source generator or some other technology. I am opening this issue with the hope that you will build an official solution that will completely eliminate a significant source of problems and challenges.
Here is some background on the problem:
When building update APIs, there should be a differentiation between a null value and a not-set value.
For example, with the following request:
We can expect a query like this to execute:
And with this request:
We can expect a query like this to execute:
However, in C# today, it takes a lot of special work to ensure that happens. Likely, both requests will result in the same query running. This is because a developer would likely write the following code:
And in the above, there will be no difference at all between what happens regardless of if Parent is null because it was not provided or it is null because it is explicitly set to null. As a result of this, a lot of .NET JSON "Update" APIs require that developers pass in every single property of their object again or risk it being set to null/default(t).
To work around this, I have started seeing developers keep track of what properties have had their setters invoked and being smart about only updating those properties.
Proposed API
The .NET Team can greatly simplify this challenge by introducing a new source generator:
[TrackSetProperties]
When applied to a class, code like this:
Becomes:
I hope the above information is clear and that you can see the value in this addition.
Alternative Designs
I expect that we will see some developers who will start to interrogate the JSON dom directly once dotnet/designs#163 is fully released. This has the limitation of tying a framework specifically to json and will likely be error prone due to working with magic strings.
Risks
None
Other Notes
The Json serializer could be enhanced such that if a serialized object implements ITrackSetProperties, it will only serialize set properties instead of all properties.
@steveharter @jkotas @ericstj
The text was updated successfully, but these errors were encountered: