예제 #1
0
        private static JsonSerializerOptions CreateJsonSerializerOptions()
        {
            var options = new JsonSerializerOptions
            {
                MaxDepth         = int.MaxValue,
                Converters       = { new JsonStringEnumConverter() },
                IgnoreNullValues = true
            };

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new TonClientDiscriminatorConvention(options));
            registry.DiscriminatorPolicy = DiscriminatorPolicy.Always;

            var nestedTypes = typeof(Abi.Contract).Assembly.GetTypes().Where(t => t.IsNestedPublic);

            // register all nested types from models
            foreach (Type type in nestedTypes)
            {
                registry.RegisterType(type);
            }

            return(options);
        }
예제 #2
0
        static TelescopeConverter()
        {
            options = new JsonSerializerOptions()
            {
                WriteIndented = true,
            };
            options.SetupExtensions();

            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.DiscriminatorPolicy = DiscriminatorPolicy.Always;

            // Cell types
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "cell_type"));
            registry.RegisterType <CodeCell>();
            registry.RegisterType <MarkdownCell>();
            registry.RegisterType <RawCell>();

            // Cell output types
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "output_type"));
            registry.RegisterType <DataOutput>();
            registry.RegisterType <ErrorOutput>();
            registry.RegisterType <ExecuteResultOutput>();
            registry.RegisterType <StreamOutput>();
        }
예제 #3
0
        public void WritePolymorphicObject(DiscriminatorPolicy discriminatorPolicy, string expected)
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <int>(options));
            registry.RegisterType <NameObject>();
            registry.DiscriminatorPolicy = discriminatorPolicy;

            BaseObjectHolder obj = new BaseObjectHolder
            {
                BaseObject = new NameObject
                {
                    Id   = 1,
                    Name = "foo"
                },
                NameObject = new NameObject
                {
                    Id   = 2,
                    Name = "bar"
                }
            };

            string actual = JsonSerializer.Serialize(obj, options);

            Assert.Equal(expected, actual);
        }
예제 #4
0
        public ObjectConverter(JsonSerializerOptions options)
        {
            _objectMapping    = options.GetObjectMappingRegistry().Lookup <T>();
            _memberConverters = new Lazy <MemberConverters>(() => MemberConverters.Create(options, _objectMapping));

            _isInterfaceOrAbstract = typeof(T).IsInterface || typeof(T).IsAbstract;
            _isStruct = typeof(T).IsStruct();

            if (!_isInterfaceOrAbstract && _objectMapping.CreatorMapping == null && !_isStruct)
            {
                ConstructorInfo defaultConstructorInfo = typeof(T).GetConstructor(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                    null,
                    Type.EmptyTypes,
                    null);

                if (defaultConstructorInfo == null)
                {
                    throw new JsonException($"Cannot find a default constructor on type {typeof(T)}");
                }

                _constructor = defaultConstructorInfo.CreateDelegate <T>();
            }

            _discriminatorConvention = options.GetDiscriminatorConventionRegistry().GetConvention(typeof(T));
            _referenceHandling       = _isStruct ? ReferenceHandling.Default : options.GetReferenceHandling();
        }
예제 #5
0
        public JsonSerializerOptions SetupJsonSerializerOptions(JsonSerializerOptions opt)
        {
            opt.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
            opt.Converters.Add(new FlowSnakeJsonConverter());
            opt.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());
            opt.Converters.Add(new TestCaseDefinitionConverter());
            opt.SetupExtensions();
            opt.IgnoreNullValues = true;

            var dis = opt.GetDiscriminatorConventionRegistry();

            dis.ClearConventions();
            dis.RegisterConvention(new DefaultDiscriminatorConvention <string>(opt, "_t"));
            dis.RegisterType <Models.Judger.ClientStatusMsg>();
            dis.RegisterType <Models.Judger.JobProgressMsg>();
            dis.RegisterType <Models.Judger.JobResultMsg>();
            dis.RegisterType <Models.Judger.PartialResultMsg>();
            dis.RegisterType <Models.Judger.AbortJobServerMsg>();
            dis.RegisterType <Models.Judger.NewJobServerMsg>();
            dis.RegisterType <Models.Judger.JobOutputMsg>();
            dis.RegisterType <Models.WebsocketApi.JobStatusUpdateMsg>();
            dis.RegisterType <Models.WebsocketApi.JudgerStatusUpdateMsg>();
            dis.RegisterType <Models.WebsocketApi.NewJobUpdateMsg>();
            dis.RegisterType <Models.WebsocketApi.SubscribeMsg>();
            dis.RegisterType <Models.WebsocketApi.TestOutputUpdateMsg>();
            dis.RegisterType <Models.WebsocketApi.SubscribeOutputMsg>();
            dis.DiscriminatorPolicy = DiscriminatorPolicy.Always;

            opt.IgnoreNullValues    = true;
            opt.AllowTrailingCommas = true;
            opt.ReadCommentHandling = JsonCommentHandling.Skip;
            return(opt);
        }
