I need to serialize some custom objects in order to store information. However, I am struggling to deserialize those objects from the serialized JSON string back into their orig
Your classes MyClass2
and MyClass3
are read-only. In order for Json.NET to deserialize a read-only type, you must either provide a custom JsonConverter that manually deserializes and constructs an instance of the type, or provide a parameterized constructor whose argument names match the property names modulo case. You have already created the necessary constructors and so are halfway done.
However your types have parameterless constructors as well. So, which constructor does Json.NET call? For a non-enumerable type that is serialized to a JSON object, the following rules apply:
If [JsonConstructor] is set on a constructor, use that constructor.
Next, in full trust only, when MemberSerialization.Fields
is applied, or [Serializable]
is applied and DefaultContractResolver.IgnoreSerializableAttribute == false, the special method FormatterServices.GetUninitializedObject() is used to allocate the object. None of the type's constructors are called.
(This is an unusual case that does not arise often.)
Next, if there is a public parameterless constructor, use it.
Next, if a private parameterless constructor exists and the setting ConstructorHandling.AllowNonPublicDefaultConstructor is enabled, the private parameterless constructor is used.
Next, if there is a single public parameterized constructor, use that constructor.
Failing all of the above, Json.NET cannot construct instances of the type. An exception will get thrown during deserialization unless a custom converter is available.
Thus the parameterless constructors take precedence over the parameterized constructors. To force the parameterized constructors to be used, mark them with [JsonConstructor]
as mentioned above:
public class MyClass3
{
private Regex _myRegex;
private string _myString = null;
public MyClass3() { }
[JsonConstructor]
// The argument names must match the property names modulo case for Json.NET to deserialize the properties successfully.
public MyClass3(string myString, Regex myRegex)
{
_myString = myString;
_myRegex = myRegex;
}
public string MyString { get { return _myString; } }
public Regex MyRegex { get { return _myRegex; } }
}
Alternatively, you could eliminate the parameterless constructor as it apparently did not exist in the first version of your question. Then make the same change to MyClass2
. Now your types will deserialize successfully.
Note that Json.NET has a built-in converter for serializing a Regex
.
Sample fiddle.