Exemplo n.º 1
0
        public void GetMemberWritingMap(Type objectType, JsonWriterSettings settings, out Member[] outMembers)
        {
            if (writingMaps == null)
            {
                writingMaps = new Dictionary <Type, Member[]> ();
            }

            if (writingMaps.TryGetValue(objectType, out outMembers))
            {
                return;
            }

            bool anonymousType = objectType.IsGenericType && objectType.Name.StartsWith(JsonWriter.AnonymousTypePrefix);

            Type tp = objectType;

            if (memberList == null)
            {
                memberList = new List <Member> ();
            }

            memberList.Clear();

            while (tp != null)
            {
                FieldInfo[] fields = tp.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                for (int j = 0; j < fields.Length; j++)
                {
                    FieldInfo field = fields[j];

                    if (field.IsStatic || (!field.IsPublic && field.GetCustomAttributes(typeof(JsonMemberAttribute), true).Length == 0))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize " + field.Name + " : not public or is static (and does not have a JsonMember attribute)");
                        continue;
                    }

                    if (settings.IsIgnored(objectType, field, null))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize " + field.Name + " : ignored by settings");
                        continue;
                    }

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

                    memberList.Add(new Member(fieldName, field));
                }

                PropertyInfo[] properties = tp.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                for (int j = 0; j < properties.Length; j++)
                {
                    PropertyInfo property = properties[j];

                    //Console.WriteLine (property.Name);
                    if (!property.CanRead)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : cannot read");
                        continue;
                    }

                    if (!property.CanWrite && !anonymousType)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : cannot write");
                        continue;
                    }

                    if (settings.IsIgnored(objectType, property, null))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : is ignored by settings");
                        continue;
                    }

                    if (property.GetIndexParameters().Length != 0)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : is indexed");
                        continue;
                    }


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

                    memberList.Add(new Member(propertyName, property));
                }

                tp = tp.BaseType;
            }

            for (int i = 0; i < memberList.Count; i++)
            {
                memberList [i].index = i;
            }

            memberList.Sort((a, b) => {
                var attrA  = Attribute.GetCustomAttribute(a.member, typeof(JsonOrderAttribute), true) as JsonOrderAttribute;
                var attrB  = Attribute.GetCustomAttribute(b.member, typeof(JsonOrderAttribute), true) as JsonOrderAttribute;
                var orderA = attrA != null ? attrA.order : 0;
                var orderB = attrB != null ? attrB.order : 0;
                var c      = orderA.CompareTo(orderB);
                if (c != 0)
                {
                    return(c);
                }

                // Ensure stable sort
                return(a.index.CompareTo(b.index));
            });

            outMembers = memberList.ToArray();
            writingMaps[objectType] = outMembers;
        }
        public void GetMemberWritingMap(Type objectType, JsonWriterSettings settings, out KeyValuePair <string, FieldInfo>[] outFields, out KeyValuePair <string, PropertyInfo>[] outProps)
        {
            if (writingMaps == null)
            {
                writingMaps = new Dictionary <Type, KeyValuePair <KeyValuePair <string, FieldInfo>[], KeyValuePair <string, PropertyInfo>[]> > ();
            }

            KeyValuePair <KeyValuePair <string, FieldInfo>[], KeyValuePair <string, PropertyInfo>[]> pair;

            if (writingMaps.TryGetValue(objectType, out pair))
            {
                outFields = pair.Key;
                outProps  = pair.Value;
                return;
            }

            bool anonymousType = objectType.IsGenericType && objectType.Name.StartsWith(JsonWriter.AnonymousTypePrefix);

            Type tp = objectType;

            if (fieldList == null)
            {
                fieldList = new List <KeyValuePair <string, FieldInfo> > ();
            }

            if (propList == null)
            {
                propList = new List <KeyValuePair <string, PropertyInfo> > ();
            }

            fieldList.Clear();
            propList.Clear();

            while (tp != null)
            {
                FieldInfo[] fields = tp.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                for (int j = 0; j < fields.Length; j++)
                {
                    FieldInfo field = fields[j];

                    if (field.IsStatic || (!field.IsPublic && field.GetCustomAttributes(typeof(JsonMemberAttribute), true).Length == 0))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize " + field.Name + " : not public or is static (and does not have a JsonMember attribute)");
                        continue;
                    }

                    if (settings.IsIgnored(objectType, field, null))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize " + field.Name + " : ignored by settings");
                        continue;
                    }

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

                    fieldList.Add(new KeyValuePair <string, FieldInfo> (fieldName, field));
                }

                PropertyInfo[] properties = tp.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly);
                for (int j = 0; j < properties.Length; j++)
                {
                    PropertyInfo property = properties[j];

                    //Console.WriteLine (property.Name);
                    if (!property.CanRead)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : cannot read");
                        continue;
                    }

                    if (!property.CanWrite && !anonymousType)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : cannot write");
                        continue;
                    }

                    if (settings.IsIgnored(objectType, property, null))
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : is ignored by settings");
                        continue;
                    }

                    if (property.GetIndexParameters().Length != 0)
                    {
                        //if (Settings.DebugMode)
                        //	Console.WriteLine ("Cannot serialize "+property.Name+" : is indexed");
                        continue;
                    }


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

                    propList.Add(new KeyValuePair <string, PropertyInfo>(propertyName, property));
                }

                tp = tp.BaseType;
            }

            outFields = fieldList.ToArray();
            outProps  = propList.ToArray();

            pair = new KeyValuePair <KeyValuePair <string, FieldInfo>[], KeyValuePair <string, PropertyInfo>[]> (outFields, outProps);

            writingMaps[objectType] = pair;
        }