Feature request: Serialization attributes without adding Json.NET as a dependency
See original GitHub issueAlthough some data contract attributes can be used as substitutes for Json.NET specific attributes, there are some, like [JsonConstructor]
, that requires the Json.NET to be added as a dependency.
Why is this a problem?
Most core/dto/model/etc projects tend to expose types that are required to be serializable without doing any serialization themselves. This makes adding a serialization library as a dependency redundant since many of these types can get away with using the data contract attributes. Data contract attributes can be found in this lightweight, System.Runtime.Serialization.Primitives package and are already included in the full .NET framework.
So if I were to create a library with a class that has multiple constructors and want my users to be able to serialize it using Json.NET, I need to depend on Json.NET because I need the [JsonConstructor]
. This is an unnecessary dependency for my users that don’t use Json.NET and an even worse one for my users that do, because now they need to wait for me to update my library in order to update their Json.NETs.
What can be done?
Json.NET can compare attribute names instead of doing full type checks. For example, this line in the DefaultContractResolver
can check if the constructor has an attribute named “JsonConstructor” without minding which assembly it comes from, so the users can create and use their own [JsonConstructor]
s. I’ve seen this approach work with ReSharper annotations and some Redgate utilities.
Unfortunately, [JsonConstructor]
is the only Json.NET specific attribute I know that doesn’t accept a parameter. Letting the users define their own attributes would involve more reflection for attributes like [JsonObject]
.
One other option I can think of is the .NET route. The attributes can be refactored into another package (e.g. Newtonsoft.Json.Primitives) that is also a dependency of the Json.NET itself. Consisting only of annotations, it can have a much slower release cycle while being considerably smaller in size.
What should be done?
I think reading the properties of a user-defined attribute via reflection (each time, or by using cached expression trees) may increase the project’s complexity a little too much, and introducing a new dependency in the form of a primitives package may be considered overkill.
Allowing user-defined [JsonConstructor]
s, on the other hand, seem easy enough and that is the one Json.NET specific attribute I find myself using the most (To compare, I needed to use the [JsonObject]
only once in my life). For me, the only thing that the data contract attributes lack is a way to choose a constructor. It is somewhat understandable though, since the DataContractSerializer
does not call any constructor.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:2
- Comments:6
I faced the same problem, so I’d like to share my 5 cents here. If your objects are immutable, they don’t have a parameterless constructor, but they often have a constructor that accepts all or some of the property values. In this case, it would be nice if we can instruct JSON.NET to use the most specific constructor available without adding any attributes. E.g. it can be done by adding a new value to the
ConstructorHandling
enumeration.@safakgur yes, my bad It doesn’t work if there are several constructors with parameters.
Right now the desired behavior can be achieved by using a custom ContractResolver:
Usage: