private object CoerceType(Type targetType, IDictionary value, out Dictionary <string, MemberInfo> memberMap) { object newValue = this.InstantiateObject(targetType, out memberMap); if (memberMap != null) { // copy any values into new object foreach (object key in value.Keys) { MemberInfo memberInfo; Type memberType = TypeCoercionUtility.GetMemberInfo(memberMap, key as String, out memberInfo); this.SetMemberValue(newValue, memberType, memberInfo, value[key]); } } return(newValue); }
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 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 && 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})", objectType), this.index); } JsonToken jsonToken; while (true) { 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 (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 (objectType == null && this.Settings.IsTypeHintName(text)) { result = this.Settings.Coercion.ProcessTypeHint(dictionary, obj as string, out objectType, out memberMap); } else { dictionary[text] = obj; } } else { this.Settings.Coercion.SetMemberValue(result, type, memberInfo, obj); } jsonToken = this.Tokenize(); } if (jsonToken != JsonToken.ValueDelim) { goto IL_234; } } throw new JsonDeserializationException("Unterminated JSON object.", this.index); Block_5: goto IL_234; 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_234: if (jsonToken != JsonToken.ObjectEnd) { throw new JsonDeserializationException("Unterminated JSON object.", this.index); } this.index++; }
private void PopulateObject(ref object result, Type objectType, Dictionary <string, MemberInfo> memberMap, Type genericDictionaryType) { if (this.Source[this.index] != JsonReader.OperatorObjectStart) { throw new JsonDeserializationException(JsonReader.ErrorExpectedObject, this.index); } #if WINDOWS_PHONE IDictionary idict = result as IDictionary; #else IDictionary idict = result as IDictionary; if (idict == null && objectType.GetInterface(JsonReader.TypeGenericIDictionary) != null) { throw new JsonDeserializationException( String.Format(JsonReader.ErrorGenericIDictionary, objectType), this.index); } #endif JsonToken token; do { Type memberType; MemberInfo memberInfo; // consume opening brace or delim this.index++; if (this.index >= this.SourceLength) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } // get next token token = this.Tokenize(this.Settings.AllowUnquotedObjectKeys); if (token == JsonToken.ObjectEnd) { break; } if (token != JsonToken.String && token != JsonToken.UnquotedName) { throw new JsonDeserializationException(JsonReader.ErrorExpectedPropertyName, this.index); } // parse object member value string memberName = (token == JsonToken.String) ? (String)this.ReadString(null) : this.ReadUnquotedKey(); // if (genericDictionaryType == null && memberMap != null) { // determine the type of the property/field memberType = TypeCoercionUtility.GetMemberInfo(memberMap, memberName, out memberInfo); } else { memberType = genericDictionaryType; memberInfo = null; } // get next token token = this.Tokenize(); if (token != JsonToken.NameDelim) { throw new JsonDeserializationException(JsonReader.ErrorExpectedPropertyNameDelim, this.index); } // consume delim this.index++; if (this.index >= this.SourceLength) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } object value; // Reference to previously deserialized value if (Settings.HandleCyclicReferences && memberName == "@ref") { // parse object member value int refId = (int)this.Read(typeof(int), false); // Change result object to the one previously deserialized result = previouslyDeserialized[refId]; // get next token // this will probably be the end of the object token = this.Tokenize(); continue; } else { // Normal serialized value // parse object member value value = this.Read(memberType, false); } if (idict != null) { if (objectType == null && this.Settings.IsTypeHintName(memberName)) { result = this.Settings.Coercion.ProcessTypeHint(idict, value as string, out objectType, out memberMap); } else { idict[memberName] = value; } } else { this.Settings.Coercion.SetMemberValue(result, memberType, memberInfo, value); } // get next token token = this.Tokenize(); } while (token == JsonToken.ValueDelim); if (token != JsonToken.ObjectEnd) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } // consume closing brace this.index++; //return result; }
internal object CoerceType(Type targetType, object value) { bool isNullable = TypeCoercionUtility.IsNullable(targetType); if (value == null) { #if NETFX_CORE if (!allowNullValueTypes && targetType.IsValueType() && !isNullable) #else if (!allowNullValueTypes && targetType.IsValueType && !isNullable) #endif { throw new JsonTypeCoercionException(String.Format(TypeCoercionUtility.ErrorNullValueType, targetType.FullName)); } return(value); } if (isNullable) { // nullable types have a real underlying struct Type[] genericArgs = targetType.GetGenericArguments(); if (genericArgs.Length == 1) { targetType = genericArgs[0]; } } Type actualType = value.GetType(); if (targetType.IsAssignableFrom(actualType)) { return(value); } #if NETFX_CORE if (targetType.IsEnum()) #else if (targetType.IsEnum) #endif { if (value is String) { if (!Enum.IsDefined(targetType, value)) { // if isn't a defined value perhaps it is the JsonName foreach (FieldInfo field in targetType.GetFields()) { string jsonName = JsonNameAttribute.GetJsonName(field); if (((string)value).Equals(jsonName)) { value = field.Name; break; } } } return(Enum.Parse(targetType, (string)value)); } else { value = this.CoerceType(Enum.GetUnderlyingType(targetType), value); return(Enum.ToObject(targetType, value)); } } if (value is IDictionary) { Dictionary <string, MemberInfo> memberMap; return(this.CoerceType(targetType, (IDictionary)value, out memberMap)); } if (typeof(IEnumerable).IsAssignableFrom(targetType) && typeof(IEnumerable).IsAssignableFrom(actualType)) { return(this.CoerceList(targetType, actualType, (IEnumerable)value)); } if (value is String) { if (targetType == typeof(DateTime)) { DateTime date; if (DateTime.TryParse( (string)value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.RoundtripKind | DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault, out date)) { return(date); } } else if (targetType == typeof(Guid)) { // try-catch is pointless since will throw upon generic conversion return(new Guid((string)value)); } else if (targetType == typeof(Char)) { if (((string)value).Length == 1) { return(((string)value)[0]); } } else if (targetType == typeof(Uri)) { Uri uri; if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out uri)) { return(uri); } } else if (targetType == typeof(Version)) { // try-catch is pointless since will throw upon generic conversion return(new Version((string)value)); } } else if (targetType == typeof(TimeSpan)) { return(new TimeSpan((long)this.CoerceType(typeof(Int64), value))); } #if !WINDOWS_PHONE && !NETFX_CORE TypeConverter converter = TypeDescriptor.GetConverter(targetType); if (converter.CanConvertFrom(actualType)) { return(converter.ConvertFrom(value)); } converter = TypeDescriptor.GetConverter(actualType); if (converter.CanConvertTo(targetType)) { return(converter.ConvertTo(value, targetType)); } #endif try { // fall back to basics return(Convert.ChangeType(value, targetType)); } catch (Exception ex) { throw new JsonTypeCoercionException( String.Format("Error converting {0} to {1}", value.GetType().FullName, targetType.FullName), ex); } }
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); }
public Dictionary <string, MemberInfo> GetMemberMap(Type objectType) { if (TypeCoercionUtility.GetTypeInfo(typeof(IDictionary)).IsAssignableFrom(TypeCoercionUtility.GetTypeInfo(objectType))) { return(null); } return(this.CreateMemberMap(objectType)); }
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); } } }
private void PopulateObject(object result, Type objectType, Dictionary <string, MemberInfo> memberMap, Type genericDictionaryType) { if (this.Source[this.index] != JsonReader.OperatorObjectStart) { throw new JsonDeserializationException(JsonReader.ErrorExpectedObject, this.index); } JsonToken token; do { Type memberType; MemberInfo memberInfo; // consume opening brace or delim this.index++; if (this.index >= this.SourceLength) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } // get next token token = this.Tokenize(this.Settings.AllowUnquotedObjectKeys); if (token == JsonToken.ObjectEnd) { break; } if (token != JsonToken.String && token != JsonToken.UnquotedName) { throw new JsonDeserializationException(JsonReader.ErrorExpectedPropertyName, this.index); } // parse object member value string memberName = (token == JsonToken.String) ? (String)this.ReadString(null) : this.ReadUnquotedKey(); if (genericDictionaryType == null && memberMap != null) { // determine the type of the property/field memberType = TypeCoercionUtility.GetMemberInfo(memberMap, memberName, out memberInfo); } else { memberType = genericDictionaryType; memberInfo = null; } // get next token token = this.Tokenize(); if (token != JsonToken.NameDelim) { throw new JsonDeserializationException(JsonReader.ErrorExpectedPropertyNameDelim, this.index); } // consume delim this.index++; if (this.index >= this.SourceLength) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } // parse object member value object value = this.Read(memberType, false); if (result is IDictionary) { if (objectType == null && this.Settings.IsTypeHintName(memberName)) { result = this.Settings.Coercion.ProcessTypeHint((IDictionary)result, value as string, out objectType, out memberMap); } else { ((IDictionary)result)[memberName] = value; } } else if (objectType.GetInterface(JsonReader.TypeGenericIDictionary) != null) { throw new JsonDeserializationException( String.Format(JsonReader.ErrorGenericIDictionary, objectType), this.index); } else { this.Settings.Coercion.SetMemberValue(result, memberType, memberInfo, value); } // get next token token = this.Tokenize(); } while (token == JsonToken.ValueDelim); if (token != JsonToken.ObjectEnd) { throw new JsonDeserializationException(JsonReader.ErrorUnterminatedObject, this.index); } // consume closing brace this.index++; //return result; }
internal object CoerceType(Type targetType, object value) { bool isNullable = TypeCoercionUtility.IsNullable(targetType); if (value == null) { if (!allowNullValueTypes && TCU.GetTypeInfo(targetType).IsValueType&& !isNullable) { throw new JsonTypeCoercionException(String.Format(TypeCoercionUtility.ErrorNullValueType, new System.Object[] { targetType.FullName })); } return(value); } if (isNullable) { // nullable types have a real underlying struct Type[] genericArgs = targetType.GetGenericArguments(); if (genericArgs.Length == 1) { targetType = genericArgs[0]; } } Type actualType = value.GetType(); if (TCU.GetTypeInfo(targetType).IsAssignableFrom(TCU.GetTypeInfo(actualType))) { return(value); } if (TCU.GetTypeInfo(targetType).IsEnum) { if (value is String) { if (!Enum.IsDefined(targetType, value)) { // if isn't a defined value perhaps it is the JsonName foreach (FieldInfo field in TCU.GetTypeInfo(targetType).GetFields()) { string jsonName = JsonNameAttribute.GetJsonName(field); if (((string)value).Equals(jsonName)) { value = field.Name; break; } } } return(Enum.Parse(targetType, (string)value)); } else { value = this.CoerceType(Enum.GetUnderlyingType(targetType), value); return(Enum.ToObject(targetType, value)); } } // Value is of the wrong type and it has been deserialized as an IDictionary. // Previously coercion was supported // but this generally just caused more problems than it solved, so type hints are recommended now. // More specifically this can cause annoying problems with tags when a tag is referencing some object // for which there is no type info for (e.g the field has been removed), that data would have been // deserialized as an IDictionary, but when the tag gets the information it will try to coerce it // which will often fail horribly if (value is IDictionary) { return(null); // Dictionary<string, MemberInfo> memberMap; // return this.CoerceType(targetType, (IDictionary)value, out memberMap); } if (TCU.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TCU.GetTypeInfo(targetType)) && TCU.GetTypeInfo(typeof(IEnumerable)).IsAssignableFrom(TCU.GetTypeInfo(actualType))) { return(this.CoerceList(targetType, actualType, (IEnumerable)value)); } if (value is String) { if (Type.Equals(targetType, typeof(DateTime))) { DateTime date; if (DateTime.TryParse( (string)value, DateTimeFormatInfo.InvariantInfo, DateTimeStyles.RoundtripKind | DateTimeStyles.AllowWhiteSpaces | DateTimeStyles.NoCurrentDateDefault, out date)) { return(date); } } else if (Type.Equals(targetType, typeof(Guid))) { // try-catch is pointless since will throw upon generic conversion return(new Guid((string)value)); } else if (Type.Equals(targetType, typeof(Char))) { if (((string)value).Length == 1) { return(((string)value)[0]); } } else if (Equals(targetType, typeof(Uri))) { Uri uri; if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out uri)) { return(uri); } } else if (Type.Equals(targetType, typeof(Version))) { // try-catch is pointless since will throw upon generic conversion return(new Version((string)value)); } } else if (Type.Equals(targetType, typeof(TimeSpan))) { return(new TimeSpan((long)this.CoerceType(typeof(Int64), value))); } #if !WINPHONE_8 TypeConverter converter = TypeDescriptor.GetConverter(targetType); if (converter.CanConvertFrom(actualType)) { return(converter.ConvertFrom(value)); } converter = TypeDescriptor.GetConverter(actualType); if (converter.CanConvertTo(targetType)) { return(converter.ConvertTo(value, targetType)); } #endif try { // fall back to basics return(Convert.ChangeType(value, targetType)); } catch (Exception ex) { throw new JsonTypeCoercionException( String.Format("Error converting {0} to {1}", new System.Object[] { value.GetType().FullName, targetType.FullName }), ex); } }