예제 #1
0
        private static void AddTypeProperties(Type type)
        {
            if (type_properties.ContainsKey(type))
            {
                return;
            }

            xuexueJsonClass xxjc = type.GetCustomAttribute <xuexueJsonClass>();

            if (xxjc == null)
            {
                //尝试查找用户的定义
                if (JsonTypeRegister.dictTypeXXJC.ContainsKey(type))
                {
                    xxjc = JsonTypeRegister.dictTypeXXJC[type];
                }
            }
            if (xxjc == null)
            {
                xxjc = JsonTypeRegister.defaultClassAttribute;//使用一个当前的默认设置
            }

            List <PropertyMetadata> props = new List <PropertyMetadata>();


            foreach (PropertyInfo p_info in type.GetProperties(xxjc.propertyflags))
            {
                if (p_info.Name == "Item")
                {
                    continue;
                }

                //如果直接在忽略类型列表里了就直接忽略
                if (JsonTypeRegister.listIgnoreClass.Contains(p_info.PropertyType) ||
                    JsonTypeRegister.listIgnoreClass.Contains(p_info.PropertyType.GetElementType()))
                {
                    continue;
                }

                //对System.Collections.Generic中的数据结构进行忽略判断
                if (p_info.PropertyType.IsGenericType)
                {
                    bool   isIgnore = false;
                    Type[] gat      = p_info.PropertyType.GetGenericArguments();
                    for (int i = 0; i < gat.Length; i++)
                    {
                        if (JsonTypeRegister.listIgnoreClass.Contains(gat[i]))
                        {
                            isIgnore = true;
                            break;
                        }
                    }
                    if (isIgnore)
                    {
                        continue;
                    }
                }

                //如果存在特别要使能的成员名List
                if (xxjc.enableMembers != null && xxjc.enableMembers.Contains(p_info.Name))
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = p_info;
                    p_data.IsField  = false;
                    p_data.Priority = 0;
                    props.Add(p_data);

                    continue;
                }

                if (xxjc.ignoreMembers != null && xxjc.ignoreMembers.Contains(p_info.Name))
                {
                    continue; //应该被忽略
                }

                if (p_info.IsDefined(typeof(xuexueJson), false))
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = p_info;
                    p_data.IsField  = false;
                    p_data.Priority = p_info.GetCustomAttribute <xuexueJson>().priority;
                    props.Add(p_data);
                    continue;
                }
                if (p_info.IsDefined(typeof(xuexueJsonIgnore), false))
                {
                    continue;
                }
                if (xxjc.defaultPropertyConstraint == true)//如果默认设置是开启
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = p_info;
                    p_data.IsField  = false;
                    p_data.Priority = 0;
                    props.Add(p_data);
                }
            }

            foreach (FieldInfo f_info in type.GetFields(xxjc.fieldflags))
            {
                //如果直接在忽略类型列表里了就直接忽略
                if (JsonTypeRegister.listIgnoreClass.Contains(f_info.FieldType) ||
                    JsonTypeRegister.listIgnoreClass.Contains(f_info.FieldType.GetElementType()))
                {
                    continue;
                }

                //对System.Collections.Generic中的数据结构进行忽略判断
                if (f_info.FieldType.IsGenericType)
                {
                    bool   isIgnore = false;
                    Type[] gat      = f_info.FieldType.GetGenericArguments();
                    for (int i = 0; i < gat.Length; i++)
                    {
                        if (JsonTypeRegister.listIgnoreClass.Contains(gat[i]))
                        {
                            isIgnore = true;
                            break;
                        }
                    }
                    if (isIgnore)
                    {
                        continue;
                    }
                }

                if (xxjc.enableMembers != null && xxjc.enableMembers.Contains(f_info.Name))
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = f_info;
                    p_data.IsField  = true;
                    p_data.Priority = 0;
                    props.Add(p_data);

                    continue;
                }
                if (xxjc.ignoreMembers != null && xxjc.ignoreMembers.Contains(f_info.Name))
                {
                    continue; //应该被忽略
                }

                if (f_info.IsDefined(typeof(xuexueJson), false))
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = f_info;
                    p_data.IsField  = true;
                    p_data.Priority = f_info.GetCustomAttribute <xuexueJson>().priority;
                    props.Add(p_data);
                    continue; //应该被忽略
                }
                if (f_info.IsDefined(typeof(xuexueJsonIgnore), false))
                {
                    continue;
                }
                if (xxjc.defaultFieldConstraint == true)//如果默认设置是开启
                {
                    PropertyMetadata p_data = new PropertyMetadata();
                    p_data.Info     = f_info;
                    p_data.IsField  = true;
                    p_data.Priority = 0;
                    props.Add(p_data);
                }
            }

            props.Sort((p1, p2) => { return(p1.Priority - p2.Priority); });

            lock (type_properties_lock) {
                try {
                    type_properties.Add(type, props);
                } catch (ArgumentException) {
                    return;
                }
            }
        }
