Utility for forcing conversion between types
Exemple #1
0
        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);
        }
Exemple #2
0
        internal object CoerceType(Type targetType, IDictionary newValues, object existingObject, out Dictionary <string, MemberInfo> memberMap)
        {
            // don't incurr the cost of member map for dictionaries
            if (typeof(IDictionary).IsAssignableFrom(targetType) && existingObject is IDictionary)
            {
                memberMap = null;
            }
            else
            {
                memberMap = this.CreateMemberMap(targetType);
            }

            if (memberMap != null)
            {
                // copy any values into new object
                foreach (object key in newValues.Keys)
                {
                    MemberInfo memberInfo;
                    Type       memberType = TypeCoercionUtility.GetMemberInfo(memberMap, key as String, out memberInfo);
                    this.SetMemberValue(existingObject, memberType, memberInfo, newValues[key]);
                }
            }
            else
            {
                // set the values
                IDictionary newValueDictionary = existingObject as IDictionary;

                if (newValueDictionary == null)
                {
                    return(existingObject);
                }

                foreach (object key in newValues.Keys)
                {
                    newValueDictionary[key as string] = newValues[key];
                }
            }
            return(existingObject);
        }
Exemple #3
0
        private object CoerceList(Type targetType, Type arrayType, IEnumerable value)
        {
            if (targetType.IsArray)
            {
                return(this.CoerceArray(targetType.GetElementType(), value));
            }

            // targetType serializes as a JSON array but is not an array
            // assume is an ICollection / IEnumerable with AddRange, Add,
            // or custom Constructor with which we can populate it

            // many ICollection types take an IEnumerable or ICollection
            // as a constructor argument.  look through constructors for
            // a compatible match.
            ConstructorInfo[] ctors       = targetType.GetConstructors();
            ConstructorInfo   defaultCtor = null;

            foreach (ConstructorInfo ctor in ctors)
            {
                ParameterInfo[] paramList = ctor.GetParameters();
                if (paramList.Length == 0)
                {
                    // save for in case cannot find closer match
                    defaultCtor = ctor;
                    continue;
                }

                if (paramList.Length == 1 &&
                    paramList[0].ParameterType.IsAssignableFrom(arrayType))
                {
                    try
                    {
                        // invoke first constructor that can take this value as an argument
                        return(ctor.Invoke(
                                   new object[] { value }
                                   ));
                    }
                    catch
                    {
                        // there might exist a better match
                        continue;
                    }
                }
            }

            if (defaultCtor == null)
            {
                throw new JsonTypeCoercionException(
                          String.Format(TypeCoercionUtility.ErrorDefaultCtor, targetType.FullName));
            }
            object collection;

            try
            {
                // always try-catch Invoke() to expose real exception
                collection = defaultCtor.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);
            }

            // many ICollection types have an AddRange method
            // which adds all items at once
            MethodInfo method = targetType.GetMethod("AddRange");

            ParameterInfo[] parameters = (method == null) ?
                                         null : method.GetParameters();
            Type paramType = (parameters == null || parameters.Length != 1) ?
                             null : parameters[0].ParameterType;

            if (paramType != null &&
                paramType.IsAssignableFrom(arrayType))
            {
                try
                {
                    // always try-catch Invoke() to expose real exception
                    // add all members in one method
                    method.Invoke(
                        collection,
                        new object[] { value });
                }
                catch (TargetInvocationException ex)
                {
                    if (ex.InnerException != null)
                    {
                        throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException);
                    }
                    throw new JsonTypeCoercionException("Error calling AddRange on " + targetType.FullName, ex);
                }
                return(collection);
            }
            else
            {
                // many ICollection types have an Add method
                // which adds items one at a time
                method     = targetType.GetMethod("Add");
                parameters = (method == null) ?
                             null : method.GetParameters();
                paramType = (parameters == null || parameters.Length != 1) ?
                            null : parameters[0].ParameterType;
                if (paramType != null)
                {
                    var enumerator = TypeCoercionUtility.GetEnumerator(value);

                    if (enumerator == null)
                    {
                        throw new JsonTypeCoercionException(string.Format("Requested to get an IEnumerator of a value that doesn't implement the IEnumerable interface.\nValue: {0}\nValue's type: {1}", value, value.GetType().FullName));
                    }

                    while (enumerator.MoveNext())
                    {
                        // loop through adding items to collection
                        object item = enumerator.Current;
                        try
                        {
                            // always try-catch Invoke() to expose real exception
                            method.Invoke(
                                collection,
                                new object[] {
                                this.CoerceType(paramType, item)
                            });
                        }
                        catch (TargetInvocationException ex)
                        {
                            if (ex.InnerException != null)
                            {
                                throw new JsonTypeCoercionException(ex.InnerException.Message, ex.InnerException);
                            }
                            throw new JsonTypeCoercionException("Error calling Add on " + targetType.FullName, ex);
                        }
                    }

                    IDisposable disposable = enumerator as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                    }

                    return(collection);
                }
            }

            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);
            }
        }
