JavaScriptSerializer可以排除空/默认值属性吗?

39

我正在使用JavaScriptSerializer来序列化一些实体对象。

问题在于,许多公共属性包含空值或默认值。是否有任何方法可以使JavaScriptSerializer排除具有空或默认值的属性?

我希望生成的JSON更加简洁。

7个回答

36

顺便说一下,如果您想选择更简单的解决方案,这是我使用 JavaScriptConverter 实现和 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();
  }
 }
}

然后使用它:

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

3
需要指出的是,如果您想要字段(信息),那么代码缺失了这些信息。 - Andrew Cox
如果你想知道之前的评论在谈论什么:https://dev59.com/pXVC5IYBdhLWcg3wcgmd - Thibault D.
你也可以通过首先检查 ignoreProp 并且只有在它为 false 时才获取值来稍微加快速度。 - Brain2000
1
很棒的解决方案!如果您没有得到任何结果,请记得在对象属性上使用{get;set;},以便反射将它们返回到GetProperties()中。 - clamchoda

15
我的解决方案是:
将序列化类和属性进行如下装饰:
[DataContract]
public class MyDataClass
{
  [DataMember(Name = "LabelInJson", IsRequired = false)]
  public string MyProperty { get; set; }
}

IsRequired是关键项目。

可以使用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;
}

7
DataContractJsonSerializer需要在DataMember上将EmitDefaultValue设置为false。 - FinnNk
这看起来很有趣,但需要更多的解释,特别是第一段代码。 - KansaiRobot

7
为那些在谷歌上找到这篇文章的读者解释,使用Newtonsoft.Json进行序列化时可以自动跳过null值。
var json = JsonConvert.SerializeObject(
            objectToSerialize,
            new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore});

4

4

Json.NET有选项可以自动排除空值或默认值。


14
OP 询问的是 JavaScriptSerializer,而不是 json.net。 - Justin R.
5
@JustinR. 看起来是Json.NET的作者,这可能就是原因。 - Steve

1
这段代码用于为数值类型块设置空值和默认值(0)。
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

8
如果您想始终忽略一个属性,ScriptIgnore很有用,但如果您只想忽略具有null值的属性并在它们具有真实值时包含它们,则不适用。 - Kate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接