예제 #2
0
        private static object ReadValue(Type inst_type, JsonReader reader, object instance = null)
        {
            reader.Read();

            if (reader.Token == JsonToken.ArrayEnd)
            {
                return(null);
            }

            Type underlying_type = Nullable.GetUnderlyingType(inst_type);
            Type value_type      = underlying_type ?? inst_type;

            if (reader.Token == JsonToken.Null)
            {
                #if NETSTANDARD1_5
                if (inst_type.IsClass() || underlying_type != null)
                {
                    return(null);
                }
                #else
                if (inst_type.IsClass || underlying_type != null)
                {
                    return(null);
                }
                #endif

                throw new JsonException(String.Format(
                                            "Can't assign null to an instance of type {0}",
                                            inst_type));
            }

            if (reader.Token == JsonToken.Double ||
                reader.Token == JsonToken.Int ||
                reader.Token == JsonToken.Long ||
                reader.Token == JsonToken.String ||
                reader.Token == JsonToken.Boolean)
            {
                Type json_type = reader.Value.GetType();

                if (value_type.IsAssignableFrom(json_type))
                {
                    return(reader.Value);
                }

                // If there's a custom importer that fits, use it
                if (custom_importers_table.ContainsKey(json_type) &&
                    custom_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        custom_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe there's a base importer that works
                if (base_importers_table.ContainsKey(json_type) &&
                    base_importers_table[json_type].ContainsKey(
                        value_type))
                {
                    ImporterFunc importer =
                        base_importers_table[json_type][value_type];

                    return(importer(reader.Value));
                }

                // Maybe it's an enum
                #if NETSTANDARD1_5
                if (value_type.IsEnum())
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }
                #else
                if (value_type.IsEnum)
                {
                    return(Enum.ToObject(value_type, reader.Value));
                }
                #endif
                // Try using an implicit conversion operator
                MethodInfo conv_op = GetConvOp(value_type, json_type);

                if (conv_op != null)
                {
                    return(conv_op.Invoke(null,
                                          new object[] { reader.Value }));
                }

                // No luck
                throw new JsonException(String.Format(
                                            "Can't assign value '{0}' (type {1}) to type {2}",
                                            reader.Value, json_type, inst_type));
            }

            //object instance = null; //将instance作为参数传进来

            if (reader.Token == JsonToken.ArrayStart)
            {
                AddArrayMetadata(inst_type);
                ArrayMetadata t_data = array_metadata[inst_type];

                if (!t_data.IsArray && !t_data.IsList)
                {
                    throw new JsonException(String.Format(
                                                "Type {0} can't act as an array",
                                                inst_type));
                }

                IList list;
                Type  elem_type;

                if (!t_data.IsArray)
                {
                    list      = (IList)Activator.CreateInstance(inst_type);
                    elem_type = t_data.ElementType;
                }
                else
                {
                    list      = new ArrayList();
                    elem_type = inst_type.GetElementType();
                }

                while (true)
                {
                    object item = ReadValue(elem_type, reader);
                    if (item == null && reader.Token == JsonToken.ArrayEnd)
                    {
                        break;
                    }

                    list.Add(item);
                }

                if (t_data.IsArray)
                {
                    int n = list.Count;
                    instance = Array.CreateInstance(elem_type, n);

                    for (int i = 0; i < n; i++)
                    {
                        ((Array)instance).SetValue(list[i], i);
                    }
                }
                else
                {
                    instance = list;
                }
            }
            else if (reader.Token == JsonToken.ObjectStart)
            {
                AddObjectMetadata(value_type);
                ObjectMetadata t_data = object_metadata[value_type];

                //这里是创建这个对象本身
                if (instance == null)
                {
                    instance = Activator.CreateInstance(value_type);
                }

                while (true)
                {
                    reader.Read();

                    if (reader.Token == JsonToken.ObjectEnd)
                    {
                        break;
                    }

                    string property = (string)reader.Value;

                    if (t_data.Properties.ContainsKey(property))
                    {
                        PropertyMetadata prop_data =
                            t_data.Properties[property];

                        if (prop_data.IsField)
                        {
                            ((FieldInfo)prop_data.Info).SetValue(
                                instance, ReadValue(prop_data.Type, reader));
                        }
                        else
                        {
                            PropertyInfo p_info =
                                (PropertyInfo)prop_data.Info;

                            if (p_info.CanWrite)
                            {
                                p_info.SetValue(
                                    instance,
                                    ReadValue(prop_data.Type, reader),
                                    null);
                            }
                            else
                            {
                                ReadValue(prop_data.Type, reader);
                            }
                        }
                    }
                    else
                    {
                        if (!t_data.IsDictionary)
                        {
                            if (!reader.SkipNonMembers)
                            {
                                throw new JsonException(String.Format(
                                                            "The type {0} doesn't have the " +
                                                            "property '{1}'",
                                                            inst_type, property));
                            }
                            else
                            {
                                ReadSkip(reader);
                                continue;
                            }
                        }

                        ((IDictionary)instance).Add(
                            property, ReadValue(
                                t_data.ElementType, reader));
                    }
                }
            }

            return(instance);
        }
