如果使用JavaScriptSerializer为零,则忽略十进制值

时间:2018-01-19 12:30:22

标签: c# .net serialization xml-serialization javascriptserializer

如果十进制值为零,是否可以隐藏元素?

public class MyData
{
        public decimal Val1 { get; set; }
        public decimal Val2 { get; set; }
        public decimal Val3 { get; set; }
}

如果它为零,我想忽略Val3

var result = new JavaScriptSerializer().Serialize(MyData);

1 个答案:

答案 0 :(得分:1)

您可以使用自定义JavaScriptConverter

例如:

public class MyJavaScriptSerializer : 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 myData = obj as MyData;

    var result = new Dictionary<string, object>();
    if (myData != null)
    {
      result["val1"] = myData.Val1;
      result["val2"] = myData.Val2;
      if(myData.Val3 != 0)
        result["val3"] = myData.Val3;

      return result;
    }

    return new Dictionary<string, object>();
  }

  public override IEnumerable<Type> SupportedTypes =>
      new ReadOnlyCollection<Type>(new List<Type> { typeof(MyData) });
}

并使用它:

var js = new JavaScriptSerializer();
js.RegisterConverters(new List<JavaScriptConverter> { new MyJavaScriptSerializer() });
string result = js.Serialize(myData);

或者您可以使用反射和自定义属性创建更强大的解决方案。

仅举例:

制作自定义属性:

public class IgnoreIfValueExactlyAttribute : Attribute
{
  public int ValueToIgnore { get; }

  public IgnoreIfValueExactlyAttribute(int valueToIgnore)
  {
    ValueToIgnore = valueToIgnore;
  }
}

声明可支持的类型:

public override IEnumerable<Type> SupportedTypes => new ReadOnlyCollection<Type>(new List<Type> { typeof(object), /*your types*/ });

并覆盖Serialize方法,例如:

public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
  var result = new Dictionary<string, object>();
  if (obj != null)
  {
    var properties = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
    foreach (var propertyInfo in properties)
    {
      var isIgnorable = propertyInfo.GetCustomAttribute<IgnoreIfValueExactlyAttribute>();
      var value = decimal.Parse(propertyInfo.GetValue(obj).ToString());
      if (isIgnorable != null && isIgnorable.ValueToIgnore == value)
        continue;

      result[propertyInfo.Name] = value;
    }

    return result;
  }

  return new Dictionary<string, object>();
}

并在您的可分类型中使用属性:

public class MyData
{
  public decimal Val1 { get; set; }
  public decimal Val2 { get; set; }

  [IgnoreIfValueExactly(0)]
  public decimal Val3 { get; set; }
}