public static void DeserializeFields <Attr>(this object model, JObject jObject, GDeserializeSettings settings = null) where Attr : Attribute { if (settings == null) { settings = new GDeserializeSettings(); } settings.preHandler += (object handleModel, FieldInfo fieldInfo, ref bool skip) => { var editorAttribute = fieldInfo.GetCustomAttribute(typeof(Attr)) as Attr; if (editorAttribute == null) { skip = true; } }; DeserializeFields(model, jObject, settings); }
public static void DeserializeFields(this object model, JObject jObject, GDeserializeSettings settings = null) { if (model == null) { return; } var fields = model.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance).OrderBy(field => field.MetadataToken).ToArray(); foreach (var fieldInfo in fields) { var preSkip = false; settings?.preHandler?.Invoke(model, fieldInfo, ref preSkip); if (preSkip) { continue; } if (!jObject.ContainsKey(fieldInfo.Name)) { continue; } if (fieldInfo.FieldType.IsValueType && !fieldInfo.FieldType.IsEnum && !fieldInfo.FieldType.IsPrimitive) { // Struct var jField = jObject.GetValue(fieldInfo.Name) as JObject; if (jField == null) { continue; } var useDefaultHandler = true; object field = null; if (settings?.memberHandler != null) { useDefaultHandler = !settings.memberHandler.Invoke(model, fieldInfo, out field); } if (useDefaultHandler) { field = Activator.CreateInstance(fieldInfo.FieldType); field.DeserializeFields(jField); } fieldInfo.SetValue(model, field); } else if (fieldInfo.FieldType.IsClass && fieldInfo.FieldType != typeof(string)) { // Class var jFieldToken = jObject.GetValue(fieldInfo.Name); if (jFieldToken == null) { continue; } var useDefaultHandler = true; object field = null; if (settings?.memberHandler != null) { useDefaultHandler = !settings.memberHandler.Invoke(model, fieldInfo, out field); } if (useDefaultHandler) { if (typeof(IEnumerable).IsAssignableFrom(fieldInfo.FieldType)) { fieldInfo.SetValue(model, JsonConvert.DeserializeObject(jFieldToken.ToString(), fieldInfo.FieldType)); } else if (jFieldToken is JObject) { field = Activator.CreateInstance(fieldInfo.FieldType); field.DeserializeFields(jFieldToken as JObject); } } if (field != null) { fieldInfo.SetValue(model, field); } } else if (fieldInfo.FieldType == typeof(string) || fieldInfo.FieldType.IsEnum || fieldInfo.FieldType.IsPrimitive) { // Enum or String or Primitive var stringValue = jObject.GetValue <string>(fieldInfo.Name); if (fieldInfo.FieldType.IsEnum) { fieldInfo.SetValue(model, Enum.Parse(fieldInfo.FieldType, stringValue)); } else { fieldInfo.SetValue(model, Convert.ChangeType(stringValue, fieldInfo.FieldType)); } } } }