예제 #6
0
        public void TestWrite()
        {
            JsonSerializerOptions           options  = new JsonSerializerOptions().SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "$type"));
            registry.RegisterType <MessageResult>();
            registry.RegisterType <StatusResult>();

            const string json1     = "{\"data\":{\"$type\":\"message\",\"message_id\":770,\"message_content\":1},\"id\":\"6nd28c1\",\"status\":\"ok\"}";
            Response     response1 = JsonSerializer.Deserialize <Response>(json1, options);

            Assert.NotNull(response1);
            Assert.Equal("6nd28c1", response1.Id);
            Assert.Equal("ok", response1.Status);
            Assert.NotNull(response1.Data);
            MessageResult messageResult = Assert.IsType <MessageResult>(response1.Data);

            Assert.Equal(770, messageResult.MessageId);
            Assert.Equal(1, messageResult.Content);

            const string json2     = "{\"data\":{\"$type\":\"status\",\"status_id\":12},\"id\":\"6nd28c1\",\"status\":\"ok\"}";
            Response     response2 = JsonSerializer.Deserialize <Response>(json2, options);

            Assert.NotNull(response2);
            Assert.Equal("6nd28c1", response2.Id);
            Assert.Equal("ok", response2.Status);
            Assert.NotNull(response2.Data);
            StatusResult statusResult = Assert.IsType <StatusResult>(response2.Data);

            Assert.Equal(12, statusResult.StatusId);
        }
예제 #7
0
        public static void ConfigJsonOptions(JsonSerializerOptions options)
        {
            options.Converters.Add(new ObjectIdConverter());
            options.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;

            options.SetupExtensions();

            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "_t"));
            registry.RegisterType <TextMsg>();
            registry.RegisterType <FileMsg>();
            registry.RegisterType <ImageMsg>();
            registry.RegisterType <RTextMsg>();
            registry.RegisterType <RImageMsg>();
            registry.RegisterType <RFileMsg>();
            registry.RegisterType <RForwardMsg>();
            registry.RegisterType <WsSendChatMsg>();
            registry.RegisterType <WsSendOnlineStatusMsg>();
            registry.RegisterType <WsSendUnreadCountMsg>();
            registry.RegisterType <WsSendErrMsg>();
            registry.RegisterType <WsRecvChatMsg>();
            registry.RegisterType <WsRecvReadPositionMsg>();
            registry.DiscriminatorPolicy = DiscriminatorPolicy.Always;

            options.IgnoreNullValues    = true;
            options.AllowTrailingCommas = true;
            options.ReadCommentHandling = JsonCommentHandling.Skip;
        }
예제 #8
0
        public bool ShouldSerialize(object obj, Type declaredType, JsonSerializerOptions options)
        {
            if (_discriminatorConvention == null)
            {
                return(false);
            }

            DiscriminatorPolicy discriminatorPolicy = _discriminatorPolicy != DiscriminatorPolicy.Default ? _discriminatorPolicy
                : (options.GetDiscriminatorConventionRegistry().DiscriminatorPolicy != DiscriminatorPolicy.Default ? options.GetDiscriminatorConventionRegistry().DiscriminatorPolicy : DiscriminatorPolicy.Auto);

            return(discriminatorPolicy == DiscriminatorPolicy.Always ||
                   discriminatorPolicy == DiscriminatorPolicy.Auto && obj.GetType() != declaredType);
        }
