|
32 | 32 | using System.Text;
|
33 | 33 | using System.Dynamic;
|
34 | 34 | using System.Collections.Generic;
|
| 35 | +using System.Collections; |
35 | 36 |
|
36 | 37 | namespace Erasme.Json
|
37 | 38 | {
|
@@ -259,34 +260,59 @@ public static void Merge(JsonValue dest, JsonValue source)
|
259 | 260 | }
|
260 | 261 | }
|
261 | 262 |
|
262 |
| - public T ToObject<T>() where T : new() |
| 263 | + object ToObjectInternal(Type type) |
263 | 264 | {
|
264 |
| - var result = new T(); |
265 |
| - foreach (var field in typeof(T).GetFields()) |
| 265 | + object result = null; |
| 266 | + if (this is JsonPrimitive) |
| 267 | + { |
| 268 | + if (type.IsEnum && JsonType == JsonType.String) |
| 269 | + result = Enum.Parse(type, (string)Value); |
| 270 | + else if (type == typeof(TimeSpan) && JsonType == JsonType.String) |
| 271 | + result = TimeSpan.Parse((string)Value); |
| 272 | + else |
| 273 | + result = Convert.ChangeType(Value, type); |
| 274 | + } |
| 275 | + else if (this is JsonObject) |
266 | 276 | {
|
267 |
| - if (!ContainsKey(field.Name)) |
268 |
| - continue; |
269 |
| - |
270 |
| - var value = this[field.Name]; |
271 |
| - if (value is JsonPrimitive) |
272 |
| - field.SetValue(result, Convert.ChangeType(value.Value, field.FieldType)); |
273 |
| - else if (value is JsonObject) |
274 |
| - field.SetValue(result, GetType().GetMethod(nameof(ToObject)).MakeGenericMethod(field.FieldType).Invoke(value, new object[] { })); |
| 277 | + result = Activator.CreateInstance(type); |
| 278 | + foreach (var field in type.GetFields()) |
| 279 | + { |
| 280 | + if (!ContainsKey(field.Name)) |
| 281 | + continue; |
| 282 | + var value = this[field.Name]; |
| 283 | + field.SetValue(result, value.ToObjectInternal(field.FieldType)); |
| 284 | + } |
| 285 | + foreach (var prop in type.GetProperties()) |
| 286 | + { |
| 287 | + if (!ContainsKey(prop.Name)) |
| 288 | + continue; |
| 289 | + var value = this[prop.Name]; |
| 290 | + prop.SetValue(result, value.ToObjectInternal(prop.PropertyType)); |
| 291 | + } |
275 | 292 | }
|
276 |
| - foreach (var prop in typeof(T).GetProperties()) |
| 293 | + else if (this is JsonArray) |
277 | 294 | {
|
278 |
| - if (!ContainsKey(prop.Name)) |
279 |
| - continue; |
280 |
| - |
281 |
| - var value = this[prop.Name]; |
282 |
| - if (value is JsonPrimitive) |
283 |
| - prop.SetValue(result, Convert.ChangeType(value.Value, prop.PropertyType)); |
284 |
| - else if (value is JsonObject) |
285 |
| - prop.SetValue(result, GetType().GetMethod(nameof(ToObject)).MakeGenericMethod(prop.PropertyType).Invoke(value, new object[] { })); |
| 295 | + result = Activator.CreateInstance(type, Count); |
| 296 | + if (type.IsArray) |
| 297 | + { |
| 298 | + var arrayItems = result as Array; |
| 299 | + for (var i = 0; i < ((JsonArray)this).Count; i++) |
| 300 | + { |
| 301 | + var el = ((JsonArray)this)[i]; |
| 302 | + var elType = type.GetElementType(); |
| 303 | + var value = el.ToObjectInternal(elType); |
| 304 | + arrayItems.SetValue(value, i); |
| 305 | + } |
| 306 | + } |
286 | 307 | }
|
287 | 308 | return result;
|
288 | 309 | }
|
289 | 310 |
|
| 311 | + public T ToObject<T>() where T : new() |
| 312 | + { |
| 313 | + return (T)ToObjectInternal(typeof(T)); |
| 314 | + } |
| 315 | + |
290 | 316 | public static T ParseToObject<T>(string jsonString) where T : new()
|
291 | 317 | {
|
292 | 318 | var deserializer = new JsonDeserializer();
|
@@ -332,24 +358,39 @@ static JsonValue NativeToJsonValue(object value)
|
332 | 358 | else if (value is DateTime?)
|
333 | 359 | result = (DateTime?)value;
|
334 | 360 | else if (value is TimeSpan)
|
335 |
| - result = ((TimeSpan)value).TotalSeconds; |
| 361 | + result = ((TimeSpan)value).ToString("c"); |
| 362 | + else if (value is Enum) |
| 363 | + result = ((Enum)value).ToString(); |
336 | 364 | else if (value as object == null)
|
337 | 365 | result = null;
|
338 | 366 | else if (value.GetType().IsClass)
|
339 | 367 | result = ObjectToJson(value);
|
340 | 368 | return result;
|
341 | 369 | }
|
342 | 370 |
|
343 |
| - public static JsonObject ObjectToJson(object obj) |
| 371 | + public static JsonValue ObjectToJson(object obj) |
344 | 372 | {
|
345 |
| - var result = new JsonObject(); |
346 |
| - foreach (var field in obj.GetType().GetFields()) |
347 |
| - result[field.Name] = NativeToJsonValue(field.GetValue(obj)); |
348 |
| - foreach (var prop in obj.GetType().GetProperties()) |
| 373 | + JsonValue result = null; |
| 374 | + var enumerable = obj as IEnumerable; |
| 375 | + if (enumerable != null) |
| 376 | + { |
| 377 | + var jsonArray = new JsonArray(); |
| 378 | + result = jsonArray; |
| 379 | + foreach (var enumObj in enumerable) |
| 380 | + jsonArray.Add(ObjectToJson(enumObj)); |
| 381 | + } |
| 382 | + else |
349 | 383 | {
|
350 |
| - if (prop.GetIndexParameters().Length > 0) |
351 |
| - continue; |
352 |
| - result[prop.Name] = NativeToJsonValue(prop.GetValue(obj)); |
| 384 | + var jsonObject = new JsonObject(); |
| 385 | + result = jsonObject; |
| 386 | + foreach (var field in obj.GetType().GetFields()) |
| 387 | + result[field.Name] = NativeToJsonValue(field.GetValue(obj)); |
| 388 | + foreach (var prop in obj.GetType().GetProperties()) |
| 389 | + { |
| 390 | + if (prop.GetIndexParameters().Length > 0) |
| 391 | + continue; |
| 392 | + result[prop.Name] = NativeToJsonValue(prop.GetValue(obj)); |
| 393 | + } |
353 | 394 | }
|
354 | 395 | return result;
|
355 | 396 | }
|
|
0 commit comments