如果使用 JavaScriptSerializer 为零,则忽略十进制值
Ignore decimal value if it is zero using 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);
您可以使用自定义 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; }
}
是否可以隐藏小数为零的元素?
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);
您可以使用自定义 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; }
}