web-dev-qa-db-fra.com

JavaScriptSerializer peut-il exclure des propriétés avec des valeurs nulles / par défaut?

J'utilise JavaScriptSerializer pour sérialiser certains objets d'entité.

Le problème est que de nombreuses propriétés publiques contiennent des valeurs nulles ou par défaut. Existe-t-il un moyen de faire en sorte que JavaScriptSerializer exclue les propriétés avec des valeurs nulles ou par défaut?

Je voudrais que le JSON résultant soit moins verbeux.

37
frankadelic

La solution qui a fonctionné pour moi:

La classe et les propriétés sérialisées seraient décorées comme suit:

[DataContract]
public class MyDataClass
{
  [DataMember(Name = "LabelInJson", IsRequired = false)]
  public string MyProperty { get; set; }
}

IsRequired était l'élément clé.

La sérialisation réelle peut être effectuée à l'aide de DataContractJsonSerializer:

public static string Serialize<T>(T obj)
{
  string returnVal = "";
  try
  {
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    using (MemoryStream ms = new MemoryStream())
    {
      serializer.WriteObject(ms, obj);
      returnVal = Encoding.Default.GetString(ms.ToArray());
    }
  }
  catch (Exception /*exception*/)
  {
    returnVal = "";
    //log error
  }
  return returnVal;
}
14
frankadelic

Pour info, si vous souhaitez opter pour la solution la plus simple, voici ce que j'ai utilisé pour accomplir cela en utilisant une implémentation JavaScriptConverter avec JavaScriptSerializer:

private class NullPropertiesConverter: JavaScriptConverter {
 public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer) {
  throw new NotImplementedException();
 }

 public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer) {
  var jsonExample = new Dictionary<string, object >();
  foreach(var prop in obj.GetType().GetProperties()) {
   //check if decorated with ScriptIgnore attribute
   bool ignoreProp = prop.IsDefined(typeof(ScriptIgnoreAttribute), true);

   var value = prop.GetValue(obj, BindingFlags.Public, null, null, null);
   if (value != null && !ignoreProp)
    jsonExample.Add(prop.Name, value);
  }

  return jsonExample;
 }

 public override IEnumerable<Type> SupportedTypes {
  get {
   return GetType().Assembly.GetTypes();
  }
 }
}

puis de l'utiliser:

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] {
  new NullPropertiesConverter();
});
return serializer.Serialize(someObjectToSerialize);
32
Mitch

Json.NET a des options pour exclure automatiquement les valeurs nulles ou par défaut.

5
James Newton-King

Vous pouvez implémenter un JavaScriptConverter et l'enregistrer en utilisant la méthode RegisterConverters de JavaScriptSerializer.

4
Vinay Sajip

Pour ceux qui trouvent cela sur google, notez que les valeurs nulles peuvent être ignorées nativement lors de la sérialisation avec Newtonsoft.Json

var json = JsonConvert.SerializeObject(
            objectToSerialize,
            new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});
3
Daniel Mohr

Ce code est un bloc nul et des valeurs par défaut (0) pour les types numériques

private class NullPropertiesConverter: JavaScriptConverter {
 public override object Deserialize(IDictionary < string, object > dictionary, Type type, JavaScriptSerializer serializer) {
  throw new NotImplementedException();
 }

 public override IDictionary < string, object > Serialize(object obj, JavaScriptSerializer serializer) {
  var jsonExample = new Dictionary < string,
   object > ();
  foreach(var prop in obj.GetType().GetProperties()) {
   //this object is nullable 
   var nullableobj = prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable < > );
   //check if decorated with ScriptIgnore attribute
   bool ignoreProp = prop.IsDefined(typeof(ScriptIgnoreAttribute), true);

   var value = prop.GetValue(obj, System.Reflection.BindingFlags.Public, null, null, null);
   int i;
   //Object is not nullable and value=0 , it is a default value for numeric types 
   if (!(nullableobj == false && value != null && (int.TryParse(value.ToString(), out i) ? i : 1) == 0) && value != null && !ignoreProp)
    jsonExample.Add(prop.Name, value);
  }

  return jsonExample;
 }

 public override IEnumerable < Type > SupportedTypes {
  get {
   return GetType().Assembly.GetTypes();
  }
 }
}
1
Ali B.

Sans changer d'orteil DataContractSerializer

Vous pouvez utiliser ScriptIgnoreAttribute

[1] http://msdn.Microsoft.com/en-us/library/system.web.script.serialization.scriptignoreattribute.aspx

0
Sameer