예제 #9
0
        public void ReadWithDiscriminator()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            options.GetDiscriminatorConventionRegistry().ClearConventions();
            options.GetDiscriminatorConventionRegistry().RegisterConvention(
                new DefaultDiscriminatorConvention <string>(options, "_t"));
            options.GetObjectMappingRegistry().Register <InheritedObject>(objectMapping =>
                                                                          objectMapping
                                                                          .AutoMap()
                                                                          .SetDiscriminator("inherited")
                                                                          );

            const string json = @"{""_t"":""inherited"",""InheritedValue"":13,""BaseValue"":12}";
            BaseObject   obj  = Helper.Read <BaseObject>(json, options);

            Assert.NotNull(obj);
            Assert.IsType <InheritedObject>(obj);
            Assert.Equal(12, obj.BaseValue);
            Assert.Equal(13, ((InheritedObject)obj).InheritedValue);
        }
예제 #10
0
        public void ReadWithNoDiscriminator()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();

            const string json = @"{""Name"":""foo"",""Id"":12}";
            BaseObject   obj  = JsonSerializer.Deserialize <BaseObject>(json, options);

            Assert.NotNull(obj);
            Assert.Equal(12, obj.Id);
        }
예제 #11
0
        public void WriteWithDiscriminator()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            options.GetDiscriminatorConventionRegistry().ClearConventions();
            options.GetDiscriminatorConventionRegistry().RegisterConvention(
                new DefaultDiscriminatorConvention <string>(options, "_t"));
            options.GetObjectMappingRegistry().Register <InheritedObject>(objectMapping =>
                                                                          objectMapping
                                                                          .SetDiscriminator("inherited")
                                                                          .AutoMap()
                                                                          );

            InheritedObject obj = new InheritedObject
            {
                BaseValue      = 12,
                InheritedValue = 13
            };

            const string json = @"{""_t"":""inherited"",""InheritedValue"":13,""BaseValue"":12}";

            Helper.TestWrite <BaseObject>(obj, json, options);
        }
예제 #12
0
        public void ReadNonAssignablePolymorphicObject()
        {
            const string json = @"{""BaseObject"":{""$type"":13}}";

            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <int>(options));
            registry.RegisterType <NameObject>();
            registry.RegisterType <OtherObject>();

            Assert.ThrowsAny <JsonException>(() => JsonSerializer.Deserialize <BaseObjectHolder>(json, options));
        }
예제 #13
0
        public JsonIntegration()
        {
            _options = new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented        = true
            };
            _options.SetupExtensions();

            var registry = _options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(_options, "_type"));
            registry.RegisterType <MobilePhone>();
            registry.RegisterType <RadioPhone>();
        }
예제 #14
0
        public void Read()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            options.GetObjectMappingConventionRegistry().RegisterProvider(
                new DiscriminatorObjectMappingConventionProvider(t => t == typeof(Foo))
                );
            options.GetDiscriminatorConventionRegistry().DiscriminatorPolicy = DiscriminatorPolicy.Always;

            Assert.Equal(@"{""$type"":""Foo"",""Id"":1}", JsonSerializer.Serialize(new Foo {
                Id = 1
            }, options));
            Assert.Equal(@"{""Id"":1}", JsonSerializer.Serialize(new Bar {
                Id = 1
            }, options));
        }
        public void ReadPolymorphicObjectWithDefaultDiscriminatorConvention()
        {
            const string json = @"{""$type"":""Dahomey.Json.Tests.BaseObjectHolder, Dahomey.Json.Tests"",""BaseObject"":{""$type"":12,""Name"":""foo"",""Id"":1}}";

            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.RegisterConvention(new AttributeBasedDiscriminatorConvention <int>(options));
            registry.RegisterType <NameObject>();

            object obj = JsonSerializer.Deserialize <object>(json, options);

            Assert.NotNull(obj);
            Assert.IsType <BaseObjectHolder>(obj);
        }
