I have a class myClass
which I have recently refactored. Originally, it contained properties string Category
and string Value
, and serialized as
{
"Category": "someCategory",
"Value": "someValue"
}
After refactoring, it now contains properties Signature Sig
and ExtraData Data
, where Signature
is a class containing the original properties string Category
and string Value
, so it deserializes as
{
"Sig":{
"Category": "someCategory",
"Value": "someValue"
},
"ExtraData": { ... large set of additional data here}
}
myClass
is a shared class used extensively throughout my program, usually in the context of List<myClass>
, and is serialized as part of saving several different types of larger overarching settings classes. When I try to deserialize these settings files using the updated class definition, the deserializer (of course) fails to deserialize the existing string, resulting in empty lists that had previously been populated.
I am wondering if it's possible to implement the following logic using a JsonConverter
or ContractResolver
(pseudocode)
///jsonString here should be the fragment of the larger json file containing just the current object
myclass attempt = JsonConvert.DeserializeObject<myClass>(jsonString);
if (attempt == null) // or whichever method is best to determine deserialization success
{
Signature attempt2 = JsonConvert.DeserializeObject<Signature>(jsonString);
if (attempt2 != null)
{
myClass converted = new();
converted.Sig = attempt2;
return converted;
}
else
{
return null; // or whatever behavior is used to skip populating the list
}
}
else
{
return attempt; // from a settings file which had already been upgraded
}
I tried implementing a JsonConverter
but got stuck on the ReadJson()
function at object value = reader.Value;
- it seemed like value
was only generated one line at a time (e.g. in my case as "Category": "someCategory"
) instead of the entire object, so I couldn't deserialize it to a Signature
class as it only contained half of the required data.
Is there a way to implement the desired behavior?
CodePudding user response:
I usually use a JsonConstructor in this case, it will properly deserialize both of your jsons.
MyClass myClass = JsonConvert.DeserializeObject<MyClass>(json);
public class MyClass
{
public Sig Sig { get; set; }
public ExtraData ExtraData { get; set; }
[JsonConstructor]
public MyClass(Sig Sig, string Category, string Value)
{
if (Sig != null) this.Sig = Sig;
else
{
this.Sig = new Sig
{
Category = Category,
Value = Value
};
}
}
public MyClass() {}
}
public class Sig
{
public string Category { get; set; }
public string Value { get; set; }
}
public class ExtraData
{
}