@@ -108,6 +108,14 @@ static Func<T, bool> GetShouldSerializeMethod(MemberInfo member)
108108 return ( method == null || method . ReturnType != typeof ( bool ) ) ? null : ( Func < T , bool > ) method . CreateDelegate ( typeof ( Func < T , bool > ) ) ;
109109 }
110110
111+ static Func < T , string , bool ? > ShouldSerialize ( Type type )
112+ {
113+ var method = type . GetMethod ( "ShouldSerialize" , BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic , null , new [ ] { typeof ( string ) } , null ) ;
114+ return ( method == null || method . ReturnType != typeof ( bool ? ) )
115+ ? null
116+ : ( Func < T , string , bool ? > ) Delegate . CreateDelegate ( typeof ( Func < T , string , bool ? > ) , method ) ;
117+ }
118+
111119 private static bool Init ( )
112120 {
113121 if ( ! typeof ( T ) . IsClass ( ) && ! typeof ( T ) . IsInterface ( ) && ! JsConfig . TreatAsRefType ( typeof ( T ) ) ) return false ;
@@ -123,6 +131,8 @@ private static bool Init()
123131 return typeof ( T ) . IsDto ( ) ;
124132 }
125133
134+ var shouldSerializeDynamic = ShouldSerialize ( typeof ( T ) ) ;
135+
126136 // NOTE: very limited support for DataContractSerialization (DCS)
127137 // NOT supporting Serializable
128138 // support for DCS is intended for (re)Name of properties and Ignore by NOT having a DataMember present
@@ -173,6 +183,7 @@ private static bool Init()
173183 Serializer . GetWriteFn ( propertyType ) ,
174184 propertyType . GetDefaultValue ( ) ,
175185 shouldSerialize ,
186+ shouldSerializeDynamic ,
176187 propertyType . IsEnum ( )
177188 ) ;
178189 }
@@ -225,6 +236,7 @@ private static bool Init()
225236 Serializer . GetWriteFn ( propertyType ) ,
226237 defaultValue ,
227238 shouldSerialize ,
239+ shouldSerializeDynamic ,
228240 propertyType . IsEnum ( )
229241 ) ;
230242 }
@@ -257,11 +269,15 @@ internal string PropertyName
257269 internal readonly WriteObjectDelegate WriteFn ;
258270 internal readonly object DefaultValue ;
259271 internal readonly Func < T , bool > shouldSerialize ;
272+ internal readonly Func < T , string , bool ? > shouldSerializeDynamic ;
260273 internal readonly bool isEnum ;
261274
262275 public TypePropertyWriter ( string propertyName , string propertyDeclaredTypeName , string propertyNameCLSFriendly ,
263276 string propertyNameLowercaseUnderscore , int propertyOrder , bool propertySuppressDefaultConfig , bool propertySuppressDefaultAttribute ,
264- Func < T , object > getterFn , WriteObjectDelegate writeFn , object defaultValue , Func < T , bool > shouldSerialize , bool isEnum )
277+ Func < T , object > getterFn , WriteObjectDelegate writeFn , object defaultValue ,
278+ Func < T , bool > shouldSerialize ,
279+ Func < T , string , bool ? > shouldSerializeDynamic ,
280+ bool isEnum )
265281 {
266282 this . propertyName = propertyName ;
267283 this . propertyOrder = propertyOrder ;
@@ -274,6 +290,7 @@ public TypePropertyWriter(string propertyName, string propertyDeclaredTypeName,
274290 this . WriteFn = writeFn ;
275291 this . DefaultValue = defaultValue ;
276292 this . shouldSerialize = shouldSerialize ;
293+ this . shouldSerializeDynamic = shouldSerializeDynamic ;
277294 this . isEnum = isEnum ;
278295 }
279296
@@ -361,15 +378,31 @@ public static void WriteProperties(TextWriter writer, object value)
361378 if ( propertyWriter . shouldSerialize != null && ! propertyWriter . shouldSerialize ( ( T ) value ) )
362379 continue ;
363380
381+ var dontSkipDefault = false ;
382+ if ( propertyWriter . shouldSerializeDynamic != null )
383+ {
384+ var shouldSerialize = propertyWriter . shouldSerializeDynamic ( ( T ) value , propertyWriter . PropertyName ) ;
385+ if ( shouldSerialize . HasValue )
386+ {
387+ if ( shouldSerialize . Value )
388+ dontSkipDefault = true ;
389+ else
390+ continue ;
391+ }
392+ }
393+
364394 var propertyValue = value != null
365395 ? propertyWriter . GetterFn ( ( T ) value )
366396 : null ;
367-
368- if ( ! propertyWriter . ShouldWriteProperty ( propertyValue ) )
369- continue ;
370397
371- if ( JsConfig . ExcludePropertyReferences != null
372- && JsConfig . ExcludePropertyReferences . Contains ( propertyWriter . propertyReferenceName ) ) continue ;
398+ if ( ! dontSkipDefault )
399+ {
400+ if ( ! propertyWriter . ShouldWriteProperty ( propertyValue ) )
401+ continue ;
402+
403+ if ( JsConfig . ExcludePropertyReferences != null
404+ && JsConfig . ExcludePropertyReferences . Contains ( propertyWriter . propertyReferenceName ) ) continue ;
405+ }
373406
374407 if ( i ++ > 0 )
375408 writer . Write ( JsWriter . ItemSeperator ) ;
0 commit comments