Exemple #4
0
        internal object CoerceType(Type targetType, object value)
        {
            bool isNullable = TypeCoercionUtility.IsNullable(targetType);

            if (value == null)
            {
                if (!allowNullValueTypes &&
                    targetType.IsValueType &&
                    !isNullable)
                {
                    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 (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 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 this is a crazy server date string, clean up the server junk.
                    if (((string)value).StartsWith("/Date(") && ((string)value).EndsWith(")/"))
                    {
                        date  = new DateTime(1970, 1, 1, 0, 0, 0, 0);
                        value = ((string)value).Replace("/Date(", "").Replace(")/", "").Replace("+0000", "");
                        date  = date.AddMilliseconds(long.Parse((string)value));
                        return(date);
                    }

                    // Try a regular DateTime parse
                    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)));
            }

            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));
            }

            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);
            }
        }
Exemple #5
0
        protected virtual object ReadObject(Type objectType)
        {
            if (Source[index] != '{')
            {
                throw new JsonDeserializationException("Expected JSON object.", index);
            }
            Type type = null;
            Dictionary <string, MemberInfo> memberMap = null;
            object obj;

            if (objectType != null)
            {
                obj = Settings.Coercion.InstantiateObject(objectType, out memberMap);
                if (memberMap == null)
                {
                    Type @interface = objectType.GetInterface("System.Collections.Generic.IDictionary`2");
                    if (@interface != null)
                    {
                        Type[] genericArguments = @interface.GetGenericArguments();
                        if (genericArguments.Length == 2)
                        {
                            if (genericArguments[0] != typeof(string))
                            {
                                throw new JsonDeserializationException($"Types which implement Generic IDictionary<TKey, TValue> need to have string keys to be deserialized. ({objectType})", index);
                            }
                            if (genericArguments[1] != typeof(object))
                            {
                                type = genericArguments[1];
                            }
                        }
                    }
                }
            }
            else
            {
                obj = new Dictionary <string, object>();
            }
            JsonToken jsonToken;

            do
            {
                index++;
                if (index >= SourceLength)
                {
                    throw new JsonDeserializationException("Unterminated JSON object.", index);
                }
                jsonToken = Tokenize(Settings.AllowUnquotedObjectKeys);
                switch (jsonToken)
                {
                default:
                    throw new JsonDeserializationException("Expected JSON object property name.", index);

                case JsonToken.String:
                case JsonToken.UnquotedName:
                {
                    string     text = ((jsonToken != JsonToken.String) ? ReadUnquotedKey() : ((string)ReadString(null)));
                    Type       type2;
                    MemberInfo memberInfo;
                    if (type == null && memberMap != null)
                    {
                        type2 = TypeCoercionUtility.GetMemberInfo(memberMap, text, out memberInfo);
                    }
                    else
                    {
                        type2      = type;
                        memberInfo = null;
                    }
                    jsonToken = Tokenize();
                    if (jsonToken != JsonToken.NameDelim)
                    {
                        throw new JsonDeserializationException("Expected JSON object property name delimiter.", index);
                    }
                    index++;
                    if (index >= SourceLength)
                    {
                        throw new JsonDeserializationException("Unterminated JSON object.", index);
                    }
                    object obj2 = Read(type2, typeIsHint: false);
                    if (obj is IDictionary)
                    {
                        if (objectType == null && Settings.IsTypeHintName(text))
                        {
                            obj = Settings.Coercion.ProcessTypeHint((IDictionary)obj, obj2 as string, out objectType, out memberMap);
                        }
                        else
                        {
                            ((IDictionary)obj)[text] = obj2;
                        }
                    }
                    else
                    {
                        if (objectType.GetInterface("System.Collections.Generic.IDictionary`2") != null)
                        {
                            throw new JsonDeserializationException($"Types which implement Generic IDictionary<TKey, TValue> also need to implement IDictionary to be deserialized. ({objectType})", index);
                        }
                        Settings.Coercion.SetMemberValue(obj, type2, memberInfo, obj2);
                    }
                    goto IL_0270;
                }

                case JsonToken.ObjectEnd:
                    break;
                }
                break;
IL_0270:
                jsonToken = Tokenize();
            }while (jsonToken == JsonToken.ValueDelim);
            if (jsonToken != JsonToken.ObjectEnd)
            {
                throw new JsonDeserializationException("Unterminated JSON object.", index);
            }
            index++;
            return(obj);
        }
        internal object CoerceType(Type targetType, object value)
        {
            bool isNullable = TypeCoercionUtility.IsNullable(targetType);

            if (value == null)
            {
                if (!allowNullValueTypes &&
                    targetType.IsValueType &&
                    !isNullable)
                {
                    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 (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 targetType.GetFields())
                        {
                            string jsonName = JsonNameAttribute.GetJsonName(field);
                            if (((string)value).Equals(jsonName))
                            {
                                value = field.Name;
                                break;
                            }
                        }
                    }
                    //Julien: Added check for enums (previously didn't have try catch and wasn't case-insensitive)
                    //we don't want JSONFx to entirely abandon the parsing just because the user badly entered an enum
                    //instead just return null
                    object output;
                    try
                    {
                        output = Enum.Parse(targetType, (string)value, true);
                    }
                    catch (ArgumentException)
                    {
                        //If value is 'null', handle that gracefully.  Can happen when enum is stored as string on other end, e.g. w/ DBs
                        if (((string)value).ToLower() != "null")
                        {
                            UnityEngine.Debug.LogWarning("JSONFx could not parse '" + (string)value + "' as a(n) " + targetType.ToString());
                        }

                        //output = Activator.CreateInstance(targetType); //if we want to return the default for this enum
                        output = null;
                    }
                    return(output);
                }
                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)));
            }
            //Julien: Added to be able to deserialize times in epoch format
            //Commented because of inconsistencies: Java uses milliseconds & .NET uses ticks
            //else if (targetType == typeof(DateTime) && value is Decimal)
            //{
            //    return new DateTime((long)this.CoerceType(typeof(Int64), value));
            //}

            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));
            }

            try
            {
                // fall back to basics
                return(Convert.ChangeType(value, targetType));
            }
            catch (Exception ex)
            {
                throw new JsonTypeCoercionException(
                          String.Format("Error converting {0} to {1} for value: " + value.ToString(), value.GetType().FullName, targetType.FullName), ex);
            }
        }