예제 #16
0
        public void Test()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.RegisterType <InheritedClass>();

            const string json = @"{""$type"":""InheritedClass"",""Id"":12,""Name"":""foo"",""Age"":13}";

            BaseClass obj = Helper.Read <BaseClass>(json, options);

            Assert.NotNull(obj);
            Assert.Equal(12, obj.Id);
            Assert.Equal("foo", obj.Name);
            Assert.Equal(13, obj.Age);
        }
예제 #17
0
        public void ReadWithCustomDiscriminator()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.RegisterConvention(new CustomDiscriminatorConvention());
            registry.RegisterType(typeof(NameObject2));

            const string      json = @"{""BaseObject"":{""type"":263970807,""Name"":""foo"",""Id"":1}}";
            BaseObjectHolder2 obj  = JsonSerializer.Deserialize <BaseObjectHolder2>(json, options);

            Assert.NotNull(obj);
            Assert.IsType <NameObject2>(obj.BaseObject);
            Assert.Equal("foo", ((NameObject2)obj.BaseObject).Name);
            Assert.Equal(1, obj.BaseObject.Id);
        }
예제 #18
0
        public void Register(IObjectMapping objectMapping)
        {
            IMappingInitialization mappingInitialization = objectMapping as IMappingInitialization;

            if (mappingInitialization != null)
            {
                mappingInitialization.Initialize();
            }

            _objectMappings.AddOrUpdate(objectMapping.ObjectType, objectMapping,
                                        (type, existingObjectMapping) => objectMapping);

            _options.GetDiscriminatorConventionRegistry().RegisterType(objectMapping.ObjectType);

            if (mappingInitialization != null)
            {
                mappingInitialization.PostInitialize();
            }
        }
        public void ReadPolymorphicObject()
        {
            const string json = @"{""BaseObject"":{""$type"":12,""Name"":""foo"",""Id"":1}}";

            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.RegisterConvention(new AttributeBasedDiscriminatorConvention <int>(options));
            registry.RegisterType <NameObject>();

            BaseObjectHolder obj = JsonSerializer.Deserialize <BaseObjectHolder>(json, options);

            Assert.NotNull(obj);
            Assert.IsType <NameObject>(obj.BaseObject);
            Assert.Equal("foo", ((NameObject)obj.BaseObject).Name);
            Assert.Equal(1, obj.BaseObject.Id);
        }
예제 #20
0
        public void TestPolymorphicMissingMemberHandlingIgnore()
        {
            JsonSerializerOptions options = new JsonSerializerOptions().SetupExtensions();

            options.SetMissingMemberHandling(MissingMemberHandling.Ignore);

            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "Type"));
            registry.RegisterType <Derived>();

            const string json = @"{""Type"":""Derived"",""Int"":42,""String"":""xyz"",""Missing"":0}";
            var          obj  = JsonSerializer.Deserialize <Base>(json, options);

            Assert.NotNull(obj);
            Assert.IsType <Derived>(obj);
            Assert.Equal(42, obj.Int);
            Assert.Equal("xyz", (obj as Derived).String);
        }
예제 #21
0
        public void WriteWithNoDiscriminatorConvention()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();

            NameObject obj = new NameObject
            {
                Id   = 12,
                Name = "foo"
            };

            string       actual   = JsonSerializer.Serialize <BaseObject>(obj, options);
            const string expected = @"{""Name"":""foo"",""Id"":12}";

            Assert.Equal(expected, actual);
        }
예제 #22
0
        public void ReadPolymorphicObjectWithDeferredTypeProperty()
        {
            const string json = @"{""BaseObject"":{""Name"":""foo"",""Id"":1,""Unknown"":{""Prop1"":12,""Prop2"":""bar""},""$type"":12}}";

            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <int>(options));
            registry.RegisterType <NameObject>();

            BaseObjectHolder obj = JsonSerializer.Deserialize <BaseObjectHolder>(json, options);

            Assert.NotNull(obj);
            NameObject nameObject = Assert.IsType <NameObject>(obj.BaseObject);

            Assert.Equal("foo", nameObject.Name);
            Assert.Equal(1, nameObject.Id);
        }
