50 votes

C# automatique des biens de la désérialisation de JSON

J'ai besoin de désérialiser un peu de JavaScript objet représenté en JSON à une classe C#. Étant donné les caractéristiques intéressantes automatique de propriétés, je préfère les avoir dans ces classes plutôt que de simplement avoir des champs. Malheureusement, l' .NET moteur de sérialisation (au moins, par défaut) ignore totalement automatique de propriétés sur la désérialisation et se soucie uniquement de la sauvegarde de champ, qui n'est évidemment pas présent dans l'objet JavaScript.

Étant donné qu'il n'y a pas de méthode standard pour le nom de champs de sauvegarde et pour être honnête, je n'ai même pas envie de s'embêter avec la "nous allons créer un objet JavaScript qui ressemble comme il a C# champs de sauvegarde" comme il sonne un peu sale, la seule façon que je pouvais sérialiser JavaScript champs de C# auto-propriétés si je pouvais forcer la sérialisation moteur en quelque sorte ignorer la sauvegarde et l'utilisation de la propriété directement. Malheureusement, je ne peux pas comprendre comment c'est fait ou si cela peut être fait à tout. Toutes les idées seront les bienvenues.

EDIT: Voici un exemple:

Javascript:

function Cat()
{
    this.Name = "Whiskers";
    this.Breed = "Tabby";
}
var cat = new Cat();

C'est alors sérialisé "{Nom: "Moustaches"}".

La classe C#:

[Serializable()]
public class Cat
{
    public string Name { get; set; }
    public string Breed { get; set; }
}

Et la désérialisation code, qui échoue:

new DataContractJsonSerializer(typeof(Cat)).ReadObject(inputStream);

Et il est évident à partir de l'exception qu'il échoue, car il est à la recherche pour le champ de stockage.

EDIT2: Voici l'exception, si ça peut aider (pas d'exceptions internes):

Système.Moment de l'exécution.La sérialisation.SerializationException

"Le contrat de données type de Test.Chat" ne peut pas être désérialisé parce que le les données requises des membres '<Name>k__BackingField, <Breed>k__BackingField"n'étaient pas trouvé."

80voto

baretta Points 4391

Ce qui se passe ici est la deserializer est d'essayer de deviner le nom de votre champs de sauvegarde. Vous pouvez résoudre ce problème en ajoutant des mappages explicites (DataContract/DataMember attributs) comme ceci:

[DataContract]
public class Cat
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Breed { get; set; }
}

20voto

aleemb Points 12138

Vous pouvez faire cela avec JavaScriptSerializer trouvé dans l' System.Web.Script.Serialization d'espace de noms:

JavaScriptSerializer serializer = new JavaScriptSerializer();
Cat c = serializer.Deserialize<Cat>(jsonString);

J'ai des objets POCO automatique de propriétés et cela fonctionne bien.

EDIT: j'ai écrit sur JSON Sérialiseurs .NET qui compare le sérialiseur avec DataContractJsonSerializer.

5voto

amelvin Points 6028

baretta réponse résolu le k__BackingField la météorisation pour moi. Juste un petit supplément, vous pouvez décorer cette classe pour auto sérialiser en XML ou JSON dans une manière similaire:

[Serializable, XmlRoot, DataContract]
public class Cat
{
  [XmlElement]
  [DataMember]
  public string Name { get; set; }
  [XmlElement]
  [DataMember]
  public string Breed { get; set; }
}

... et ensuite utiliser un DataContractJsonSerializer ou XmlSerializer pour le préparer pour votre point de terminaison.

1voto

Chris Brandsma Points 7225

Je suis en supposant que vous êtes la transmission des données via un service web. Si vous utilisez la classe de Service web avec le ScriptMethod attribut sans commentaire, les méthodes de service web peut lire JSON natif. Ils utilisent même la même JavaScriptSerializer qui a été mentionné ci-dessus. Si vous êtes en utilisant WCF je suis un peu plus floue sur la logique.

Mais assurez-vous que votre objet JSON sont les données de retour pour TOUS les biens de votre classe. Dans votre erreur, il est fait mention d'une Race bien qui n'est pas dans votre exemple.

Aussi, sur le JavaScript côté, faire de la nature dynamique de JavaScript, il est facile d'ajouter de nouvelles propriétés de vos objets. Cela peut parfois conduire à des références circulaires. Vous devez supprimer toutes les données supplémentaires que vous avez ajoutés (comme vous l'envoi de données via le web méthode, puis l'ajouter à nouveau une fois que vous avez terminé).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X