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);
            }         }     } }
posted @ 2008-09-09 14:38  Feng Lu  阅读(387)  评论(0编辑  收藏  举报