-
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
Support modifying (rather than replacing) already-initialized properties and fields when deserializing #30258
Comments
It doesn't sound well. Actually, I don't think that a lot people will use the new serializer due to limitations. But others who will use it, mostly won't see this as a breaking change. |
From @chenyj796 in https://github.com/dotnet/corefx/issues/41433
|
Hi @steveharter, I'm not sure if related to this particular issue but I noted down an issue with array deserialization here: dotnet/corefx#39442 (comment) |
This is a necessary feature for folks wanting to serialize protobuf. Example:
Protobuf code generator will generate the equivalent of:
The expected behavior (and newtonsoft's behavior) would be to call the initializers to populate the data. For example I would expect It's unexpected, especially when a serializer option Perhaps add a Am I correct in understanding you don't intend to fix/enhance this until .net 5.0 is out in a year or so? |
If anyone else is being affected by this, consider a converter in the meantime. Here's one I just made since discovering the issue:
And it's been extensively tested with these industry-standard unit tests featuring breakpoint + mouse-hover debugging assertions:
It's a read-only converter (it doesn't serialize, just deserialize). Anyway, just dumping it in case it helps. We'll be implementing and testing ours in earnest in the days to come. Happy to share refinements if anyone needs it, but this is essentially a hacky workaround until a feature shows up, so it'd never be fully featured. |
Any updates on the roadmap for this. Any idea on when this could be released? |
This is still a valid issue; it just hadn't been prioritized for 5.0 (yet). Strawman proposal:
The attribute and option would likely be an enum similar to https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_ObjectCreationHandling.htm (Auto, Reuse, Replace) except that the default would be Note this attribute works on objects as well as collections. For the re-use cases, I don't think we ever want to attempt to call a "Clear" method on collections (we always append). |
With the behaviour as of now we actually need to suppress CA2227 for collections in our DTOs we want to deserialize into. So the out of the box coding standards actually prevent usage of the Deserializer ... From where I'm standing an additional JsonSerializerOption would probably be the best way to proceed. |
From @dbc2 in #32197 (comment):
|
This work should also consider sub-objects without setters, not just collections.
|
From @componentspace in #35388:
|
Would really love to be able to follow .net design guidelines for collections to not have settable collection properties. Strongly believe this should be the default behavior. XAML supported save/load of objects like this w/o needing the setter or any extra attribute. |
|
Collection properties should be read only https://docs.microsoft.com/en-gb/visualstudio/code-quality/ca2227 Suppress FxCopAnalyzers warning CA2227 as System.Text.Json.JsonSerializer.Deserialize in .NET Core 3.1 cannot deserialise to read-only properties. There are two related issues that will allow System.Text.Json.JsonSerializer.Deserialize to deserialise to read-only properties in .NET Core 5.0: 1) Pull Request that includes support for non-public accessors: dotnet/runtime#34675 2) Issue regarding, among other things, adding to collections during deserialisation if the collection property has no setter: dotnet/runtime#30258
Updating the title here to generalize this to a problem where we need to modify an already initialized property or field. An equivalent to |
From @mtaylorfsmb in #39630:
|
Related to grpc/grpc-dotnet#167 |
Something to consider with this feature is adding var user = new User();
JsonSerializer.Populate(json, user.Roles); https://www.newtonsoft.com/json/help/html/PopulateObject.htm Usage in the real world: https://cs.github.com/?q=jsonconvert.populateobject+language%3AC%23&p=1&scopeName=All+repos |
There's a thread for that already, created just a couple of months before a post I added at StackOverflow |
FWIW it will be possible to partially address this with #63686 - you will be able to use My initial prototype had callback to address this specific scenario exactly but it needs more design as it wouldn't work with async + some other tiny issues so for now at least this will make life slightly easier |
How so? Wouldn't it be possible to (roughly) do something like the following in the object converter // inside the property deserialization loop of ObjectConverter
if (jsonPropertyInfo.ReuseInitializedValue && jsonPropertyInfo.Get(parentObject) is object initializedValue)
{
state.Current.ReturnValue = initializedValue; // signal to the converter of the property type that the type has been initialized.
} |
We're moving this to 8.0. We should prioritize this in 8.0 period though. Per my offline conversation with @JamesNK lack of this will make deserializing collections in gRPC inefficient but we're ok with moving this work to next release while we focus on polishing up current contract customization design. |
I'm unassigning myself since I don't work on this now and we don't have specific plans for 8.0 yet |
I'm closing this issue in favor of #78556 - anyone interested please share your thoughts below so that we can adjust proposal if needed. |
Per comment in https://github.com/dotnet/corefx/issues/38435#issuecomment-504686914 and the original design before "replace" semantics in dotnet/corefx#39442 was added is to allow a collection to:
The existing semantics ignore the property on deserialization.
To turn on this mode, a custom attribute could be created to enable and placed on the property, and\or a global option. Doing this by default would be a breaking change (if added post 3.0).
cc @JamesNK @YohDeadfall
The text was updated successfully, but these errors were encountered: