Пример #1
0
        /// <summary>
        /// Writes the specified value.
        /// </summary>
        /// <param name="value">The value.</param>
        public virtual void Write(Enum value)
        {
            string enumName = null;

            Type type = value.GetType();

            if (type.IsDefined(typeof(FlagsAttribute), true) && !Enum.IsDefined(type, value))
            {
                Enum[]   flags     = JsonWriter.GetFlagList(type, value);
                string[] flagNames = new string[flags.Length];
                for (int i = 0; i < flags.Length; i++)
                {
                    flagNames[i] = JsonNameAttribute.GetJsonName(flags[i]);
                    if (string.IsNullOrEmpty(flagNames[i]))
                    {
                        flagNames[i] = flags[i].ToString("f");
                    }
                }
                enumName = String.Join(", ", flagNames);
            }
            else
            {
                enumName = JsonNameAttribute.GetJsonName(value);
                if (string.IsNullOrEmpty(enumName))
                {
                    enumName = value.ToString("f");
                }
            }

            this.Write(enumName);
        }
Пример #2
0
        /// <summary>
        /// Gets the name specified for use in Json serialization.
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string GetJsonName(object value)
        {
            if (value == null)
            {
                return(null);
            }

            Type       type       = value.GetType();
            MemberInfo memberInfo = null;

            if (type.IsEnum)
            {
                string name = Enum.GetName(type, value);
                if (string.IsNullOrEmpty(name))
                {
                    return(null);
                }
                memberInfo = type.GetField(name);
            }
            else
            {
                memberInfo = value as MemberInfo;
            }

            if (memberInfo == null)
            {
                throw new ArgumentException();
            }

            if (!Attribute.IsDefined(memberInfo, typeof(JsonNameAttribute)))
            {
                return(null);
            }
            JsonNameAttribute attribute = (JsonNameAttribute)Attribute.GetCustomAttribute(memberInfo, typeof(JsonNameAttribute));

            return(attribute.Name);
        }
Пример #3
0
        private static object CoerceType(Type targetType, object value, int index, bool allowNullValueTypes)
        {
            bool isNullable = JsonReader.IsNullable(targetType);

            if (value == null)
            {
                if (allowNullValueTypes &&
                    targetType.IsValueType &&
                    !isNullable)
                {
                    throw new JsonDeserializationException(String.Format(JsonReader.ErrorNullValueType, targetType.FullName), index);
                }
                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 (!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;
                        }
                    }
                }

                if (value is String)
                {
                    return(Enum.Parse(targetType, (string)value));
                }
                else
                {
                    return(Convert.ChangeType(value, targetType));
                }
            }

            if (actualType.IsArray && !targetType.IsArray)
            {
                return(JsonReader.CoerceArray(targetType, actualType, value, index, allowNullValueTypes));
            }

            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(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)JsonReader.CoerceType(typeof(Int64), value, index, allowNullValueTypes)));
            }

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

            return(Convert.ChangeType(value, targetType));
        }
Пример #4
0
        private Dictionary <string, MemberInfo> CreateMemberMap(Type objectType)
        {
            if (this.MemberMapCache == null)
            {
                // instantiate space for cache
                this.MemberMapCache = new Dictionary <Type, Dictionary <string, MemberInfo> >();
            }
            else if (this.MemberMapCache.ContainsKey(objectType))
            {
                // map was stored in cache
                return(this.MemberMapCache[objectType]);
            }

            // create a new map
            Dictionary <string, MemberInfo> memberMap = new Dictionary <string, MemberInfo>();

            // load properties into property map
            PropertyInfo[] properties = objectType.GetProperties();
            foreach (PropertyInfo info in properties)
            {
                if (!info.CanRead || !info.CanWrite)
                {
                    continue;
                }

                if (JsonIgnoreAttribute.IsJsonIgnore(info))
                {
                    continue;
                }

                string jsonName = JsonNameAttribute.GetJsonName(info);
                if (string.IsNullOrEmpty(jsonName))
                {
                    memberMap[info.Name] = info;
                }
                else
                {
                    memberMap[jsonName] = info;
                }
            }

            // load public fields into property map
            FieldInfo[] fields = objectType.GetFields();
            foreach (FieldInfo info in fields)
            {
                if (!info.IsPublic)
                {
                    continue;
                }

                if (JsonIgnoreAttribute.IsJsonIgnore(info))
                {
                    continue;
                }

                string jsonName = JsonNameAttribute.GetJsonName(info);
                if (string.IsNullOrEmpty(jsonName))
                {
                    memberMap[info.Name] = info;
                }
                else
                {
                    memberMap[jsonName] = info;
                }
            }

            // store in cache for repeated usage
            this.MemberMapCache[objectType] = memberMap;

            return(memberMap);
        }
Пример #5
0
        /// <summary>
        /// Writes the object.
        /// </summary>
        /// <param name="value">The value.</param>
        protected virtual void WriteObject(object value)
        {
            bool appendDelim = false;

            this.writer.Write(JsonReader.OperatorObjectStart);

            this.depth++;
            try
            {
                Type objType = value.GetType();

                if (!string.IsNullOrEmpty(this.TypeHintName))
                {
                    if (appendDelim)
                    {
                        this.writer.Write(JsonReader.OperatorValueDelim);
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    this.WriteLine();
                    this.Write(this.TypeHintName);
                    this.writer.Write(JsonReader.OperatorNameDelim);
                    this.Write(objType.FullName, true);
                }

                // serialize public properties
                PropertyInfo[] properties = objType.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    if (!property.CanWrite || !property.CanRead)
                    {
                        continue;
                    }

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

                    object propertyValue = property.GetValue(value, null);

                    if ((propertyValue == null) && SkipNullValue)
                    {
                        continue;
                    }

                    if (this.IsDefaultValue(property, propertyValue))
                    {
                        continue;
                    }

                    if (appendDelim)
                    {
                        this.writer.Write(JsonReader.OperatorValueDelim);
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    string propertyName = JsonNameAttribute.GetJsonName(property);
                    if (string.IsNullOrEmpty(propertyName))
                    {
                        propertyName = property.Name;
                    }

                    this.WriteLine();
                    this.Write(propertyName);
                    this.writer.Write(JsonReader.OperatorNameDelim);
                    this.Write(propertyValue, true);
                }

                // serialize public fields
                FieldInfo[] fields = objType.GetFields();
                foreach (FieldInfo field in fields)
                {
                    if (!field.IsPublic || field.IsStatic)
                    {
                        continue;
                    }

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

                    object fieldValue = field.GetValue(value);

                    if (this.IsDefaultValue(field, fieldValue))
                    {
                        continue;
                    }

                    if (appendDelim)
                    {
                        this.writer.Write(JsonReader.OperatorValueDelim);
                        this.WriteLine();
                    }
                    else
                    {
                        appendDelim = true;
                    }

                    string fieldName = JsonNameAttribute.GetJsonName(field);
                    if (string.IsNullOrEmpty(fieldName))
                    {
                        fieldName = field.Name;
                    }

                    // use Attributes here to control naming
                    this.Write(fieldName);
                    this.writer.Write(JsonReader.OperatorNameDelim);
                    this.Write(fieldValue, true);
                }
            }
            finally
            {
                this.depth--;
            }

            if (appendDelim)
            {
                this.WriteLine();
            }
            this.writer.Write(JsonReader.OperatorObjectEnd);
        }