@@ -12,9 +12,105 @@ namespace Nest
1212 /// JSON converter for IDictionary that ignores the contract resolver (e.g. CamelCaseFieldNamesContractResolver)
1313 /// when converting dictionary keys to property names.
1414 /// </summary>
15+ internal class VerbatimDictionaryKeysJsonConverter : JsonConverter
16+ {
17+ public override bool CanConvert ( Type t ) => typeof ( IDictionary ) . IsAssignableFrom ( t ) ;
18+
19+ public override bool CanRead => false ;
20+
21+ public override object ReadJson ( JsonReader reader , Type objectType , object existingValue , JsonSerializer serializer )
22+ {
23+ throw new NotSupportedException ( ) ;
24+ }
25+
26+ public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
27+ {
28+ var dictionary = ( IDictionary ) value ;
29+ if ( dictionary == null )
30+ {
31+ writer . WriteNull ( ) ;
32+ return ;
33+ }
34+
35+ var settings = serializer . GetConnectionSettings ( ) ;
36+ var seenEntries = new Dictionary < string , object > ( dictionary . Count ) ;
37+
38+ Field fieldName ;
39+ PropertyName propertyName ;
40+ IndexName indexName ;
41+ TypeName typeName ;
42+
43+ foreach ( DictionaryEntry entry in dictionary )
44+ {
45+ if ( entry . Value == null && serializer . NullValueHandling == NullValueHandling . Ignore )
46+ continue ;
47+ string key ;
48+ if ( settings == null )
49+ key = Convert . ToString ( entry . Key , CultureInfo . InvariantCulture ) ;
50+ else if ( AsType ( entry . Key , out fieldName ) )
51+ {
52+ key = settings . Inferrer . Field ( fieldName ) ;
53+ }
54+ else if ( AsType ( entry . Key , out propertyName ) )
55+ {
56+ if ( propertyName ? . Property != null )
57+ {
58+ IPropertyMapping mapping ;
59+ if ( settings . PropertyMappings . TryGetValue ( propertyName . Property , out mapping ) && mapping . Ignore )
60+ {
61+ continue ;
62+ }
63+ }
64+
65+ key = settings . Inferrer . PropertyName ( propertyName ) ;
66+ }
67+ else if ( AsType ( entry . Key , out indexName ) )
68+ {
69+ key = settings . Inferrer . IndexName ( indexName ) ;
70+ }
71+ else if ( AsType ( entry . Key , out typeName ) )
72+ {
73+ key = settings . Inferrer . TypeName ( typeName ) ;
74+ }
75+ else
76+ key = Convert . ToString ( entry . Key , CultureInfo . InvariantCulture ) ;
77+
78+ if ( key != null )
79+ seenEntries [ key ] = entry . Value ;
80+ }
81+
82+ writer . WriteStartObject ( ) ;
83+ foreach ( var entry in seenEntries )
84+ {
85+ writer . WritePropertyName ( entry . Key ) ;
86+ serializer . Serialize ( writer , entry . Value ) ;
87+ }
88+ writer . WriteEndObject ( ) ;
89+ }
90+
91+ private static bool AsType < T > ( object value , out T convertedValue ) where T : class
92+ {
93+ convertedValue = value as T ;
94+ return convertedValue != null ;
95+ }
96+ }
97+
98+ /// <summary>
99+ /// JSON converter for IDictionary<TKey,TValue> and IReadOnlyDictionary<TKey,TValue>
100+ /// that ignores the contract resolver (e.g. CamelCaseFieldNamesContractResolver)
101+ /// when converting dictionary keys to property names.
102+ /// </summary>
15103 internal class VerbatimDictionaryKeysJsonConverter < TKey , TValue > : JsonConverter
16104 {
17- public override bool CanConvert ( Type t ) => typeof ( IDictionary < TKey , TValue > ) . IsAssignableFrom ( t ) ;
105+ private readonly bool _keyIsString = typeof ( TKey ) == typeof ( string ) ;
106+ private readonly bool _keyIsField = typeof ( TKey ) == typeof ( Field ) ;
107+ private readonly bool _keyIsPropertyName = typeof ( TKey ) == typeof ( PropertyName ) ;
108+ private readonly bool _keyIsIndexName = typeof ( TKey ) == typeof ( IndexName ) ;
109+ private readonly bool _keyIsTypeName = typeof ( TKey ) == typeof ( TypeName ) ;
110+
111+ public override bool CanConvert ( Type t ) =>
112+ typeof ( IDictionary < TKey , TValue > ) . IsAssignableFrom ( t ) ||
113+ typeof ( IReadOnlyDictionary < TKey , TValue > ) . IsAssignableFrom ( t ) ;
18114
19115 public override bool CanRead => false ;
20116
@@ -25,32 +121,31 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
25121
26122 public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
27123 {
28- var dictionary = value as IDictionary < TKey , TValue > ;
29- if ( dictionary == null ) return ;
124+ var enumerable = ( IEnumerable < KeyValuePair < TKey , TValue > > ) value ;
125+ if ( enumerable == null )
126+ {
127+ writer . WriteNull ( ) ;
128+ return ;
129+ }
30130
31131 var settings = serializer . GetConnectionSettings ( ) ;
32- var seenEntries = new Dictionary < string , TValue > ( dictionary . Count ) ;
33- var keyIsString = typeof ( TKey ) == typeof ( string ) ;
34- var keyIsField = typeof ( TKey ) == typeof ( Field ) ;
35- var keyIsPropertyName = typeof ( TKey ) == typeof ( PropertyName ) ;
36- var keyIsIndexName = typeof ( TKey ) == typeof ( IndexName ) ;
37- var keyIsTypeName = typeof ( TKey ) == typeof ( TypeName ) ;
38-
39- foreach ( var entry in dictionary )
132+ var seenEntries = new Dictionary < string , TValue > ( enumerable . Count ( ) ) ;
133+
134+ foreach ( var entry in enumerable )
40135 {
41136 if ( entry . Value == null && serializer . NullValueHandling == NullValueHandling . Ignore )
42137 continue ;
43138 string key ;
44- if ( keyIsString )
139+ if ( _keyIsString )
45140 key = entry . Key ? . ToString ( ) ;
46141 else if ( settings == null )
47142 key = Convert . ToString ( entry . Key , CultureInfo . InvariantCulture ) ;
48- else if ( keyIsField )
143+ else if ( _keyIsField )
49144 {
50145 var fieldName = entry . Key as Field ;
51146 key = settings . Inferrer . Field ( fieldName ) ;
52147 }
53- else if ( keyIsPropertyName )
148+ else if ( _keyIsPropertyName )
54149 {
55150 var propertyName = entry . Key as PropertyName ;
56151 if ( propertyName ? . Property != null )
@@ -64,12 +159,12 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s
64159
65160 key = settings . Inferrer . PropertyName ( propertyName ) ;
66161 }
67- else if ( keyIsIndexName )
162+ else if ( _keyIsIndexName )
68163 {
69164 var indexName = entry . Key as IndexName ;
70165 key = settings . Inferrer . IndexName ( indexName ) ;
71166 }
72- else if ( keyIsTypeName )
167+ else if ( _keyIsTypeName )
73168 {
74169 var typeName = entry . Key as TypeName ;
75170 key = settings . Inferrer . TypeName ( typeName ) ;
0 commit comments