-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Remove DisallowNull annotation in JsonConverter.Write() #35022
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,8 +74,7 @@ internal sealed override bool TryWriteAsObject(Utf8JsonWriter writer, object? va | |
// Provide a default implementation for value converters. | ||
internal virtual bool OnTryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions options, ref WriteStack state) | ||
{ | ||
// TODO: https://github.com/dotnet/runtime/issues/32523 | ||
Write(writer, value!, options); | ||
Write(writer, value, options); | ||
return true; | ||
} | ||
|
||
|
@@ -254,8 +253,7 @@ internal bool TryWrite(Utf8JsonWriter writer, T value, JsonSerializerOptions opt | |
|
||
int originalPropertyDepth = writer.CurrentDepth; | ||
|
||
// TODO: https://github.com/dotnet/runtime/issues/32523 | ||
Write(writer, value!, options); | ||
Write(writer, value, options); | ||
VerifyWrite(originalPropertyDepth, writer); | ||
|
||
return true; | ||
|
@@ -409,6 +407,6 @@ internal void VerifyWrite(int originalDepth, Utf8JsonWriter writer) | |
/// <param name="writer">The <see cref="Utf8JsonWriter"/> to write to.</param> | ||
/// <param name="value">The value to convert.</param> | ||
/// <param name="options">The <see cref="JsonSerializerOptions"/> being used.</param> | ||
public abstract void Write(Utf8JsonWriter writer, [DisallowNull] T value, JsonSerializerOptions options); | ||
public abstract void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have tests that pass in null successfully? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have some for for cases where the type to convert is a struct - https://github.com/dotnet/runtime/blob/cc132d790af6a5971925ef476d9411b251e91cfe/src/libraries/System.Text.Json/tests/Serialization/CustomConverterTests.NullValueType.cs. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. It'd be good to have null tests for both value types and reference types. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Null strings use this path. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any special guidance for using these attributes on abstract or non-sealed types\members? A derived class, for example, may want\need different behavior. Is it OK to place [DisallowNull] on an abstract base class but then still allow null and use a nullable Type (like we do in the String converter). |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure we want to go ahead with this change without the accompanying #34439?
See #32186 (comment)
Would existing converters that don't currently check for null input need to be fixed up to handle that?
The StringConverter is explicitly annotated to allow nullable string. Do we have other examples?
runtime/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Converters/Value/StringConverter.cs
Line 7 in c27376e
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so. Even without that, the String converter gets passed null (any internal converter that uses a reference type). Does it make sense to have
DisallowNull
since we override the behavior internally?Also, for converter composition where one converter calls another converter there may be a desire to pass null as the value -- especially if the target converter does something special with null.
There is no behavior change with the PR. When #34439 is implemented, null will not be passed to any converters (except internal) unless they opt-in through the new virtual method.