Exemple #7
0
        internal object CoerceType(Type targetType, object value)
        {
            bool isNullable = TypeCoercionUtility.IsNullable(targetType);

            if (value == null)
            {
                if (!allowNullValueTypes &&
                    targetType.IsValueType &&
                    !isNullable)
                {
                    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 (targetType.IsEnum)
            {
                if (value is String)
                {
                    // AKS: Try to parse enum's for upper-case too, since we always serialize as lower-case
                    if (Enum.IsDefined(targetType, value))
                    {
                        return(Enum.Parse(targetType, (string)value));
                    }
                    if (Enum.IsDefined(targetType, ((string)value).ToUpper()))
                    {
                        return(Enum.Parse(targetType, ((string)value).ToUpper()));
                    }
                    // 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 (targetType.IsPrimitive == false && targetType != typeof(string))
//			{
//				ConstructorInfo jsonConstructor = targetType.GetConstructors().FirstOrDefault(x => Attribute.IsDefined(x, typeof(JsonConstructor), true));
//				if (jsonConstructor != null && jsonConstructor.GetParameters().Count() == 1)
//				{
//					Console.Write("JsonConstructor! " + targetType.Name);
//					Type constructorArgType = jsonConstructor.GetParameters()[0].ParameterType;
//					return jsonConstructor.Invoke(new object[] { CoerceType(constructorArgType, value) });
//				}
//
//				MethodInfo jsonFactory = targetType.GetMethods().FirstOrDefault(x => Attribute.IsDefined(x, typeof(JsonFactoryMethod), true));
//				if (jsonFactory != null && jsonFactory.GetParameters().Count() == 1)
//				{
//					Console.Write("JsonFactory! " + targetType.Name);
//					Type factoryArgType = jsonFactory.GetParameters()[0].ParameterType;
//					return jsonFactory.Invoke(null, new object[] { CoerceType(factoryArgType, 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)));
            }

            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));
            }

            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);
            }
        }
