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

434

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

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

Cependant, cela utilise les noms de propriété de datalors de l'impression dans le fichier .json. Je voudrais changer les noms de propriété pour être quelque chose de différent (par exemple, changer "foo" en "bar").

Dans la documentation Json.net , sous 'Sérialisation et désérialisation JSON' → 'Attributs de sérialisation', il est écrit "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 autre chose?

( Lien direct vers la documentation )

La documentation de Json.net semble être rare. Si vous avez un bon exemple, je vais essayer de l'ajouter à la documentation officielle. Merci!

culix
la source
3
Pour info, il y a un exemple de cela dans la documentation sous Samples -> Serializing JSON -> JsonPropertyAttribute name . Je ne sais pas à quel moment il a été ajouté.
Brian Rogers

Réponses:

791

Vous pouvez décorer la propriété que vous souhaitez contrôler son nom avec l' [JsonProperty]attribut 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

Darin Dimitrov
la source
1
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?
culix
3
@culix, oui, cela nécessite l'utilisation d'un modèle. Un DataSet est une structure faiblement typée, donc parler de noms de propriété n'est pas très logique.
Darin Dimitrov
76
En tant que raccourci, vous pouvez également le faire[JsonProperty("FooBar")]
Bart Verkoeijen
2
@DarinDimitrov est-il possible de le faire sans Json .NET?
CH81
13
L'utilisation d'un modèle est cependant facile, il suffit de prendre un échantillon de votre JSON et de le coller dans un fichier .cs vide en utilisant "Collage spécial" -> "Coller JSON comme classes". - Il est intégré à Visual Studio. - À partir de là, il vous suffit simplement de configurer les choses en tant que casse de titre / renommage pour utiliser les conventions de dénomination .NET, etc. (en utilisant un convertisseur de casse de titre pour le premier et l'attribut JsonProperty pour le second).
BrainSlugs83
72

Si vous n'avez pas accès aux classes pour modifier les propriétés ou si vous ne souhaitez pas toujours utiliser la même propriété de renommage, le changement de nom 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 celui-ci…

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

Appelez ensuite 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": "prop value"}

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

StingyJack
la source
1
Il s'agit d'une meilleure solution si votre classe à sérialiser est déclarée dans un autre assembly qui inclut une version différente du package Newtonsoft.Json. (il ne peut même pas lancer d'erreur). Le DefaultContractResolverdoit être placé dans le même assembly où la méthode JsonConvert.Serialize () est utilisée.
Artemious
6

Il y a encore une autre façon de le faire, qui utilise une NamingStrategy particulière , qui peut être appliquée à une classe ou une propriété en les décorant avec [JSonObject]ou [JsonProperty].

Il existe des stratégies de nommage prédéfinies comme CamelCaseNamingStrategy, mais vous pouvez implémenter les vôtres.

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

JotaBe
la source
3
Si vous le pouvez, veuillez partager un exemple d'implémentation de stratégie de nommage personnalisée
user1007074
Bien sûr que non. Vous auriez dû le faire vous-même, mais je vous épargnerai le temps de vous dire que vous n'avez qu'à hériter de newtonsoft.com/json/help/html/… Vous pouvez voir l'implémentation des classes existantes et créer la vôtre.
JotaBe
Merci - j'aurais dû mettre à jour mon commentaire: en fait, grâce à la gloire de GitHub, on peut utiliser l'une des implémentations de Newtonsoft comme exemple, par exemple, celle-ci
user1007074
8
@JotaBe, ce n'est pas l'esprit de stackoverflow. Et en tant que programmeur qui veut juste faire mon travail, franchement, il aurait été mille fois mieux pour moi de lever le code que vous auriez pu fournir. Et vous auriez également obtenu mon vote. J'ai 18 ans d'expérience en codage et je suis classé par TripleByte comme "expert" en c #. Pas CHAQUE problème doit être laissé comme un "exercice pour le lecteur". Parfois, nous voulons simplement faire notre travail et passer à autre chose.
bboyle1234
2
Je suis d'accord avec vous et je n'écris généralement pas ce genre de commentaire. Cependant, je peux vous assurer que, dans ce cas, regarder le code lié est bien meilleur que toute explication que je peux donner. Et json.net est une bibliothèque open source très bien documentée. Lien inclus vers les implémentations (exemples parfaits)
JotaBe