web-dev-qa-db-fra.com

Cas de chameau par défaut des noms de propriété dans la sérialisation JSON

J'ai un tas de classes qui seront sérialisées en JSON à un moment donné et pour le respect des conventions C # sur le back-end et des conventions JavaScript sur le front-end, j'ai défini des propriétés comme celle-ci:

[JsonProperty(PropertyName="myFoo")]
public int MyFoo { get; set; }

Pour qu'en C # je puisse:

MyFoo = 10;

Et en Javascript je peux:

if (myFoo === 10)

Mais faire cela pour chaque propriété est fastidieux. Existe-t-il un moyen rapide et facile de définir la façon par défaut dont JSON.Net gère les noms de propriété afin qu'il se casse automatiquement les chameaux, sauf indication contraire?

28
Matt Burland

Vous pouvez utiliser la classe fournie Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver :

var serializer = new JsonSerializer
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};
var jobj = JObject.FromObject(request, serializer);

En d'autres termes, vous n'avez pas besoin de créer vous-même un résolveur personnalisé.

35
David Kennedy

Lors de la sérialisation de votre objet, transmettez certains paramètres personnalisés.

var settings = new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver()
};

var json = JsonConvert.SerializeObject(yourObject, settings);
13
Pure.Krome

Étant donné que la réponse acceptée est uniquement liée à un lien, j'ajoute le code réel que j'ai fini par utiliser (au cas où le lien mourrait). C'est en gros la même chose que ce qui était dans le lien:

// Automatic camel casing because I'm bored of putting [JsonProperty] on everything
// See: http://harald-muehlhoff.de/post/2013/05/10/Automatic-camelCase-naming-with-JsonNET-and-Microsoft-Web-API.aspx#.Uv43fvldWCl
public class CamelCase : CamelCasePropertyNamesContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member,
        MemberSerialization memberSerialization)
    {
        var res = base.CreateProperty(member, memberSerialization);

        var attrs = member.GetCustomAttributes(typeof(JsonPropertyAttribute), true);

        if (attrs.Any())
        {
            var attr = (attrs[0] as JsonPropertyAttribute);
            if (res.PropertyName != null && attr.PropertyName != null)
                res.PropertyName = attr.PropertyName;
        }

        return res;
    }
}

Le seul changement que j'ai fait a été l'ajout de attr.PropertyName != null à la clause if à cause du cas où j'avais ajouté quelque chose comme:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string SomeProperty { get; set; }

Et je ne voulais pas spécifier le PropertyName (donc c'est nul). Ce qui précède sera sérialisé en JSON comme someProperty.

6
Matt Burland

Mieux vaut utiliser le nouveau CamelCaseNamingStrategy :

new JsonSerializerSettings()
{
    ContractResolver = new DefaultContractResolver
    {
       NamingStrategy = new CamelCaseNamingStrategy()
    }
};

Il ne remplace pas les noms personnalisés définis par JsonPropert('Name') par défaut. (Vous pouvez changer le comportement par CamelCaseNamingStrategy(bool, bool) ctor.) Donc, n'a pas besoin de créer de classe personnalisée comme la réponse de @Matt Burland.

5
xmedeko

Vous pouvez utiliser un résolveur de contrat personnalisé :

class MyContractResolver : DefaultContractResolver
{
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);

        foreach (var property in properties)
        {
            property.PropertyName = char.ToLower(property.PropertyName[0]) + string.Join("", property.PropertyName.Skip(1));
        }

        return properties;
    }
}

Et utilisez-le comme:

class MyClass
{
    public int MyProperty { get; set; }
    public int MyProperty2 { get; set; }
}

var json = JsonConvert.SerializeObject(new MyClass(), 
                Formatting.Indented, 
                new JsonSerializerSettings { ContractResolver = new MyContractResolver() });
5
Alberto

JObject.FromObject utilise les paramètres par défaut de JsonConvert par défaut. Il y a une propriété func que vous pouvez assigner comme ceci:

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
 {
   ContractResolver = new CamelCasePropertyNamesContractResolver()
 };

et chaque fois que vous appelez Jobject.FromObject, il utilisera cette fonction pour construire les paramètres.

4