예제 #3
0
        private static void AddObjectMetadata(Type type)
        {
            if (object_metadata.ContainsKey(type))
            {
                return;
            }

            xuexueJsonClass xxjc = type.GetCustomAttribute <xuexueJsonClass>();

            if (xxjc == null)
            {
                //尝试查找用户的定义
                if (JsonTypeRegister.dictTypeXXJC.ContainsKey(type))
                {
                    xxjc = JsonTypeRegister.dictTypeXXJC[type];
                }
            }
            if (xxjc == null)
            {
                xxjc = JsonTypeRegister.defaultClassAttribute;//使用一个当前的默认设置
            }

            IList <PropertyMetadata> props = new List <PropertyMetadata>();

            ObjectMetadata data = new ObjectMetadata();

            if (type.GetInterface("System.Collections.IDictionary") != null)
            {
                data.IsDictionary = true;
            }

            data.Properties = new Dictionary <string, PropertyMetadata> ();

            foreach (PropertyInfo p_info in type.GetProperties(xxjc.propertyflags))
            {
                if (p_info.Name == "Item")
                {
                    ParameterInfo[] parameters = p_info.GetIndexParameters();

                    if (parameters.Length != 1)
                    {
                        continue;
                    }

                    if (parameters[0].ParameterType == typeof(string))
                    {
                        data.ElementType = p_info.PropertyType;
                    }

                    continue;
                }

                PropertyMetadata p_data = new PropertyMetadata();
                p_data.Info = p_info;
                p_data.Type = p_info.PropertyType;

                data.Properties.Add(p_info.Name, p_data);
            }

            foreach (FieldInfo f_info in type.GetFields(xxjc.fieldflags))
            {
                PropertyMetadata p_data = new PropertyMetadata();
                p_data.Info    = f_info;
                p_data.IsField = true;
                p_data.Type    = f_info.FieldType;

                data.Properties.Add(f_info.Name, p_data);
            }

            lock (object_metadata_lock) {
                try {
                    object_metadata.Add(type, data);
                } catch (ArgumentException) {
                    return;
                }
            }
        }