@@ -61,7 +61,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
61
61
reader . Read ( ) ;
62
62
}
63
63
64
- if ( HaveStreams ( list ) )
64
+ if ( HasMemoryStream ( list ) )
65
65
{
66
66
return list ;
67
67
}
@@ -103,8 +103,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
103
103
dict . Add ( key , item ) ;
104
104
}
105
105
106
- var list = dict . Values . ToList ( ) ;
107
- if ( HaveStreams ( list ) )
106
+ if ( HasMemoryStream ( dict ) )
108
107
{
109
108
return dict ;
110
109
}
@@ -119,68 +118,139 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
119
118
120
119
public override void WriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
121
120
{
122
- if ( ! typeof ( MemoryStream ) . IsAssignableFrom ( value . GetType ( ) ) )
121
+ if ( HasMemoryStream ( value ) )
123
122
{
124
- if ( value . GetType ( ) . GetInterface ( nameof ( IEnumerable ) ) != null )
123
+ InternalWriteJson ( writer , value , serializer ) ;
124
+ return ;
125
+ }
126
+
127
+ JToken . FromObject ( value , serializer ) . WriteTo ( writer ) ;
128
+ }
129
+
130
+ private static void InternalWriteJson ( JsonWriter writer , object value , JsonSerializer serializer )
131
+ {
132
+ if ( value == null || value is string )
133
+ {
134
+ // Avoid processing strings, since they implement IEnumerable.
135
+ JToken . FromObject ( value , serializer ) . WriteTo ( writer ) ;
136
+ return ;
137
+ }
138
+
139
+ if ( value is MemoryStream )
140
+ {
141
+ var buffer = ( value as MemoryStream ) . ToArray ( ) ;
142
+ var result = new SerializedMemoryStream
143
+ {
144
+ Type = nameof ( MemoryStream ) ,
145
+ Buffer = buffer . ToList ( )
146
+ } ;
147
+
148
+ JToken . FromObject ( result , serializer ) . WriteTo ( writer ) ;
149
+ return ;
150
+ }
151
+
152
+ if ( value is IDictionary dictionary )
153
+ {
154
+ writer . WriteStartObject ( ) ;
155
+ foreach ( DictionaryEntry entry in dictionary )
125
156
{
126
- // This makes the WriteJson loops over nested values to replace all instances of MemoryStream.
127
- serializer . Converters . Add ( this ) ;
157
+ writer . WritePropertyName ( entry . Key . ToString ( ) ) ;
158
+ InternalWriteJson ( writer , entry . Value , serializer ) ;
128
159
}
129
160
130
- JToken . FromObject ( value , serializer ) . WriteTo ( writer ) ;
131
- serializer . Converters . Remove ( this ) ;
161
+ writer . WriteEndObject ( ) ;
162
+ return ;
163
+ }
164
+
165
+ if ( value is IEnumerable collection )
166
+ {
167
+ writer . WriteStartArray ( ) ;
168
+ foreach ( var item in collection )
169
+ {
170
+ InternalWriteJson ( writer , item , serializer ) ;
171
+ }
172
+
173
+ writer . WriteEndArray ( ) ;
132
174
return ;
133
175
}
134
176
135
- var buffer = ( value as MemoryStream ) . ToArray ( ) ;
136
- var result = new SerializedMemoryStream
177
+ var type = value . GetType ( ) ;
178
+ if ( type . IsClass )
137
179
{
138
- Type = nameof ( MemoryStream ) ,
139
- Buffer = buffer . ToList ( )
140
- } ;
180
+ writer . WriteStartObject ( ) ;
181
+ foreach ( var prop in type . GetProperties ( ) )
182
+ {
183
+ writer . WritePropertyName ( prop . Name ) ;
184
+ InternalWriteJson ( writer , prop . GetValue ( value ) , serializer ) ;
185
+ }
141
186
142
- JToken . FromObject ( result ) . WriteTo ( writer ) ;
187
+ writer . WriteEndObject ( ) ;
188
+ return ;
189
+ }
190
+
191
+ JToken . FromObject ( value , serializer ) . WriteTo ( writer ) ;
143
192
}
144
193
145
194
/// <summary>
146
- /// Check if a List contains at least one MemoryStream.
195
+ /// Check if an object contains at least one MemoryStream.
147
196
/// </summary>
148
- /// <param name="list">List of values that might have a MemoryStream instance.</param>
197
+ /// <param name="value">Object contaning values that might have a MemoryStream instance.</param>
149
198
/// <returns>True if there is at least one MemoryStream in the list, otherwise false.</returns>
150
- private static bool HaveStreams ( List < object > list )
199
+ private static bool HasMemoryStream ( object value )
151
200
{
152
- var result = false ;
153
- foreach ( var nextLevel in list )
201
+ if ( value == null || value is string )
154
202
{
155
- if ( nextLevel == null )
156
- {
157
- continue ;
158
- }
203
+ // Avoid processing strings, since they implement IEnumerable.
204
+ return false ;
205
+ }
159
206
160
- if ( nextLevel . GetType ( ) == typeof ( MemoryStream ) )
161
- {
162
- result = true ;
163
- }
207
+ if ( value is MemoryStream )
208
+ {
209
+ return true ;
210
+ }
164
211
165
- // Type generated from the ReadJson => JsonToken.StartObject.
166
- if ( nextLevel . GetType ( ) == typeof ( Dictionary < string , object > ) )
212
+ if ( value is IDictionary dictionary )
213
+ {
214
+ foreach ( DictionaryEntry entry in dictionary )
167
215
{
168
- result = HaveStreams ( ( nextLevel as Dictionary < string , object > ) . Values . ToList ( ) ) ;
216
+ if ( HasMemoryStream ( entry . Value ) )
217
+ {
218
+ return true ;
219
+ }
169
220
}
170
221
171
- // Type generated from the ReadJson => JsonToken.StartArray.
172
- if ( nextLevel . GetType ( ) == typeof ( List < object > ) )
222
+ return false ;
223
+ }
224
+
225
+ if ( value is IEnumerable collection )
226
+ {
227
+ foreach ( var item in collection )
173
228
{
174
- result = HaveStreams ( nextLevel as List < object > ) ;
229
+ if ( HasMemoryStream ( item ) )
230
+ {
231
+ return true ;
232
+ }
175
233
}
176
234
177
- if ( result )
235
+ return false ;
236
+ }
237
+
238
+ var type = value . GetType ( ) ;
239
+ if ( type . IsClass )
240
+ {
241
+ foreach ( var prop in type . GetProperties ( ) )
178
242
{
179
- break ;
243
+ var propValue = prop . GetValue ( value ) ;
244
+ if ( HasMemoryStream ( propValue ) )
245
+ {
246
+ return true ;
247
+ }
180
248
}
249
+
250
+ return false ;
181
251
}
182
252
183
- return result ;
253
+ return false ;
184
254
}
185
255
186
256
internal class SerializedMemoryStream
0 commit comments