2010-11-29 3 views
1

J'ai un objet graphique que j'ai besoin de sérialiser. Nomatter que les membres i Implement, la méthode renvoie {}Impossible d'appeler JavascriptSerialize dans la classe personnalisée

string json = new JavascriptSerializer().Serialize(routeGraph); 

Voici ma classe graphique:

namespace GraphClass 
{ 
    [Serializable, DataContract] 
    public class Graph : ISerializable 
    { 
     [DataMember] 
     readonly Dictionary<string, Node> nodeMap = new Dictionary<string, Node>(); 
     [DataMember] 
     private Tuple<string, string, double> bufferOriginalOffer; 
    } 
    [Serializable, DataContract] 
    public class Node : ISerializable 
    { 
     [DataMember] 
     public string Name { get; private set; } 
     [DataMember] 
     public List<Edge> Adj { get; private set; } 
     [DataMember] 
     public Node Prev { get; set; } 
     [DataMember] 
     public double Distance { get; set; } 
    [Serializable, DataContract] 
    public class Edge : IComparable, ISerializable 
    { 
     [DataMember] 
     public Node Destination { get; private set; } 
     [DataMember] 
     public double Cost { get; set; } 
     [DataMember] 
     public double Time { get; set; } 
    } 
    [Serializable, DataContract] 
    public class Tuple<T, T1, T2> : ISerializable 
    { 
     [DataMember] 
     public T Item1 { get; set; } 
     [DataMember] 
     public T1 Item2 { get; set; } 
     [DataMember] 
     public T2 Item3 { get; set; } 
    } 
} 

J'ai essayé pendant toute une journée, pour sérialiser ce soit JSON ou XML, comme je devez envoyer l'objet à un webservice.

MISE À JOUR: Utilisé DataContractJsonSerialiser à la place. Je reçois l'erreur suivante:

Object graph for type 'GraphClass.Edge' contains cycles and cannot be serialized if reference tracking is disabled. 

Comme vous pouvez le voir dans la classe Node, un nœud peut contenir une liste des arêtes. Je ne sais pas comment corriger l'erreur.

Répondre

4

Avez-vous eu l'intention d'utiliser DataContractJsonSerializer? C'est plus axé sur les données-contrat; JavascriptSerializer ne se soucie pas vraiment du tout sur les données-contrats - il suffit de regarder le type meta.

Graph Seuls les champs privés; JavascriptSerializer ne regarde que les membres publics. Ajouter une propriété publique pour nodeMap, peut-être?

Notez que [Serializable] ne fait rien ici, et les types ne mettent pas en œuvreISerializable etc, malgré prétendre.


Edit: a confirmé ce qui suit semble fonctionner OK:

DataContractJsonSerializer ser = new DataContractJsonSerializer(graph.GetType()); 
string s; 
using(var ms = new MemoryStream()) { 
    ser.WriteObject(ms, graph); 
    s = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length); 
} 
Console.WriteLine(s); 

et ce qui suit semble fonctionner après avoir ajouté une propriété:

public Dictionary<string, Node> NodeMap { get { return nodeMap; } } 
... 
JavaScriptSerializer ser = new JavaScriptSerializer(); 
string s = ser.Serialize(graph); 
Console.WriteLine(s); 
+0

Ah, je devrais alors utiliser DataContractJsonSerializer. Mais j'obtiens cette erreur: Le graphe d'objet pour le type 'GraphClass.Edge' contient des cycles et ne peut pas être sérialisé si le suivi de référence est désactivé. Si j'utilise JavascriptSerializer, j'obtiens cette erreur: Une référence circulaire a été détectée lors de la sérialisation d'un objet de type Graph.Node – CasperT

+1

Les graphes @CasperT avec des boucles sont difficiles à sérialiser. Je ne peux pas diagnostiquer sans plus de détails cependant. –

+0

Vous ne savez pas ce que vous entendez par boucles, car c'est une infrastructure de données. Les nœuds peuvent contenir 1 ... * Bords, si c'est ce que vous voulez dire. De quels détails avez-vous besoin? – CasperT

0

Je crois que Marc est exactement ici. JavaScriptSerializer crée des graphes Json basés sur les propriétés publiques d'un objet; dont votre classe Graph n'a pas. Pour utiliser les fonctionnalités DataContract, vous avez besoin de DataContractJsonSerializer.

Questions connexes