示例#1
0
        public static void CombiningSingleResolverProducesSameAnswersAsInputResolver()
        {
            JsonSerializerOptions options = new();
            JsonTypeInfo          t1      = JsonTypeInfo.CreateJsonTypeInfo(typeof(int), options);
            JsonTypeInfo          t2      = JsonTypeInfo.CreateJsonTypeInfo(typeof(uint), options);
            JsonTypeInfo          t3      = JsonTypeInfo.CreateJsonTypeInfo(typeof(string), options);

            // we return same instance for easier comparison
            TestResolver resolver = new((t, o) =>
            {
                Assert.Same(o, options);
                if (t == typeof(int))
                {
                    return(t1);
                }
                if (t == typeof(uint))
                {
                    return(t2);
                }
                if (t == typeof(string))
                {
                    return(t3);
                }
                return(null);
            });

            IJsonTypeInfoResolver combined = JsonTypeInfoResolver.Combine(resolver);

            Assert.Same(t1, combined.GetTypeInfo(typeof(int), options));
            Assert.Same(t2, combined.GetTypeInfo(typeof(uint), options));
            Assert.Same(t3, combined.GetTypeInfo(typeof(string), options));
            Assert.Null(combined.GetTypeInfo(typeof(char), options));
            Assert.Null(combined.GetTypeInfo(typeof(StringBuilder), options));
        }
示例#2
0
        public static void JsonPropertyInfoOptionsAreSet()
        {
            JsonSerializerOptions options  = new();
            JsonTypeInfo          typeInfo = JsonTypeInfo.CreateJsonTypeInfo(typeof(MyClass), options);

            CreatePropertyAndCheckOptions(options, typeInfo);

            typeInfo = JsonTypeInfo.CreateJsonTypeInfo <MyClass>(options);
            CreatePropertyAndCheckOptions(options, typeInfo);

            typeInfo = options.TypeInfoResolver.GetTypeInfo(typeof(MyClass), options);
            CreatePropertyAndCheckOptions(options, typeInfo);
示例#3
0
    public JsonTypeInfo?GetTypeInfo(Type type, JsonSerializerOptions options)
    {
        if (!IsStandardMessage(type, out var messageDescriptor))
        {
            return(null);
        }

        var typeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, options);

        typeInfo.CreateObject = () => Activator.CreateInstance(type) !;

        var fields = messageDescriptor.Fields.InFieldNumberOrder();

        // The field map can have multiple entries for a property:
        // 1. The JSON field name, e.g. firstName. This is used to serialize and deserialize JSON.
        // 2. The original field name, e.g. first_name. This might be different. It is only used to deserialize JSON.
        var mappings = CreateJsonFieldMap(fields);

        foreach (var field in fields)
        {
            var propertyInfo = CreatePropertyInfo(typeInfo, field.JsonName, field, isSerializable: true);
            typeInfo.Properties.Add(propertyInfo);

            // We have a property for reading and writing the JSON name so remove from mappings.
            mappings.Remove(field.JsonName);
        }

        // Fields have two mappings: the original field name and the camelcased JSON name.
        // The JSON name can also be customized in proto with json_name option.
        // Remaining mappings are for extra setter only properties.
        foreach (var mapping in mappings)
        {
            var propertyInfo = CreatePropertyInfo(typeInfo, mapping.Key, mapping.Value, isSerializable: false);
            typeInfo.Properties.Add(propertyInfo);
        }

        return(typeInfo);
    }
示例#4
0
        public static void CombiningUsesAndRespectsAllResolversInOrder()
        {
            JsonSerializerOptions options = new();
            JsonTypeInfo          t1      = JsonTypeInfo.CreateJsonTypeInfo(typeof(int), options);
            JsonTypeInfo          t2      = JsonTypeInfo.CreateJsonTypeInfo(typeof(uint), options);
            JsonTypeInfo          t3      = JsonTypeInfo.CreateJsonTypeInfo(typeof(string), options);

            int resolverId = 1;

            // we return same instance for easier comparison
            TestResolver r1 = new((t, o) =>
            {
                Assert.Equal(1, resolverId);
                Assert.Same(o, options);
                if (t == typeof(int))
                {
                    return(t1);
                }
                resolverId++;
                return(null);
            });

            TestResolver r2 = new((t, o) =>
            {
                Assert.Equal(2, resolverId);
                Assert.Same(o, options);
                if (t == typeof(uint))
                {
                    return(t2);
                }
                resolverId++;
                return(null);
            });

            TestResolver r3 = new((t, o) =>
            {
                Assert.Equal(3, resolverId);
                Assert.Same(o, options);
                if (t == typeof(string))
                {
                    return(t3);
                }
                resolverId++;
                return(null);
            });

            IJsonTypeInfoResolver combined = JsonTypeInfoResolver.Combine(r1, r2, r3);

            resolverId = 1;
            Assert.Same(t1, combined.GetTypeInfo(typeof(int), options));
            Assert.Equal(1, resolverId);

            resolverId = 1;
            Assert.Same(t2, combined.GetTypeInfo(typeof(uint), options));
            Assert.Equal(2, resolverId);

            resolverId = 1;
            Assert.Same(t3, combined.GetTypeInfo(typeof(string), options));
            Assert.Equal(3, resolverId);

            resolverId = 1;
            Assert.Null(combined.GetTypeInfo(typeof(char), options));
            Assert.Equal(4, resolverId);

            resolverId = 1;
            Assert.Null(combined.GetTypeInfo(typeof(StringBuilder), options));
            Assert.Equal(4, resolverId);
        }
