2009-09-07 46 views
32

Tôi đang sử dụng JavaScriptSerializer để tuần tự hóa một số đối tượng thực thể.JavaScriptSerializer có thể loại trừ các thuộc tính với giá trị null/mặc định không?

Vấn đề là, nhiều thuộc tính công khai chứa giá trị rỗng hoặc mặc định. Có cách nào để làm cho JavaScriptSerializer loại trừ các thuộc tính với giá trị null hoặc mặc định không?

Tôi muốn kết quả JSON ít tiết hơn.

Trả lời

12

Các giải pháp mà làm việc cho tôi:

Lớp serialized và tài sản sẽ được trang trí như sau:

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

isRequired là key item.

Các serialization thực tế có thể được thực hiện bằng 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

Đối với DataContractJsonSerializer bạn cần phải đặt EmitDefaultValue thành false trên DataMember – FinnNk

4

Json.NET có các tùy chọn để tự động loại trừ giá trị rỗng hoặc giá trị mặc định.

+13

OP đã hỏi về JavaScriptSerializer, chứ không phải json.net. –

+5

@JustinR. trông giống như ông là tác giả của Json.NET và đó có lẽ là lý do tại sao – Steve

27

FYI, nếu bạn muốn đi với các giải pháp dễ dàng hơn, đây là những gì tôi đã sử dụng để thực hiện điều này bằng cách sử dụng thực hiện JavaScriptConverter với 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(); } 
     } 
    } 

và sau đó sử dụng nó:

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

Nên chỉ ra rằng nếu bạn muốn các trường cũng như mã thiếu nó –

+0

Nếu bạn tự hỏi những gì bình luận trước đó đã nói về: http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c –

+0

Bạn cũng có thể làm điều này nhanh hơn một chút bởi kiểm tra ignoreProp trước và không nhận giá trị trừ khi nó là false. – Brain2000

1

Mã này là khối vô mặc định (0) giá trị với nhiều loại số

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

Để tiện lợi hơn những người tìm thấy điều này trên google, lưu ý rằng các giá trị rỗng có thể bị bỏ qua trong quá trình tuần tự hóa với Newtonsoft.Json

var json = JsonConvert.SerializeObject(
      objectToSerialize, 
      new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}); 
Các vấn đề liên quan