Exemple #8
0
        protected virtual void WriteObject(object value, Type type)
        {
            bool appendDelim = false;

            this.Writer.Write(JsonReader.OperatorObjectStart);

            this.depth++;
            if (this.depth > this.settings.MaxDepth)
            {
                throw new JsonSerializationException(String.Format(JsonWriter.ErrorMaxDepth, this.settings.MaxDepth));
            }
            try
            {
                if (!String.IsNullOrEmpty(this.settings.TypeHintName))
                {
                    if (appendDelim)
                    {
                        this.WriteObjectPropertyDelim();
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    this.WriteObjectProperty(this.settings.TypeHintName, type.FullName + ", " + type.Assembly.GetName().Name);
                }

#if JSONFX_SERIALIZE_PROPERTIES
                bool anonymousType = type.IsGenericType && type.Name.StartsWith(JsonWriter.AnonymousTypePrefix);
                // serialize public properties
                IList <PropertyInfo> properties = TypeCoercionUtility.GetAllProperties(type);
//				PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    if (!property.CanRead)
                    {
                        continue;
                    }

                    if (!property.CanWrite && !anonymousType)
                    {
                        continue;
                    }

                    if (this.IsIgnored(type, property, value))
                    {
                        continue;
                    }

                    if (property.PropertyType == typeof(Action))
                    {
                        continue;
                    }

                    object propertyValue = property.GetValue(value, null);
                    if (this.IsDefaultValue(property, propertyValue))
                    {
                        continue;
                    }

                    if (appendDelim)
                    {
                        this.WriteObjectPropertyDelim();
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    // use Attributes here to control naming
                    string propertyName = JsonNameAttribute.GetJsonName(property);
                    if (String.IsNullOrEmpty(propertyName))
                    {
                        propertyName = NameResolver.CSharpToJson(property.Name);
//						propertyName = property.Name;
                    }

                    this.WriteObjectProperty(propertyName, propertyValue);
                }
#endif

                // serialize public fields
                IList <FieldInfo> fields = TypeCoercionUtility.GetAllFields(type);
//				FieldInfo[] fields = type.GetFields();
                foreach (FieldInfo field in fields)
                {
//					if (!field.IsPublic || field.IsStatic)
//					{
//						continue;
//					}

                    if (field.IsPrivate)
                    {
                        int breakhere = 1;
                        ++breakhere;
                    }

                    if (/*field.IsPrivate ||*/ field.IsStatic)
                    {
                        continue;
                    }

                    if (this.IsIgnored(type, field, value))
                    {
                        continue;
                    }

                    if (field.FieldType == typeof(Action))
                    {
                        continue;
                    }

                    object fieldValue = field.GetValue(value);
                    if (this.IsDefaultValue(field, fieldValue))
                    {
                        continue;
                    }

                    if (appendDelim)
                    {
                        this.WriteObjectPropertyDelim();
                        this.WriteLine();
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    // use Attributes here to control naming
                    string fieldName = JsonNameAttribute.GetJsonName(field);
                    if (String.IsNullOrEmpty(fieldName))
                    {
                        fieldName = NameResolver.CSharpToJson(field.Name);
//						fieldName = field.Name;
                    }

                    this.WriteObjectProperty(fieldName, fieldValue);
                }
            }
            finally
            {
                this.depth--;
            }

            if (appendDelim)
            {
                this.WriteLine();
            }
            this.Writer.Write(JsonReader.OperatorObjectEnd);
        }
Exemple #9
0
        private object ReadObject(Type objectType)
        {
            if (this.Source[this.index] != JsonReader.OperatorObjectStart)
            {
                throw new JsonDeserializationException(JsonReader.ErrorExpectedObject, this.index);
            }

            Type genericDictionaryType = null;
            Dictionary <string, MemberInfo> memberMap = null;
            Object result;

            if (objectType != null)
            {
                result = this.Settings.Coercion.InstantiateObject(objectType, out memberMap);

                if (memberMap == null)
                {
                    // this allows specific IDictionary<string, T> to deserialize T
                    Type genericDictionary = objectType.GetInterface(JsonReader.TypeGenericIDictionary);
                    if (genericDictionary != null)
                    {
                        Type[] genericArgs = genericDictionary.GetGenericArguments();
                        if (genericArgs.Length == 2)
                        {
                            if (genericArgs[0] != typeof(String))
                            {
                                throw new JsonDeserializationException(
                                          String.Format(JsonReader.ErrorGenericIDictionaryKeys, objectType),
                                          this.index);
                            }

                            if (genericArgs[1] != typeof(Object))
                            {
                                genericDictionaryType = genericArgs[1];
                            }
                        }
                    }
                }
            }
            else
            {
                result = new Dictionary <String, Object>();
            }

            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);
        }
Exemple #10
0
        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);
                }

                /*
                 * if (memberInfo == null && memberType == null)
                 *          {
                 *  Debug.LogErrorFormat("Can't find MemberInfo with Name - {0}, Type - {1}. You need to create it in object: {2}",
                 *                      memberName, value.GetType().Name, result.GetType().Name);
                 *          }
                 */
                // 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;
        }
        protected virtual object ReadObject(Type objectType)
        {
            if (this.Source[this.index] != '{')
            {
                throw new JsonDeserializationException("Expected JSON object.", this.index);
            }
            Type type = null;
            Dictionary <string, MemberInfo> dictionary = null;
            object obj;

            if (objectType != null)
            {
                obj = this.Settings.Coercion.InstantiateObject(objectType, out dictionary);
                if (dictionary == null)
                {
                    Type @interface = objectType.GetInterface("System.Collections.Generic.IDictionary`2");
                    if (@interface != null)
                    {
                        Type[] genericArguments = @interface.GetGenericArguments();
                        if (genericArguments.Length == 2)
                        {
                            if (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})", objectType), this.index);
                            }
                            if (genericArguments[1] != typeof(object))
                            {
                                type = genericArguments[1];
                            }
                        }
                    }
                }
            }
            else
            {
                obj = new Dictionary <string, object>();
            }
            JsonToken jsonToken;

            for (;;)
            {
                this.index++;
                if (this.index >= this.SourceLength)
                {
                    break;
                }
                jsonToken = this.Tokenize(this.Settings.AllowUnquotedObjectKeys);
                if (jsonToken == JsonToken.ObjectEnd)
                {
                    goto Block_9;
                }
                if (jsonToken != JsonToken.String && jsonToken != JsonToken.UnquotedName)
                {
                    goto Block_11;
                }
                string     text = (jsonToken != JsonToken.String) ? this.ReadUnquotedKey() : ((string)this.ReadString(null));
                MemberInfo memberInfo;
                Type       type2;
                if (type == null && dictionary != null)
                {
                    type2 = TypeCoercionUtility.GetMemberInfo(dictionary, text, out memberInfo);
                }
                else
                {
                    type2      = type;
                    memberInfo = null;
                }
                jsonToken = this.Tokenize();
                if (jsonToken != JsonToken.NameDelim)
                {
                    goto Block_15;
                }
                this.index++;
                if (this.index >= this.SourceLength)
                {
                    goto Block_16;
                }
                object obj2 = this.Read(type2, false);
                if (obj is IDictionary)
                {
                    if (objectType == null && this.Settings.IsTypeHintName(text))
                    {
                        obj = this.Settings.Coercion.ProcessTypeHint((IDictionary)obj, obj2 as string, out objectType, out dictionary);
                    }
                    else
                    {
                        ((IDictionary)obj)[text] = obj2;
                    }
                }
                else
                {
                    if (objectType.GetInterface("System.Collections.Generic.IDictionary`2") != null)
                    {
                        goto Block_20;
                    }
                    this.Settings.Coercion.SetMemberValue(obj, type2, memberInfo, obj2);
                }
                jsonToken = this.Tokenize();
                if (jsonToken != JsonToken.ValueDelim)
                {
                    goto IL_281;
                }
            }
            throw new JsonDeserializationException("Unterminated JSON object.", this.index);