示例#5
0
 public override JsonTypeInfo?GetTypeInfo(Type type) => JsonTypeInfo.CreateJsonTypeInfo(type, Options);
        public static void CombineCustomResolverWithDefault()
        {
            TestResolver resolver = new TestResolver((Type type, JsonSerializerOptions options) =>
            {
                if (type != typeof(TestClass))
                {
                    return(null);
                }

                JsonTypeInfo <TestClass> ti = JsonTypeInfo.CreateJsonTypeInfo <TestClass>(options);
                ti.CreateObject             = () => new TestClass()
                {
                    TestField    = string.Empty,
                    TestProperty = 42,
                };

                JsonPropertyInfo field = ti.CreateJsonPropertyInfo(typeof(string), "MyTestField");
                field.Get = (o) =>
                {
                    TestClass obj = (TestClass)o;
                    return(obj.TestField ?? string.Empty);
                };

                field.Set = (o, val) =>
                {
                    TestClass obj = (TestClass)o;
                    string value  = (string?)val ?? string.Empty;
                    obj.TestField = value;
                };

                field.ShouldSerialize = (o, val) => (string)val != string.Empty;

                JsonPropertyInfo prop = ti.CreateJsonPropertyInfo(typeof(int), "MyTestProperty");
                prop.Get = (o) =>
                {
                    TestClass obj = (TestClass)o;
                    return(obj.TestProperty);
                };

                prop.Set = (o, val) =>
                {
                    TestClass obj    = (TestClass)o;
                    obj.TestProperty = (int)val;
                };

                prop.ShouldSerialize = (o, val) => (int)val != 42;

                ti.Properties.Add(field);
                ti.Properties.Add(prop);
                return(ti);
            });

            JsonSerializerOptions options = new JsonSerializerOptions {
                TypeInfoResolver = new DefaultJsonTypeInfoResolver()
            };

            options.IncludeFields    = true;
            options.TypeInfoResolver = JsonTypeInfoResolver.Combine(resolver, options.TypeInfoResolver);

            TestClass originalObj = new TestClass()
            {
                TestField    = "test value",
                TestProperty = 45,
            };

            string json = JsonSerializer.Serialize(originalObj, options);

            Assert.Equal(@"{""MyTestField"":""test value"",""MyTestProperty"":45}", json);

            TestClass deserialized = JsonSerializer.Deserialize <TestClass>(json, options);

            Assert.Equal(originalObj.TestField, deserialized.TestField);
            Assert.Equal(originalObj.TestProperty, deserialized.TestProperty);

            originalObj.TestField = null;
            json = JsonSerializer.Serialize(originalObj, options);
            Assert.Equal(@"{""MyTestProperty"":45}", json);

            originalObj.TestField = string.Empty;
            json = JsonSerializer.Serialize(originalObj, options);
            Assert.Equal(@"{""MyTestProperty"":45}", json);

            deserialized = JsonSerializer.Deserialize <TestClass>(json, options);
            Assert.Equal(originalObj.TestField, deserialized.TestField);
            Assert.Equal(originalObj.TestProperty, deserialized.TestProperty);

            originalObj.TestField    = "test value";
            originalObj.TestProperty = 42;
            json = JsonSerializer.Serialize(originalObj, options);
            Assert.Equal(@"{""MyTestField"":""test value""}", json);
            deserialized = JsonSerializer.Deserialize <TestClass>(json, options);
            Assert.Equal(originalObj.TestField, deserialized.TestField);
            Assert.Equal(originalObj.TestProperty, deserialized.TestProperty);
        }