예제 #23
0
        public void Test()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.ClearConventions();
            registry.RegisterConvention(new DefaultDiscriminatorConvention <string>(options, "Tag"));
            registry.RegisterType <Box>();
            registry.RegisterType <Circle>();

            Shape origin1 = new Box {
                Width = 10, Height = 20
            };
            Shape origin2 = new Circle {
                Radius = 30
            };

            string json1 = JsonSerializer.Serialize(origin1, options);
            string json2 = JsonSerializer.Serialize(origin2, options);

            Assert.Equal(@"{""Tag"":""Box"",""Width"":10,""Height"":20}", json1);
            Assert.Equal(@"{""Tag"":""Circle"",""Radius"":30}", json2);

            Shape restored1 = JsonSerializer.Deserialize <Shape>(json1, options);
            Shape restored2 = JsonSerializer.Deserialize <Shape>(json2, options);

            Assert.NotNull(restored1);
            Box restoredBox = Assert.IsType <Box>(restored1);

            Assert.Equal(10, restoredBox.Width);
            Assert.Equal(20, restoredBox.Height);

            Assert.NotNull(restored2);
            Circle restoredCircle = Assert.IsType <Circle>(restored2);

            Assert.Equal(30, restoredCircle.Radius);
        }
예제 #24
0
        public void WriteWithCustomDiscriminator()
        {
            JsonSerializerOptions options = new JsonSerializerOptions();

            options.SetupExtensions();
            DiscriminatorConventionRegistry registry = options.GetDiscriminatorConventionRegistry();

            registry.RegisterConvention(new CustomDiscriminatorConvention());
            registry.RegisterType(typeof(NameObject2));

            BaseObjectHolder2 obj = new BaseObjectHolder2
            {
                BaseObject = new NameObject2
                {
                    Id   = 1,
                    Name = "foo"
                },
            };

            string       actual   = JsonSerializer.Serialize(obj, options);
            const string expected = @"{""BaseObject"":{""type"":263970807,""Name"":""foo"",""Id"":1},""NameObject"":null}";

            Assert.Equal(expected, actual);
        }
예제 #25
0
        public void AddDiscriminatorMapping()
        {
            DiscriminatorMapping <T> memberMapping = new DiscriminatorMapping <T>(_options.GetDiscriminatorConventionRegistry(), this);

            _memberMappings.Insert(0, memberMapping);
        }
예제 #26
0
        public ObjectMapping(JsonSerializerOptions options)
        {
            _options   = options;
            ObjectType = typeof(T);

            if (!ObjectType.IsAbstract && !ObjectType.IsInterface && !ObjectType.IsStruct())
            {
                DiscriminatorMapping <T> memberMapping = new DiscriminatorMapping <T>(_options.GetDiscriminatorConventionRegistry(), this);
                _memberMappings.Add(memberMapping);
            }
        }
