public static string GetJsonName(object value) { if (value == null) { return(null); } Type type = value.GetType(); MemberInfo memberInfo; if (TypeCoercionUtility.GetTypeInfo(type).IsEnum) { string name = Enum.GetName(type, value); if (string.IsNullOrEmpty(name)) { return(null); } memberInfo = TypeCoercionUtility.GetTypeInfo(type).GetField(name); } else { memberInfo = (value as MemberInfo); } if (object.Equals(memberInfo, null)) { throw new ArgumentException(); } JsonNameAttribute jsonNameAttribute = Attribute.GetCustomAttribute(memberInfo, typeof(JsonNameAttribute)) as JsonNameAttribute; return((jsonNameAttribute == null) ? null : jsonNameAttribute.Name); }
public Dictionary <string, MemberInfo> GetMemberMap(Type objectType) { if (TypeCoercionUtility.GetTypeInfo(typeof(IDictionary)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(objectType))) { return(null); } return(this.CreateMemberMap(objectType)); }
private Dictionary <string, MemberInfo> CreateMemberMap(Type objectType) { Dictionary <string, MemberInfo> dictionary; if (this.MemberMapCache.TryGetValue(objectType, out dictionary)) { return(dictionary); } dictionary = new Dictionary <string, MemberInfo>(); for (Type type = objectType; type != null; type = type.BaseType) { foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (propertyInfo.CanRead && propertyInfo.CanWrite) { if (!JsonIgnoreAttribute.IsJsonIgnore(propertyInfo)) { string jsonName = JsonNameAttribute.GetJsonName(propertyInfo); if (string.IsNullOrEmpty(jsonName)) { dictionary[propertyInfo.Name] = propertyInfo; } else { dictionary[jsonName] = propertyInfo; } } } } FieldInfo[] fields = TypeCoercionUtility.GetTypeInfo(objectType).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.IsPublic || fieldInfo.GetCustomAttributes(typeof(JsonMemberAttribute), true).Length != 0) { if (!JsonIgnoreAttribute.IsJsonIgnore(fieldInfo)) { string jsonName2 = JsonNameAttribute.GetJsonName(fieldInfo); if (string.IsNullOrEmpty(jsonName2)) { dictionary[fieldInfo.Name] = fieldInfo; } else { dictionary[jsonName2] = fieldInfo; } } } } } this.MemberMapCache[objectType] = dictionary; return(dictionary); }
public static bool IsJsonIgnore(object value) { if (value == null) { return(false); } Type type = value.GetType(); ICustomAttributeProvider customAttributeProvider; if (TypeCoercionUtility.GetTypeInfo(type).IsEnum) { customAttributeProvider = TypeCoercionUtility.GetTypeInfo(type).GetField(Enum.GetName(type, value)); } else { customAttributeProvider = (value as ICustomAttributeProvider); } if (customAttributeProvider == null) { throw new ArgumentException(); } return(customAttributeProvider.IsDefined(typeof(JsonIgnoreAttribute), true)); }
private Type GetGenericDictionaryType(Type objectType) { Type @interface = TypeCoercionUtility.GetTypeInfo(objectType).GetInterface(JsonReader.TypeGenericIDictionary); if (@interface != null) { Type[] genericArguments = @interface.GetGenericArguments(); if (genericArguments.Length == 2) { if (!object.Equals(genericArguments[0], typeof(string))) { throw new JsonDeserializationException(string.Format("Types which implement Generic IDictionary<TKey, TValue> need to have string keys to be deserialized. ({0})", new object[] { objectType }), this.index); } if (!object.Equals(genericArguments[1], typeof(object))) { return(genericArguments[1]); } } } return(null); }
private IEnumerable ReadArray(Type arrayType) { if (this.Source[this.index] != '[') { throw new JsonDeserializationException("Expected JSON array.", this.index); } bool flag = !object.Equals(arrayType, null); bool typeIsHint = !flag; Type type = null; if (flag) { if (arrayType.HasElementType) { type = arrayType.GetElementType(); } else if (TypeCoercionUtility.GetTypeInfo(arrayType).IsGenericType) { Type[] genericArguments = arrayType.GetGenericArguments(); if (genericArguments.Length == 1) { type = genericArguments[0]; } } } List <object> list = (this.jsArrays.Count <= 0) ? new List <object>() : this.jsArrays.Pop(); list.Clear(); JsonToken jsonToken; for (;;) { this.index++; if (this.index >= this.SourceLength) { break; } jsonToken = this.Tokenize(); if (jsonToken == JsonToken.ArrayEnd) { goto Block_8; } object obj = this.Read(type, typeIsHint); list.Add(obj); if (obj == null) { if (!object.Equals(type, null) && TypeCoercionUtility.GetTypeInfo(type).IsValueType) { type = null; } flag = true; } else if (!object.Equals(type, null) && !TypeCoercionUtility.GetTypeInfo(type).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(obj.GetType()))) { if (TypeCoercionUtility.GetTypeInfo(obj.GetType()).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(type))) { type = obj.GetType(); } else { type = null; flag = true; } } else if (!flag) { type = obj.GetType(); flag = true; } jsonToken = this.Tokenize(); if (jsonToken != JsonToken.ValueDelim) { goto IL_1AB; } } throw new JsonDeserializationException("Unterminated JSON array.", this.index); Block_8: IL_1AB: if (jsonToken != JsonToken.ArrayEnd) { throw new JsonDeserializationException("Unterminated JSON array.", this.index); } this.index++; this.jsArrays.Push(list); if (object.Equals(type, null) || object.Equals(type, typeof(object))) { return(list.ToArray()); } if (arrayType != null && arrayType.IsGenericType && object.Equals(arrayType.GetGenericTypeDefinition(), typeof(List <>))) { IList list2 = Activator.CreateInstance(arrayType, new object[] { list.Count }) as IList; for (int i = 0; i < list.Count; i++) { list2.Add(list[i]); } return(list2); } Array array = Array.CreateInstance(type, new int[] { list.Count }); for (int j = 0; j < list.Count; j++) { array.SetValue(list[j], new int[] { j }); } return(array); }
private void PopulateObject(ref object result, Type objectType, Dictionary <string, MemberInfo> memberMap, Type genericDictionaryType) { if (this.Source[this.index] != '{') { throw new JsonDeserializationException("Expected JSON object.", this.index); } IDictionary dictionary = result as IDictionary; if (dictionary == null && !object.Equals(TypeCoercionUtility.GetTypeInfo(objectType).GetInterface(JsonReader.TypeGenericIDictionary), null)) { throw new JsonDeserializationException(string.Format("Types which implement Generic IDictionary<TKey, TValue> also need to implement IDictionary to be deserialized. ({0})", new object[] { objectType }), this.index); } JsonToken jsonToken; for (;;) { this.index++; if (this.index >= this.SourceLength) { break; } jsonToken = this.Tokenize(this.Settings.AllowUnquotedObjectKeys); if (jsonToken == JsonToken.ObjectEnd) { goto Block_5; } if (jsonToken != JsonToken.String && jsonToken != JsonToken.UnquotedName) { goto Block_7; } string text = (jsonToken != JsonToken.String) ? this.ReadUnquotedKey() : ((string)this.ReadString(null)); MemberInfo memberInfo; Type type; if (object.Equals(genericDictionaryType, null) && memberMap != null) { type = TypeCoercionUtility.GetMemberInfo(memberMap, text, out memberInfo); } else { type = genericDictionaryType; memberInfo = null; } jsonToken = this.Tokenize(); if (jsonToken != JsonToken.NameDelim) { goto Block_11; } this.index++; if (this.index >= this.SourceLength) { goto Block_12; } if (this.Settings.HandleCyclicReferences && text == "@ref") { int num = (int)this.Read(typeof(int), false); result = this.previouslyDeserialized[num]; jsonToken = this.Tokenize(); } else { object obj = this.Read(type, false); if (dictionary != null) { if (object.Equals(objectType, null) && this.Settings.IsTypeHintName(text)) { result = this.Settings.Coercion.ProcessTypeHint(dictionary, obj as string, out objectType, out memberMap); } else { dictionary[text] = obj; } } else if (this.Settings.IsTypeHintName(text)) { result = this.Settings.Coercion.ProcessTypeHint(result, obj as string, out objectType, out memberMap); } else { this.Settings.Coercion.SetMemberValue(result, type, memberInfo, obj); } jsonToken = this.Tokenize(); } if (jsonToken != JsonToken.ValueDelim) { goto IL_28A; } } throw new JsonDeserializationException("Unterminated JSON object.", this.index); Block_5: goto IL_28A; Block_7: throw new JsonDeserializationException("Expected JSON object property name.", this.index); Block_11: throw new JsonDeserializationException("Expected JSON object property name delimiter.", this.index); Block_12: throw new JsonDeserializationException("Unterminated JSON object.", this.index); IL_28A: if (jsonToken != JsonToken.ObjectEnd) { throw new JsonDeserializationException("Unterminated JSON object.", this.index); } this.index++; }
private static bool IsNullable(Type type) { return(TypeCoercionUtility.GetTypeInfo(type).IsGenericType&& typeof(Nullable <>).Equals(type.GetGenericTypeDefinition())); }
private object CoerceList(Type targetType, Type arrayType, IEnumerable value) { if (targetType.IsArray) { return(this.CoerceArray(targetType.GetElementType(), value)); } ConstructorInfo[] constructors = targetType.GetConstructors(); ConstructorInfo constructorInfo = null; foreach (ConstructorInfo constructorInfo2 in constructors) { ParameterInfo[] parameters = constructorInfo2.GetParameters(); if (parameters.Length == 0) { constructorInfo = constructorInfo2; } else if (parameters.Length == 1 && TypeCoercionUtility.GetTypeInfo(parameters[0].ParameterType).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(arrayType))) { try { return(constructorInfo2.Invoke(new object[] { value })); } catch { } } } if (object.Equals(constructorInfo, null)) { throw new JsonTypeCoercionException(string.Format("Only objects with default constructors can be deserialized. ({0})", new object[] { targetType.FullName })); } object obj; try { obj = constructorInfo.Invoke(null); } catch (TargetInvocationException ex) { if (ex.InnerException != null) { throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException); } throw new JsonTypeCoercionException("Error instantiating " + targetType.FullName, ex); } MethodInfo method = TypeCoercionUtility.GetTypeInfo(targetType).GetMethod("AddRange"); ParameterInfo[] array2 = (!object.Equals(method, null)) ? method.GetParameters() : null; Type type = (array2 != null && array2.Length == 1) ? array2[0].ParameterType : null; if (!object.Equals(type, null) && TypeCoercionUtility.GetTypeInfo(type).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(arrayType))) { try { method.Invoke(obj, new object[] { value }); } catch (TargetInvocationException ex2) { if (ex2.InnerException != null) { throw new JsonTypeCoercionException(ex2.InnerException.Message, ex2.InnerException); } throw new JsonTypeCoercionException("Error calling AddRange on " + targetType.FullName, ex2); } return(obj); } method = TypeCoercionUtility.GetTypeInfo(targetType).GetMethod("Add"); array2 = ((!object.Equals(method, null)) ? method.GetParameters() : null); type = ((array2 != null && array2.Length == 1) ? array2[0].ParameterType : null); if (!object.Equals(type, null)) { IEnumerator enumerator = value.GetEnumerator(); try { while (enumerator.MoveNext()) { object value2 = enumerator.Current; try { method.Invoke(obj, new object[] { this.CoerceType(type, value2) }); } catch (TargetInvocationException ex3) { if (ex3.InnerException != null) { throw new JsonTypeCoercionException(ex3.InnerException.Message, ex3.InnerException); } throw new JsonTypeCoercionException("Error calling Add on " + targetType.FullName, ex3); } } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } return(obj); } object result; try { result = Convert.ChangeType(value, targetType); } catch (Exception innerException) { throw new JsonTypeCoercionException(string.Format("Error converting {0} to {1}", new object[] { value.GetType().FullName, targetType.FullName }), innerException); } return(result); }
internal object CoerceType(Type targetType, object value) { bool flag = TypeCoercionUtility.IsNullable(targetType); if (value == null) { if (!this.allowNullValueTypes && TypeCoercionUtility.GetTypeInfo(targetType).IsValueType&& !flag) { throw new JsonTypeCoercionException(string.Format("{0} does not accept null as a value", new object[] { targetType.FullName })); } return(value); } else { if (flag) { Type[] genericArguments = targetType.GetGenericArguments(); if (genericArguments.Length == 1) { targetType = genericArguments[0]; } } Type type = value.GetType(); if (TypeCoercionUtility.GetTypeInfo(targetType).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(type))) { return(value); } if (TypeCoercionUtility.GetTypeInfo(targetType).IsEnum) { if (value is string) { if (!Enum.IsDefined(targetType, value)) { foreach (FieldInfo fieldInfo in TypeCoercionUtility.GetTypeInfo(targetType).GetFields()) { string jsonName = JsonNameAttribute.GetJsonName(fieldInfo); if (((string)value).Equals(jsonName)) { value = fieldInfo.Name; break; } } } return(Enum.Parse(targetType, (string)value)); } value = this.CoerceType(Enum.GetUnderlyingType(targetType), value); return(Enum.ToObject(targetType, value)); } else { if (value is IDictionary) { Dictionary <string, MemberInfo> dictionary; return(this.CoerceType(targetType, (IDictionary)value, out dictionary)); } if (TypeCoercionUtility.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(targetType)) && TypeCoercionUtility.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(type))) { return(this.CoerceList(targetType, type, (IEnumerable)value)); } if (value is string) { if (object.Equals(targetType, typeof(DateTime))) { DateTime dateTime; if (DateTime.TryParse((string)value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite | DateTimeStyles.AllowInnerWhite | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.RoundtripKind, out dateTime)) { return(dateTime); } } else { if (object.Equals(targetType, typeof(Guid))) { return(new Guid((string)value)); } if (object.Equals(targetType, typeof(char))) { if (((string)value).Length == 1) { return(((string)value)[0]); } } else if (object.Equals(targetType, typeof(Uri))) { Uri result; if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out result)) { return(result); } } else if (object.Equals(targetType, typeof(Version))) { return(new Version((string)value)); } } } else if (object.Equals(targetType, typeof(TimeSpan))) { return(new TimeSpan((long)this.CoerceType(typeof(long), value))); } TypeConverter converter = TypeDescriptor.GetConverter(targetType); if (converter.CanConvertFrom(type)) { return(converter.ConvertFrom(value)); } converter = TypeDescriptor.GetConverter(type); if (converter.CanConvertTo(targetType)) { return(converter.ConvertTo(value, targetType)); } object result2; try { result2 = Convert.ChangeType(value, targetType); } catch (Exception innerException) { throw new JsonTypeCoercionException(string.Format("Error converting {0} to {1}", new object[] { value.GetType().FullName, targetType.FullName }), innerException); } return(result2); } } }