508 votes

Comment puis-je changer les noms des propriétés lors de la sérialisation avec Json.net ?

J'ai des données dans un objet C# DataSet. Je peux le sérialiser en utilisant un convertisseur Json.net comme ceci

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

Cependant, cela utilise les noms de propriétés de data lors de l'impression du fichier .json. Je voudrais changer les noms des propriétés pour qu'ils soient différents (par exemple, remplacer 'foo' par 'bar').

En el Documentation sur Json.net Dans la section "Serializing and Deserializing JSON", sous "Serialization Attributes", il est indiqué que "JsonPropertyAttribute... permet de personnaliser le nom". Mais il n'y a pas d'exemple. Quelqu'un sait-il comment utiliser un JsonPropertyAttribute pour changer le nom de la propriété en quelque chose d'autre ?

( Lien direct vers la documentation )

La documentation de Json.net semble être clairsemée. Si vous avez un bon exemple, j'essaierai de le faire ajouter à la documentation officielle. Merci !

5 votes

Pour info, il y a un exemple de ceci dans la documentation sous la rubrique Exemples -> Sérialisation JSON -> Nom de l'attribut JsonPropertyAttribute . Je ne sais pas exactement à quel moment il a été ajouté.

903voto

Darin Dimitrov Points 528142

Vous pouvez décorer la propriété que vous souhaitez en contrôlant son nom avec la balise [JsonProperty] qui vous permet de spécifier un nom différent :

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

Documentation : Attributs de sérialisation

2 votes

Cela nécessite-t-il que je lise mes données dans un objet personnalisé que je crée plutôt que dans un DataSet ?

4 votes

@culix, oui, il faut utiliser un modèle. Un DataSet est une structure faiblement typée, donc parler de noms de propriétés pour lui n'est pas très logique.

92 votes

En guise de raccourci, vous pouvez aussi faire [JsonProperty("FooBar")]

101voto

StingyJack Points 10956

Si vous n'avez pas accès aux classes pour modifier les propriétés, ou si vous ne voulez pas toujours utiliser la même propriété de renommage, le renommage peut également être effectué en créant un résolveur personnalisé.

Par exemple, si vous avez une classe appelée MyCustomObject qui a une propriété appelée LongPropertyName vous pouvez utiliser un résolveur personnalisé comme ceci

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

Ensuite, appelez la sérialisation et fournissez le résolveur :

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

Et le résultat sera raccourci à {"Short" : "prop value"} au lieu de {"LongPropertyName" : "valeur de la propriété"}

Plus d'informations sur les résolveurs personnalisés ici

3 votes

C'est une meilleure solution si votre classe à sérialiser est déclarée dans une autre assemblée qui inclut une version différente du paquet Newtonsoft.Json. (il se peut même qu'aucune erreur n'apparaisse). Le site DefaultContractResolver doit être placé dans le même assemblage où la méthode JsonConvert.Serialize() est utilisée.

2 votes

Je travaille avec l'API d'un fournisseur qui possède un objet commun utilisé par plusieurs fonctions de l'API. Dans un seul des appels d'API, une propriété de l'objet commun doit être sérialisée sous un nom légèrement différent (par exemple, clientid au lieu de client_id). Cette réponse était la solution parfaite à mon problème.

8voto

JotaBe Points 8950

Il existe encore une autre façon de procéder, qui consiste à utiliser une méthode particulière Stratégie de dénomination qui peuvent être appliqués à une classe ou à une propriété en les décorant de la mention [JSonObject] o [JsonProperty] .

Il existe des stratégies de dénomination prédéfinies comme CamelCaseNamingStrategy mais vous pouvez mettre en œuvre les vôtres.

La mise en œuvre de différentes stratégies de dénomination peut être consultée ici : https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization

5 votes

Si vous le pouvez, veuillez partager un exemple d'une mise en œuvre personnalisée de NamingStrategy.

2 votes

Bien sûr... non. Vous auriez dû le faire vous-même, mais je vous épargnerai le temps de vous dire que vous devez simplement hériter newtonsoft.com/json/help/html/ Vous pouvez voir la mise en œuvre des classes existantes et créer la vôtre.

4 votes

Merci - j'aurais dû mettre à jour mon commentaire : en fait, grâce à la gloire qu'est GitHub, on peut utiliser l'une des implémentations de Newtonsoft comme exemple, par exemple, este

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