2009-09-07 14 views

Respuesta

12

La solución que funcionó para mí:

La clase y las propiedades serializado se pueden decorar de la siguiente manera:

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

isRequired fue el elemento clave.

La serialización real podría hacerse utilizando 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; 
} 
+6

Para DataContractJsonSerializer necesita establecer EmitDefaultValue como falso en el DataMember – FinnNk

4

Json.NET tiene opciones para excluir automáticamente los valores nulos o predeterminados.

+13

OP preguntaba por JavaScriptSerializer, no por json.net. –

+5

@JustinR. parece que él es el autor de Json.NET y esa es probablemente la razón por la cual – Steve

27

FYI, si desea seguir con la solución más fácil, esto es lo que solía lograr esto usando una aplicación JavaScriptConverter con el 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(); } 
     } 
    } 

y luego se usa:

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

Debe señalar que si también desea campos, el código lo falta –

+0

Si se preguntaba qué comentario anterior estaba hablando de: http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c –

+0

También podría hacer esto un poco más rápido por verificando ignoreProp primero y sin obtener el valor a menos que sea falso. – Brain2000

1

Este código es el bloqueo nulo y predeterminado (0) valores para los tipos numéricos

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(); } 
     } 
    } 
0

Para el beneficio de Aquellos que encuentran esto en google, notan que los nulos pueden omitirse de forma nativa durante la serialización con Newtonsoft.Json

var json = JsonConvert.SerializeObject(
      objectToSerialize, 
      new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}); 
Cuestiones relacionadas