Block_9:
            goto IL_281;
Block_11:
            throw new JsonDeserializationException("Expected JSON object property name.", this.index);
Block_15:
            throw new JsonDeserializationException("Expected JSON object property name delimiter.", this.index);
Block_16:
            throw new JsonDeserializationException("Unterminated JSON object.", this.index);
Block_20:
            throw new JsonDeserializationException(string.Format("Types which implement Generic IDictionary<TKey, TValue> also need to implement IDictionary to be deserialized. ({0})", objectType), this.index);
IL_281:
            if (jsonToken != JsonToken.ObjectEnd)
            {
                throw new JsonDeserializationException("Unterminated JSON object.", this.index);
            }
            this.index++;
            return(obj);
        }
Exemple #12
0
        private object ReadObject(Type objectType)
        {
            object    obj2;
            JsonToken token;

            if (this.Source[this.index] != '{')
            {
                throw new JsonDeserializationException("Expected JSON object.", this.index);
            }
            Type type = null;
            Dictionary <string, MemberInfo> memberMap = null;

            if (objectType != null)
            {
                #region 这里是映射JsonWriter(619行)所设定的特殊类型
                if (objectType == typeof(Vector2))
                {
                    obj2      = new Vector2();
                    memberMap = this.Settings.Coercion.CreateFieldMemberMap(objectType);
                }
                else if (objectType == typeof(Vector3))
                {
                    obj2      = new Vector3();
                    memberMap = this.Settings.Coercion.CreateFieldMemberMap(objectType);
                }
                else if (objectType == typeof(Vector4))
                {
                    obj2      = new Vector4();
                    memberMap = this.Settings.Coercion.CreateFieldMemberMap(objectType);
                }
                #endregion
                else
                {
                    obj2 = this.Settings.Coercion.InstantiateObject(objectType, out memberMap);
                }

                if (memberMap == null)
                {
                    Type type2 = objectType.GetInterface("System.Collections.Generic.IDictionary`2");
                    if (type2 != null)
                    {
                        Type[] genericArguments = type2.GetGenericArguments();
                        if (genericArguments.Length == 2)
                        {
                            if (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})", objectType), this.index);
                            }
                            if (genericArguments[1] != typeof(object))
                            {
                                type = genericArguments[1];
                            }
                        }
                    }
                }
            }
            else
            {
                obj2 = new Dictionary <string, object>();
            }
            do
            {
                Type       type3;
                MemberInfo info;
                this.index++;
                if (this.index >= this.SourceLength)
                {
                    throw new JsonDeserializationException("Unterminated JSON object.", this.index);
                }
                token = this.Tokenize(this.Settings.AllowUnquotedObjectKeys);
                if (token == JsonToken.ObjectEnd)
                {
                    break;
                }
                if ((token != JsonToken.String) && (token != JsonToken.UnquotedName))
                {
                    throw new JsonDeserializationException("Expected JSON object property name.", this.index);
                }
                string memberName = (token != JsonToken.String) ? this.ReadUnquotedKey() : ((string)this.ReadString(null));
                if ((type == null) && (memberMap != null))
                {
                    type3 = TypeCoercionUtility.GetMemberInfo(memberMap, memberName, out info);
                }
                else
                {
                    type3 = type;
                    info  = null;
                }
                if (this.Tokenize() != JsonToken.NameDelim)
                {
                    throw new JsonDeserializationException("Expected JSON object property name delimiter.", this.index);
                }
                this.index++;
                if (this.index >= this.SourceLength)
                {
                    throw new JsonDeserializationException("Unterminated JSON object.", this.index);
                }
                object obj3 = this.Read(type3, false);
                if (obj2 is IDictionary)
                {
                    if ((objectType == null) && this.Settings.IsTypeHintName(memberName))
                    {
                        obj2 = this.Settings.Coercion.ProcessTypeHint((IDictionary)obj2, obj3 as string, out objectType, out memberMap);
                    }
                    else
                    {
                        ((IDictionary)obj2)[memberName] = obj3;
                    }
                }
                else
                {
                    if (objectType.GetInterface("System.Collections.Generic.IDictionary`2") != 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);
                    }
                    this.Settings.Coercion.SetMemberValue(obj2, type3, info, obj3);
                }
                token = this.Tokenize();
            }while (token == JsonToken.ValueDelim);
            if (token != JsonToken.ObjectEnd)
            {
                throw new JsonDeserializationException("Unterminated JSON object.", this.index);
            }
            this.index++;
            return(obj2);
        }
