2014-06-16 6 views
7

Ich muss JSer für folgende Klasse deserialize.Deserialize json in C# -Objekt für Klasse, die privaten Standardkonstruktor hat

public class Test 
{ 
    public string Property { get; set; } 

    private Test() 
    { 
     //NOTHING TO INITIALIZE 
    } 

    public Test(string prop) 
    { 
     Property = prop; 
    } 
} 

Ich kann eine Instanz von Test erstellen wie

var instance = new Test("Instance"); 

sichts meiner json so etwas wie

"{ "Property":"Instance" }" 

Wie soll ich ein Objekt der Klasse Test erstellen als Standard-Konstruktor privat ist und Ich bekomme Objekt, wo Eigenschaft 0 ist

Ich benutze Newtonsoft Json Parser.

+0

Welche Bibliothek verwenden Sie? Wie bekommst du eine Instanz von 'Test'? –

+0

Wenn es keine Factory gibt, die ein 'Test'-Objekt generiert, wie erwarten Sie dann, ein JSON in eine Instanz davon zu deserialisieren? –

Antwort

22

können Sie machen Json.Net den privaten Konstruktor aufrufen, indem Sie es mit einem [JsonConstructor] Attribut Kennzeichnung:

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

Beachten Sie, dass der Serializer noch die öffentlichen Setter verwenden wird das Objekt nach dem Aufruf der Konstruktor zu füllen.

EDIT

Eine weitere mögliche Option ist die ConstructorHandling Einstellung zu verwenden:

JsonSerializerSettings settings = new JsonSerializerSettings 
{ 
    ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor 
}; 

Test t = JsonConvert.DeserializeObject<Test>(json, settings); 
+2

Die zweite Option ist die beste, wenn das Objekt, das Sie serialisieren möchten, in einer Bibliothek/Assembly ist, in die Sie keine Abhängigkeiten von Drittanbietern einführen möchten (einschließlich Abhängigkeiten zu Json.Net ...) –

2

Es scheint nicht, wie Sie zusätzliche Schritte ergreifen müssen.

Mit Json.NET v6.0.8, das folgende C# Programm funktioniert innerhalb 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; 
    } 
} 
+0

Beispiel für ein Bit-modifiziertes Beispiel online: https://dotnetfiddle.net/4qFumV – Maxim

0

keine Notwendigkeit, eine Serializer Einstellung zu erstellen und assign gibt hier ConstructorHandling. Bitte denken Sie daran, das Attribut [JsonConstructor] für den privaten Konstruktor zu definieren. Ich habe ähnlichen Fall mit abstrakten BaseNode.cs und seine konkrete Implementierung von ComputerNode.cs. Sie können die Klassen erstellen, den folgenden Code kopieren und einfügen und etwas experimentieren.

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]; 
    } 
} 

Für JSon Lesen und Schreiben folgenden Code hilft -

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; 
    } 

} 

Alles Gute!