Newtonsoft.Json:AllowNull bug?

时间:2017-03-09 13:41:07

标签: c# json json.net

我正在尝试编写序列化程序,它将序列化/反序列化为完全相同的类结构。因此,即使没有提供属性的默认值 - 它也应该抛出错误。我想通过设置成员处理和合同解析器我完成了它,但它不会工作。不应该在任何地方抛出异常(我在合同解析器中明确指出了它)。

这是我的序列化器:

public sealed class JsonSerializer : ISerializer
{
    private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
    {
        ContractResolver = new RequireObjectPropertiesContractResolver(),//Everything required. Null are allowed.
        MissingMemberHandling = MissingMemberHandling.Error, //If something missing in target class - it should throw error.
        Formatting = Formatting.Indented
    };

    public object Deserialize(string input, Type type)
    {
        return JsonConvert.DeserializeObject(input, type, _settings);
    }

    public string Serialize(object input)
    {
        return JsonConvert.SerializeObject(input, _settings);
    }

    private class RequireObjectPropertiesContractResolver : DefaultContractResolver
    {
        protected override JsonObjectContract CreateObjectContract(Type objectType)
        {
            var contract = base.CreateObjectContract(objectType);
            contract.ItemRequired = Required.AllowNull;
            return contract;
        }
    }
}

这是我无法工作的测试用例:

   [DataContract]
    private class TestInput
    {
        [DataMember]
        public string Value0 { get; set; }

        [DataMember]
        public string Value1 { get; set; }

        [DataMember]
        public Inner Inner { get; set; }
    }

    [DataContract]
    private class Inner
    {
        [DataMember]
        public string NewValue0 { get; set; }
    }

    [TestMethod]
    public void TestSerialization()
    {
        using (var kernel = new StandardKernel(new MyModule()))
        {
            var serializer = kernel.Get<ISerializer>();

            //It should throw error because Inner not provided as null (not thrown)
            string json = "{\"Value0\":\"test0\", \"Value1\":\"test1\"}";
            Extensions.Throws<Exception> (()=>serializer.Deserialize(json, typeof(TestInput)));

            //It should throw error because nothing were provided as null (not thrown)
            json = "{}";
            Extensions.Throws<Exception>(() => serializer.Deserialize(json, typeof(TestInput)));

            //this one is correct one (no problems here)
            json = "{\"Value0\":\"test0\", \"Value1\":\"test1\", \"Inner\":null}";
            Extensions.NotThrows(()=>serializer.Deserialize(json, typeof(TestInput)));
        }
    }

这两项测试都没有通过。

1 个答案:

答案 0 :(得分:1)

过了一段时间,我设法让它发挥作用。 DataContract适用于我的类,所以我只是重新分配了他们设置的值:

regex re0("(0+)(?!.*\\1)");
if (regex_search(sch, m, re0)) {
    std::cout << "match '" << m[0] << "' ";
    std::cout << "at position " << m.position(0) << std::endl;  
}

刚刚在所有属性上设置了Required.AllowNull,而不是契约本身。