Exemple #13
0
        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));
                }
            }

            if (value is IDictionary)
            {
                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);
            }
        }
Exemple #14
0
        private object ReadObject(Type objectType)
        {
            if (this.Source[this.index] != JsonReader.OperatorObjectStart)
            {
                throw new JsonDeserializationException(JsonReader.ErrorExpectedObject, this.index);
            }

            // If this is a Date, then we should be reading an EJSON Date
            if (objectType != null &&
                objectType == typeof(DateTime))
            {
                // Read an EJSON result instead
                var ejsonDateResult = this.ReadObject(typeof(Meteor.EJSON.EJSONDate)) as Meteor.EJSON.EJSONDate;
                var returnDate      = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddTicks(ejsonDateResult.date * 10000L);
                return(returnDate);
            }

            // If this is a byte[] destination and we're reading an object, we're handling an EJSON UInt8 array
            if (objectType != null &&
                objectType == typeof(byte[]))
            {
                var ejsonBinaryResult = this.ReadObject(typeof(Meteor.EJSON.EJSONUInt8Array)) as Meteor.EJSON.EJSONUInt8Array;
                var returnBytes       = System.Convert.FromBase64String(ejsonBinaryResult.binary);
                return(returnBytes);
            }

            Type genericDictionaryType = null;
            Dictionary <string, MemberInfo> memberMap = null;
            Object result;

            if (objectType != null)
            {
                result = this.Settings.Coercion.InstantiateObject(objectType, out memberMap);

                if (memberMap == null)
                {
                    // this allows specific IDictionary<string, T> to deserialize T
                    Type genericDictionary = objectType.GetInterface(JsonReader.TypeGenericIDictionary);
                    if (genericDictionary != null)
                    {
                        Type[] genericArgs = genericDictionary.GetGenericArguments();
                        if (genericArgs.Length == 2)
                        {
                            if (genericArgs[0] != typeof(String))
                            {
                                throw new JsonDeserializationException(
                                          String.Format(JsonReader.ErrorGenericIDictionaryKeys, objectType),
                                          this.index);
                            }

                            if (genericArgs[1] != typeof(Object))
                            {
                                genericDictionaryType = genericArgs[1];
                            }
                        }
                    }
                }
            }
            else
            {
                result = new Dictionary <String, Object>();
            }

            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 = 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);
        }
