-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
STJ: Support serialization callbacks for collection and dictionary types #104120
base: main
Are you sure you want to change the base?
Conversation
value = (TCollection)state.Current.ReturnValue!; | ||
|
||
jsonTypeInfo.OnDeserialized?.Invoke(value); |
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.
If TCollection
is a struct this would result in the value being boxed again and potentially breaking user callback that depend on the same reference being passed to the callback.
value = (TCollection)state.Current.ReturnValue!; | |
jsonTypeInfo.OnDeserialized?.Invoke(value); | |
object result = state.Current.ReturnValue!; | |
value = (TCollection)result; | |
jsonTypeInfo.OnDeserialized?.Invoke(result); |
state.Current.JsonPropertyInfo = state.Current.JsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo; | ||
state.Current.JsonPropertyInfo = jsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo; | ||
|
||
jsonTypeInfo.OnSerializing?.Invoke(value); |
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.
Nit: I would move the callback before the first JSON gets written to the underlying writer.
value = (TDictionary)state.Current.ReturnValue!; | ||
|
||
jsonTypeInfo.OnDeserialized?.Invoke(value); |
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.
Likewise
value = (TDictionary)state.Current.ReturnValue!; | |
jsonTypeInfo.OnDeserialized?.Invoke(value); | |
object result = state.Current.ReturnValue!; | |
value = (TDictionary)result; | |
jsonTypeInfo.OnDeserialized?.Invoke(result); |
state.Current.JsonPropertyInfo = state.Current.JsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo; | ||
state.Current.JsonPropertyInfo = jsonTypeInfo.ElementTypeInfo!.PropertyInfoForTypeInfo; | ||
|
||
jsonTypeInfo.OnSerializing?.Invoke(dictionary); |
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.
Likewise, I would invoke the callback before metadata or the start object token get written to the wire.
@@ -153,7 +153,7 @@ internal JsonTypeInfo(Type type, JsonConverter converter, JsonSerializerOptions | |||
{ | |||
VerifyMutable(); | |||
|
|||
if (Kind != JsonTypeInfoKind.Object) | |||
if (Kind == JsonTypeInfoKind.None) |
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.
In the unlikely case that new kinds get added in the future, I would probably just turn this into an explicit check:
if (Kind == JsonTypeInfoKind.None) | |
if (Kind is not (JsonTypeInfoKind.Object or JsonTypeInfoKind.Enumerable or JsonTypeInfoKind.Dictionary)) |
@@ -419,10 +531,7 @@ public override void Write(Utf8JsonWriter writer, MyValue value, JsonSerializerO | |||
[Fact] | |||
public static void NonPocosIgnored() | |||
{ | |||
JsonSerializer.Serialize(new MyCollection()); |
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.
Could you also add a few tests in MetadataTests.cs that verify that callbacks can be specified via the JsonTypeInfo
APIs?
Closes #71945