예제 #27
0
        public void Apply <T>(JsonSerializerOptions options, ObjectMapping <T> objectMapping)
        {
            Type type = objectMapping.ObjectType;
            List <MemberMapping <T> > memberMappings = new List <MemberMapping <T> >();

            JsonDiscriminatorAttribute?discriminatorAttribute = type.GetCustomAttribute <JsonDiscriminatorAttribute>();

            if (discriminatorAttribute != null && options.GetDiscriminatorConventionRegistry().AnyConvention())
            {
                objectMapping.SetDiscriminator(discriminatorAttribute.Discriminator);
                objectMapping.SetDiscriminatorPolicy(discriminatorAttribute.Policy);
            }

            Type?namingPolicyType = type.GetCustomAttribute <JsonNamingPolicyAttribute>()?.NamingPolicyType;

            if (namingPolicyType != null)
            {
                JsonNamingPolicy?namingPolicy = (JsonNamingPolicy?)Activator.CreateInstance(namingPolicyType);

                if (namingPolicy == null)
                {
                    throw new JsonException($"Cannot instantiate naming policy {namingPolicyType}");
                }

                objectMapping.SetPropertyNamingPolicy(namingPolicy);
            }

            PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
            FieldInfo[]    fields     = type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);

            foreach (PropertyInfo propertyInfo in properties)
            {
                if (propertyInfo.IsDefined(typeof(JsonIgnoreAttribute)))
                {
                    continue;
                }

                if (propertyInfo.IsDefined(typeof(JsonExtensionDataAttribute)))
                {
                    objectMapping.MapExtensionData(propertyInfo);
                    continue;
                }

                MethodInfo?getMethod = propertyInfo.GetMethod;

                if (getMethod == null)
                {
                    continue;
                }

                if ((getMethod.IsPrivate || getMethod.IsStatic) &&
                    !propertyInfo.IsDefined(typeof(JsonPropertyNameAttribute)) &&
                    !propertyInfo.IsDefined(typeof(JsonPropertyAttribute)))
                {
                    continue;
                }

                MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, propertyInfo, propertyInfo.PropertyType);
                ProcessDefaultValue(propertyInfo, memberMapping);
                ProcessShouldSerializeMethod(memberMapping);
                ProcessRequired(propertyInfo, memberMapping);
                ProcessMemberName(propertyInfo, memberMapping);
                ProcessConverter(propertyInfo, memberMapping);
                ProcessDeserialize(propertyInfo, memberMapping);
                memberMappings.Add(memberMapping);
            }

            foreach (FieldInfo fieldInfo in fields)
            {
                if (fieldInfo.IsDefined(typeof(JsonIgnoreAttribute)))
                {
                    continue;
                }

                if ((fieldInfo.IsPrivate || fieldInfo.IsStatic) &&
                    !fieldInfo.IsDefined(typeof(JsonPropertyNameAttribute)) &&
                    !fieldInfo.IsDefined(typeof(JsonPropertyAttribute)))
                {
                    continue;
                }

                Type fieldType = fieldInfo.FieldType;

                MemberMapping <T> memberMapping = new MemberMapping <T>(options, objectMapping, fieldInfo, fieldInfo.FieldType);
                ProcessDefaultValue(fieldInfo, memberMapping);
                ProcessShouldSerializeMethod(memberMapping);
                ProcessRequired(fieldInfo, memberMapping);
                ProcessMemberName(fieldInfo, memberMapping);
                ProcessConverter(fieldInfo, memberMapping);

                memberMappings.Add(memberMapping);
            }

            objectMapping.AddMemberMappings(memberMappings);

            ConstructorInfo[] constructorInfos = type.GetConstructors(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

            ConstructorInfo constructorInfo = constructorInfos
                                              .FirstOrDefault(c => c.IsDefined(typeof(JsonConstructorAttribute)));

            if (constructorInfo != null)
            {
                JsonConstructorAttribute?constructorAttribute = constructorInfo.GetCustomAttribute <JsonConstructorAttribute>();
                CreatorMapping           creatorMapping       = objectMapping.MapCreator(constructorInfo);
                if (constructorAttribute != null && constructorAttribute.MemberNames != null)
                {
                    creatorMapping.SetMemberNames(constructorAttribute.MemberNames);
                }
            }
            // if no default constructor, pick up first one
            else if (constructorInfos.Length > 0 && !constructorInfos.Any(c => c.GetParameters().Length == 0))
            {
                constructorInfo = constructorInfos[0];
                objectMapping.MapCreator(constructorInfo);
            }

            MethodInfo methodInfo = type.GetMethods()
                                    .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializingAttribute)));

            if (methodInfo != null)
            {
                objectMapping.SetOnDeserializingMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
            else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize)))
            {
                objectMapping.SetOnDeserializingMethod(t => ((ISupportInitialize?)t)?.BeginInit());
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnDeserializedAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnDeserializedMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
            else if (type.GetInterfaces().Any(i => i == typeof(ISupportInitialize)))
            {
                objectMapping.SetOnDeserializedMethod(t => ((ISupportInitialize?)t)?.EndInit());
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnSerializingAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnSerializingMethod(GenerateCallbackDelegate <T>(methodInfo));
            }

            methodInfo = type.GetMethods()
                         .FirstOrDefault(m => m.IsDefined(typeof(OnSerializedAttribute)));
            if (methodInfo != null)
            {
                objectMapping.SetOnSerializedMethod(GenerateCallbackDelegate <T>(methodInfo));
            }
        }