Deserialize json to a C # object for a class that has its own default constructor

I need to deserialize json for the next class.

public class Test { public string Property { get; set; } private Test() { //NOTHING TO INITIALIZE } public Test(string prop) { Property = prop; } } 

I can create an instance of Test, for example

 var instance = new Test("Instance"); 

considering my json is something like

 "{ "Property":"Instance" }" 

How to create an object of class Test, since my default constructor is private, and I get an object where Property is NULL

I am using the Newtonsoft Json parser.

+7
json c # serialization
source share
3 answers

You can force Json.Net to call the private constructor by marking it with the [JsonConstructor] attribute:

 [JsonConstructor] private Test() { //NOTHING TO INITIALIZE } 

Note that the serializer will still use public setters to populate the object after calling the constructor.

EDIT

Another possible option is to use the ConstructorHandling parameter:

 JsonSerializerSettings settings = new JsonSerializerSettings { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; Test t = JsonConvert.DeserializeObject<Test>(json, settings); 
+23
source share

You don't seem to need to take any extra steps.

Using Json.NET v6.0.8, the following C # program works in LINQPad:

 void Main() { var o = JsonConvert.DeserializeObject<Test>("{\"Property\":\"Instance\"}"); Debug.Assert(o.Property == "Instance", "Property value not set when deserializing."); } public class Test { public string Property { get; set; } private Test() { } public Test(string propertyValue) { Property = propertyValue; } } 
+2
source share

No need to create Serializer settings and assign ConstructorHandling here. Remember to specify the [JsonConstructor] attribute for the private constructor. I have a similar case with the abstract BaseNode.cs and its specific implementation of ComputerNode.cs. You can create classes, copy / paste the code below and conduct an experiment.

  public abstract class BaseNode { [JsonConstructor] // ctor used when Json Deserializing protected BaseNode(string Owner, string Name, string Identifier) { this.Name = Name; this.Identifier = Identifier; } // ctor called by concrete class. protected BaseNode(string [] specifications) { if (specifications == null) { throw new ArgumentNullException(); } if (specifications.Length == 0) { throw new ArgumentException(); } Name = specifications[0]; Identifier = specifications[1]; } public string Name{ get; protected set; } public string Identifier { get; protected set; } } public class ComputerNode: BaseNode { public string Owner { get; private set; } [JsonConstructor] // not visible while creating object from outside and only used during Json Deserialization. private ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier) { this.Owner = Owner; } public ComputerNode(string[] specifications):base(specifications) { Owner = specifications[2]; } } 

For JSon, reading and writing code helps -

  public class Operation<T> { public string path; public Operation() { var path = Path.Combine(Directory.GetCurrentDirectory(), "nodes.txt"); if (File.Exists(path) == false) { using (File.Create(path)) { } } this.path = path; } public void Write(string path, List<T> nodes) { var ser = JsonConvert.SerializeObject(nodes, Formatting.Indented); File.WriteAllText(path, ser); } public List<T> Read(string path) { var text = File.ReadAllText(path); var res = JsonConvert.DeserializeObject<List<T>>(text); return res; } } 

All the best!

0
source share

All Articles