Skip to content
This repository was archived by the owner on Dec 22, 2023. It is now read-only.

Commit e04fe11

Browse files
committed
add support for Array and Enum in JsonValue.ToObject
1 parent 7273caf commit e04fe11

File tree

1 file changed

+70
-29
lines changed

1 file changed

+70
-29
lines changed

Erasme.Http/Erasme.Json/JsonValue.cs

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
using System.Text;
3333
using System.Dynamic;
3434
using System.Collections.Generic;
35+
using System.Collections;
3536

3637
namespace Erasme.Json
3738
{
@@ -259,34 +260,59 @@ public static void Merge(JsonValue dest, JsonValue source)
259260
}
260261
}
261262

262-
public T ToObject<T>() where T : new()
263+
object ToObjectInternal(Type type)
263264
{
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)
266276
{
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+
}
275292
}
276-
foreach (var prop in typeof(T).GetProperties())
293+
else if (this is JsonArray)
277294
{
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+
}
286307
}
287308
return result;
288309
}
289310

311+
public T ToObject<T>() where T : new()
312+
{
313+
return (T)ToObjectInternal(typeof(T));
314+
}
315+
290316
public static T ParseToObject<T>(string jsonString) where T : new()
291317
{
292318
var deserializer = new JsonDeserializer();
@@ -332,24 +358,39 @@ static JsonValue NativeToJsonValue(object value)
332358
else if (value is DateTime?)
333359
result = (DateTime?)value;
334360
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();
336364
else if (value as object == null)
337365
result = null;
338366
else if (value.GetType().IsClass)
339367
result = ObjectToJson(value);
340368
return result;
341369
}
342370

343-
public static JsonObject ObjectToJson(object obj)
371+
public static JsonValue ObjectToJson(object obj)
344372
{
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
349383
{
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+
}
353394
}
354395
return result;
355396
}

0 commit comments

Comments
 (0)