How to configure JSON.net deserializer to track missing properties?

前端 未结 3 1061

Sample class:

public class ClassA
{
    public int Id { get; set; }
    public string SomeString { get; set; }
    public int? SomeInt { get; set; }
}
         


        
3条回答
  •  再見小時候
    2020-12-18 08:34

    1. JSON has a property which is missing in your class

    Using property JsonSerializerSettings.MissingMemberHandling you can say whether missing properties are handled as errors.

    Than you can install the Error delegate which will register errors.

    This will detect if there is some "garbage" property in JSON string.

    public class ClassA
    {
        public int Id { get; set; }
        public string SomeString { get; set; }
    }
    
    internal class Program
    {
        private static void Main(string[] args)
        {
            const string str = "{'Id':5, 'FooBar': 42 }";
            var myObject = JsonConvert.DeserializeObject(str
                , new JsonSerializerSettings
                {
                    Error = OnError,
                    MissingMemberHandling = MissingMemberHandling.Error
                });
    
            Console.ReadKey();
        }
    
        private static void OnError(object sender, ErrorEventArgs args)
        {
            Console.WriteLine(args.ErrorContext.Error.Message);
            args.ErrorContext.Handled = true;
        }
    }
    

    2. Your class has a property which is missing in JSON

    Option 1:

    Make it a required property:

        public class ClassB
        {
            public int Id { get; set; }
    
            [JsonProperty(Required = Required.Always)]
            public string SomeString { get; set; }
    
        }
    
    Option 2:

    Use some "special" value as a default value and check afterwards.

    public class ClassB
    {
        public int Id { get; set; }
    
        [DefaultValue("NOTSET")]
        public string SomeString { get; set; }
        public int? SomeInt { get; set; }
    }
    
    internal class Program
    {
        private static void Main(string[] args)
        {
            const string str = "{ 'Id':5 }";
            var myObject = JsonConvert.DeserializeObject(str
                , new JsonSerializerSettings
                {
                    DefaultValueHandling = DefaultValueHandling.Populate
                });
    
            if (myObject.SomeString == "NOTSET")
            {
                Console.WriteLine("no value provided for property SomeString");
            }
    
            Console.ReadKey();
        }
    }
    
    Option 3:

    Another good idea would be to encapsulate this check iside the class istself. Create a Verify() method as shown below and call it after deserialization.

    public class ClassC
    {
        public int Id { get; set; }
    
        [DefaultValue("NOTSET")]
        public string SomeString { get; set; }
        public int? SomeInt { get; set; }
    
        public void Verify()
        {
            if (SomeInt == null ) throw new JsonSerializationException("SomeInt not set!");
            if (SomeString == "NOTSET") throw new JsonSerializationException("SomeString not set!");
        }
    }
    

提交回复
热议问题