Exemple #15
0
        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 WINPHONE_8
            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;
        }
        public virtual object CoerceType(Type targetType, object value)
        {
            bool flag = TypeCoercionUtility.IsNullable(targetType);

            if (value == null)
            {
                if (!this.allowNullValueTypes && targetType.IsValueType && !flag)
                {
                    throw new JsonTypeCoercionException(string.Format("{0} does not accept null as a value", targetType.FullName));
                }
                return(value);
            }
            else
            {
                if (flag)
                {
                    Type[] genericArguments = targetType.GetGenericArguments();
                    if (genericArguments.Length == 1)
                    {
                        targetType = genericArguments[0];
                    }
                }
                Type type = value.GetType();
                if (targetType.IsAssignableFrom(type))
                {
                    return(value);
                }
                if (targetType.IsEnum)
                {
                    if (value is string)
                    {
                        if (!Enum.IsDefined(targetType, value))
                        {
                            foreach (FieldInfo fieldInfo in 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 (typeof(IEnumerable).IsAssignableFrom(targetType) && typeof(IEnumerable).IsAssignableFrom(type))
                    {
                        return(this.CoerceList(targetType, type, (IEnumerable)value));
                    }
                    if (value is string)
                    {
                        if (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 (targetType == typeof(Guid))
                            {
                                return(new Guid((string)value));
                            }
                            if (targetType == typeof(char))
                            {
                                if (((string)value).Length == 1)
                                {
                                    return(((string)value)[0]);
                                }
                            }
                            else if (targetType == typeof(Uri))
                            {
                                Uri result;
                                if (Uri.TryCreate((string)value, UriKind.RelativeOrAbsolute, out result))
                                {
                                    return(result);
                                }
                            }
                            else if (targetType == typeof(Version))
                            {
                                return(new Version((string)value));
                            }
                        }
                    }
                    else if (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}", value.GetType().FullName, targetType.FullName), innerException);
                    }
                    return(result2);
                }
            }
        }