Changed private methods of JsonSerializer to implement IgoreDefaultValue (needs Newtonsot.Json)
Usage Sample
[JsonObject(MemberSerialization.OptIn)]
public class Person
{
// "John Smith"
//this property will be ignored during serializing if John Smith's name is still 'john smith'
[DefaultValue("John Smith")]
[JsonProperty]
public string Name { get; set; }
// not serialized
public string Department { get; set; }
}
here is the code:
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Collections; using System.Reflection; using System.ComponentModel; using Newtonsoft.Json.Utilities; using System.Globalization; using System.Linq; using Newtonsoft.Json.Linq; using System.Collections.ObjectModel;
namespace Newtonsoft.Json {
#region new interfacce IJsonIgoreDefaultValue
/// <summary>
/// if the object is IJsonIgoreDefaultValue, JsonSerializer will igore the properties which has a DefaultValueAttribute and the property's value is equal to this default value.
/// </summary> public interface IJsonIgoreDefaultValue { }
#endregion
/// <summary> /// changed private methods of JsonSerializer to implement IgoreDefaultValue are moved here. /// </summary> public partial class JsonSerializer { private void SerializeObject(JsonWriter writer, object value) { Type objectType = value.GetType();
#if !SILVERLIGHT
TypeConverter converter = TypeDescriptor.GetConverter(objectType);
// use the objectType's TypeConverter if it has one and can convert to a string
if (converter != null && !(converter is ComponentConverter) && converter.GetType() != typeof(TypeConverter)) { if (converter.CanConvertTo(typeof(string))) { writer.WriteValue(converter.ConvertToInvariantString(value)); return; } } #else
if (value is Guid) { writer.WriteValue(value.ToString()); return; } #endif
writer.SerializeStack.Add(value); writer.WriteStartObject(); MemberMappingCollection memberMappings = GetMemberMappings(objectType);
//changes begin (add) bool isIJsonIgoreDefaultValue = typeof(IJsonIgoreDefaultValue).IsAssignableFrom(objectType); //changes end foreach (MemberMapping memberMapping in memberMappings) {
if (!memberMapping.Ignored && memberMapping.Readable) #region changes begin #region old //WriteMemberInfoProperty(writer, value, memberMapping.Member, memberMapping.MappingName, memberMapping.MemberConverter); #endregion #region new WriteMemberInfoProperty(writer, value, memberMapping.Member, memberMapping.MappingName, memberMapping.MemberConverter, isIJsonIgoreDefaultValue);
#endregion
#endregion
}
writer.WriteEndObject();
writer.SerializeStack.Remove(value);
}
private void WriteMemberInfoProperty(JsonWriter writer, object value, MemberInfo member, string propertyName, JsonConverter memberConverter
//changes begin (add) , bool isIJsonIgoreDefaultValue //changes end ) { if (!ReflectionUtils.IsIndexedProperty(member)) { object memberValue = ReflectionUtils.GetMemberValue(member, value); if (_nullValueHandling == NullValueHandling.Ignore && memberValue == null) return;
if (writer.SerializeStack.IndexOf(memberValue) != -1) { switch (_referenceLoopHandling) { case ReferenceLoopHandling.Error:
throw new JsonSerializationException("Self referencing loop");
case ReferenceLoopHandling.Ignore:
// return from method
return;
case ReferenceLoopHandling.Serialize:
// continue
break;
default:
throw new InvalidOperationException("Unexpected ReferenceLoopHandling value: '{0}'".FormatWith(CultureInfo.InvariantCulture, _referenceLoopHandling));
}
}
#region changes (add)
if (isIJsonIgoreDefaultValue) { DefaultValueAttribute defaultValueAttribute = ReflectionUtils.GetAttribute<DefaultValueAttribute>(member, true);
if (defaultValueAttribute != null) { bool defaultValueIsNull = null == defaultValueAttribute.Value;
bool memberValueIsNull = null == memberValue;
if (memberValueIsNull && defaultValueIsNull == memberValueIsNull)
return;
if (memberValueIsNull == false && defaultValueIsNull == false) { Type dt = defaultValueAttribute.Value.GetType(); Type mt = memberValue.GetType(); if (dt == mt) {
object dv = defaultValueAttribute.Value; object mv = memberValue; switch (dt.ToString()) { case "System.Int32": case "System.Int16": case "System.Int64": if ((int)dv == (int)mv) return; break; case "System.Boolean": if ((bool)dv == (bool)mv) return; break; case "System.String": if ((string)dv == (string)mv) return; break; } if (dt.ToString() == mt.ToString()) return; } else { if (defaultValueAttribute.Value == memberValue) return;
} } } }
//changes end
#endregion
writer.WritePropertyName(propertyName ?? member.Name);
SerializeValue(writer, memberValue, memberConverter);
} } } }