I have a type that I don't control with multiple constructors, equivalent to this one:
public class MyClass
{
private readonly string _property;
private MyClass()
{
Console.WriteLine("We don't want this one to be called.");
}
public MyClass(string property)
{
_property = property;
}
public MyClass(object obj) : this(obj.ToString()) {}
public string Property
{
get { return _property; }
}
}
Now when I try to deserialize it, the private parameterless constuctor is called and the property is never set. The test:
[Test]
public void MyClassSerializes()
{
MyClass expected = new MyClass("test");
string output = JsonConvert.SerializeObject(expected);
MyClass actual = JsonConvert.DeserializeObject<MyClass>(output);
Assert.AreEqual(expected.Property, actual.Property);
}
gives the following output:
We don't want this one to be called.
Expected: "test"
But was: null
How can I fix it, without changing the definition of MyClass
? Also, this type is a key deep in the definition of the objects that I really need to serialize.
Implement deserialization by doing the following steps in the Read () method: Parse JSON into a JsonDocument. Get the properties needed to call the parameterized constructor. Create the object with the parameterized constructor. Set the rest of the properties.
When your class has multiple constructors, you can use the JsonConstructor attribute to specify which constructor to use during deserialization. Here’s an example: Note: JsonConstructor for System.Text.Json was added in .NET 5. This shows that it used the Person (int luckyNumber) constructor.
When you use System.Text.Json indirectly in an ASP.NET Core app, some default behaviors are different. For more information, see Web defaults for JsonSerializerOptions. By default, all public properties are serialized. You can specify properties to ignore. By default, JSON is minified. You can pretty-print the JSON.
By default, all public properties are serialized. You can specify properties to ignore. The default encoder escapes non-ASCII characters, HTML-sensitive characters within the ASCII-range, and characters that must be escaped according to the RFC 8259 JSON spec. By default, JSON is minified.
Try adding the [JsonConstructor]
attribute to the constructor you want to use when deserializing.
Change this property in your class:
[JsonConstructor]
public MyClass(string property)
{
_property = property;
}
I have just tried it and your test passes :-)
If you can't make this change then I guess you'd need to create a CustomJsonConverter
. http://james.newtonking.com/json/help/index.html?topic=html/CustomJsonConverter.htm and How to implement custom JsonConverter in JSON.NET to deserialize a List of base class objects? might help.
Here is a useful link for creating a CustomJsonConverter
: https://stackoverflow.com/a/8312048/234415
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With