17
17
using System . Reflection ;
18
18
using ServiceStack . Reflection ;
19
19
using ServiceStack . Text . Json ;
20
+ using ServiceStack . Text . Jsv ;
20
21
21
22
namespace ServiceStack . Text . Common
22
23
{
@@ -178,6 +179,7 @@ private static bool Init()
178
179
179
180
PropertyWriters [ i ] = new TypePropertyWriter
180
181
(
182
+ propertyType ,
181
183
propertyName ,
182
184
propertyDeclaredTypeName ,
183
185
propertyNameCLSFriendly ,
@@ -234,6 +236,7 @@ private static bool Init()
234
236
235
237
PropertyWriters [ i + propertyNamesLength ] = new TypePropertyWriter
236
238
(
239
+ propertyType ,
237
240
propertyName ,
238
241
propertyDeclaredTypeName ,
239
242
propertyNameCLSFriendly ,
@@ -267,6 +270,8 @@ internal string PropertyName
267
270
: propertyName ;
268
271
}
269
272
}
273
+
274
+ internal readonly Type PropertyType ;
270
275
internal readonly string propertyName ;
271
276
internal readonly int propertyOrder ;
272
277
internal readonly bool propertySuppressDefaultConfig ;
@@ -281,13 +286,14 @@ internal string PropertyName
281
286
internal readonly Func < T , string , bool ? > shouldSerializeDynamic ;
282
287
internal readonly bool isEnum ;
283
288
284
- public TypePropertyWriter ( string propertyName , string propertyDeclaredTypeName , string propertyNameCLSFriendly ,
289
+ public TypePropertyWriter ( Type propertyType , string propertyName , string propertyDeclaredTypeName , string propertyNameCLSFriendly ,
285
290
string propertyNameLowercaseUnderscore , int propertyOrder , bool propertySuppressDefaultConfig , bool propertySuppressDefaultAttribute ,
286
291
Func < T , object > getterFn , WriteObjectDelegate writeFn , object defaultValue ,
287
292
Func < T , bool > shouldSerialize ,
288
293
Func < T , string , bool ? > shouldSerializeDynamic ,
289
294
bool isEnum )
290
295
{
296
+ this . PropertyType = propertyType ;
291
297
this . propertyName = propertyName ;
292
298
this . propertyOrder = propertyOrder ;
293
299
this . propertySuppressDefaultConfig = propertySuppressDefaultConfig ;
@@ -359,6 +365,15 @@ public static void WriteAbstractProperties(TextWriter writer, object value)
359
365
WriteLateboundProperties ( writer , value , valueType ) ;
360
366
}
361
367
368
+ internal static string GetPropertyName ( string propertyName )
369
+ {
370
+ return JsConfig < T > . EmitCamelCaseNames . GetValueOrDefault ( JsConfig . EmitCamelCaseNames )
371
+ ? propertyName . ToCamelCase ( )
372
+ : JsConfig < T > . EmitLowercaseUnderscoreNames . GetValueOrDefault ( JsConfig . EmitLowercaseUnderscoreNames )
373
+ ? propertyName . ToLowercaseUnderscore ( )
374
+ : propertyName ;
375
+ }
376
+
362
377
public static void WriteProperties ( TextWriter writer , object value )
363
378
{
364
379
if ( value == null )
@@ -488,20 +503,54 @@ public static void WriteComplexQueryStringProperties(string typeName, TextWriter
488
503
if ( i ++ > 0 )
489
504
writer . Write ( '&' ) ;
490
505
491
- writer . Write ( typeName ) ;
492
- writer . Write ( '[' ) ;
493
- writer . Write ( propertyWriter . PropertyName ) ;
494
- writer . Write ( ']' ) ;
506
+ var propertyValueType = propertyValue != null ? propertyValue . GetType ( ) : null ;
507
+ if ( propertyValueType != null &&
508
+ propertyValueType . IsUserType ( ) &&
509
+ ! propertyValueType . HasInterface ( typeof ( IEnumerable ) ) )
510
+ {
511
+ //Nested Complex Type: legal_entity[dob][day]=1
512
+ var prefix = "{0}[{1}]" . Fmt ( typeName , propertyWriter . PropertyName ) ;
513
+ var props = propertyValueType . GetSerializableProperties ( ) ;
514
+ for ( int j = 0 ; j < props . Length ; j ++ )
515
+ {
516
+ var pi = props [ j ] ;
517
+ var pValue = pi . GetValue ( propertyValue , new object [ 0 ] ) ;
518
+ if ( pValue == null && ! Serializer . IncludeNullValues )
519
+ continue ;
495
520
496
- writer . Write ( '=' ) ;
521
+ if ( j > 0 )
522
+ writer . Write ( '&' ) ;
497
523
498
- if ( propertyValue == null )
499
- {
500
- writer . Write ( JsonUtils . Null ) ;
524
+ writer . Write ( prefix ) ;
525
+ writer . Write ( '[' ) ;
526
+ writer . Write ( GetPropertyName ( pi . Name ) ) ;
527
+ writer . Write ( "]=" ) ;
528
+
529
+ if ( pValue == null )
530
+ {
531
+ writer . Write ( JsonUtils . Null ) ;
532
+ }
533
+ else
534
+ {
535
+ JsvWriter . GetWriteFn ( pValue . GetType ( ) ) ( writer , pValue ) ;
536
+ }
537
+ }
501
538
}
502
539
else
503
540
{
504
- propertyWriter . WriteFn ( writer , propertyValue ) ;
541
+ writer . Write ( typeName ) ;
542
+ writer . Write ( '[' ) ;
543
+ writer . Write ( propertyWriter . PropertyName ) ;
544
+ writer . Write ( "]=" ) ;
545
+
546
+ if ( propertyValue == null )
547
+ {
548
+ writer . Write ( JsonUtils . Null ) ;
549
+ }
550
+ else
551
+ {
552
+ propertyWriter . WriteFn ( writer , propertyValue ) ;
553
+ }
505
554
}
506
555
}
507
556
}
@@ -524,7 +573,7 @@ public static void WriteQueryString(TextWriter writer, object value)
524
573
var propertyType = propertyValue . GetType ( ) ;
525
574
var strValue = propertyValue as string ;
526
575
var isEnumerable = strValue == null
527
- && ! ( propertyType . IsValueType ( ) )
576
+ && ! propertyType . IsValueType ( )
528
577
&& propertyType . HasInterface ( typeof ( IEnumerable ) ) ;
529
578
530
579
if ( QueryStringSerializer . ComplexTypeStrategy != null
0 commit comments