2017-07-07 3 views
0

J'utilise des bibliothèques Newtonsoft pour la sérialisation et la désérialisation de l'objet json. Le code de référence est ci-dessous:Valeur de chaîne de désérialisation JSON à la liste <T> en utilisant Newtonsoft - Constructeur arg est null en C#

public abstract class BaseNode 
{ 
    [JsonConstructor] 
    protected BaseNode(string [] specifications) 
    { 
     if (specifications == null) 
     { 
      throw new ArgumentNullException(); 
     } 
     if (specifications.Length == 0) 
     { 
      throw new ArgumentException(); 
     } 

     Name = specifications[0]; 
     Identifier = specifications[1]; 
     //Owner = specifications[2]; 
    } 

    public string Name{ get; protected set; } 
    public string Identifier { get; protected set; } 
    public string Owner { get; protected set; } 
} 


public class ComputerNode: BaseNode 
{ 
    [JsonConstructor] 
    public ComputerNode(string[] specifications):base(specifications) 
    { 
     Owner = specifications[2]; 
    } 
} 

sérialisation fonctionne très bien et je peux enregistrer les données au format JSON dans un fichier. Je stocke une liste d'objets ComputerNode dans un fichier. code suivant pour le fichier opération de lecture/écriture:

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

     File.WriteAllText(path, ser); 
    } 

    public List<T> Read(string path) 
    { 
     var text = File.ReadAllText(path); 

     var res = JsonConvert.DeserializeObject<List<T>>(text); 
     return res; 
    } 

} 

Le fichier résultat escompté Lire devrait être une liste d'objets ComputerNode stockés dans un fichier. Cependant, lors de la désérialisation - création d'un objet de ComputerNode, le constructeur correct est appelé mais l'argument (string [] specifications) est null.

Existe-t-il une meilleure façon de travailler avec.

S'il vous plaît ne pas suggérer de changer BaseNode.cs ou ComputerNode.cs

Merci pour la suggestion ...

réponse correcte

outrepassée avec nouveau constructeur JSON. Dans BaseNode.cs

[JsonConstructor] 
    public BaseNode(string Owner, string Name, string Identifier) 
    { 
     this.Name = Name; 
     this.Identifier = Identifier; 
    } 

et un constructeur OPPOSER JSON - ComputerNode.cs

[JsonConstructor] 
    public ComputerNode(string Owner, string Name, string Identifier):base(Owner, Name, Identifier) 
    { 
     this.Owner = Owner; 
    } 
+0

À quoi ressemble votre JSON? Je ne vois pas pourquoi vous auriez besoin de ceux-ci passés dans le constructeur lors de la désérialisation d'un objet JSON de structure de puits. Il devrait juste peupler les propriétés comme vous vous y attendiez. – Skintkingle

+0

[ { "Nom": "jack", "Identifier": "123345", "Propriétaire": "CiiW" }, { "Nom": "didi", "Identifier": " 1dd123345 ", " Propriétaire ":" C12W " } ] – JayeshThamke

+0

Désolé, il n'a pas ajouté d'indentation dans l'éditeur SO. – JayeshThamke

Répondre

1

https://stackoverflow.com/a/23017892/34092 états:

Il est important que les noms des paramètres du constructeur correspondent aux noms de propriétés correspondant de l'objet JSON pour que cela fonctionne correctement .

Votre paramètre constructeur est appelé specifications. Il n'y a aucune propriété dans le JSON avec le nom de specifications. C'est pourquoi la valeur est passée comme nulle. Voir aussi http://www.newtonsoft.com/json/help/html/JsonConstructorAttribute.htm.

0

dans la pratique si vous exécutez

var ser = JsonConvert.SerializeObject(nodes); 
File.WriteAllText(path, ser); 

où les nœuds est une liste < T>

puis

var text = File.ReadAllText(path); 
var res = JsonConvert.DeserializeObject<List<T>>(text); 

où res est une liste < T>

Selon la documentation JsonConstructor: http://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_JsonConstructorAttribute.htm

charge la JsonSerializer d'utiliser le constructeur spécifié lors de désérialisation cet objet.

Non où il est dit qu'il y aura un paramètre constructeur lié à la chaîne à désérialiser.

en fait le constructeur que vous avez désigné ([JsonConstructor]) essayer de passer outre le résultat de la désérialisation avec Dans votre cas paramètre

toujours null, vous devriez avoir

[JsonConstructor] 
protected BaseNode() 
{ 

} 

pour éviter le constructeur sur l'interaction avec la désérialisation.À mon humble avis, le désérialiseur ne donnera jamais (selon la documentation) un paramètre à un constructeur.