Search code examples
c#jsonjson.netjsonconvert

Using JsonConvert.DeserializeObject, how to warn about missing members, but continue deserializing?


I am using JsonConvert.DeserializeObject to deserialize some objects. There is a possibility that the properties in the json file may not be present in the corresponding definition. When this happens, I want to essentially ignore the field and continue deserializing, but print a warning in the console that the field was missing.

The documentation for DeserializeObject shows that an additional JsonSerializerSettings argument can be given, and that contains a MissingMemberHandling setting. However, the two options available for that setting are Ignore and Error. The former silently ignores missing fields and continues, and the latter stops the deserialization and throws an error. I seem to need something in between these two.

I have seen the similar question here Detect if deserialized object is missing a field with the JsonConvert class in Json.NET. However, in this question, the original post wants the deserializer to throw an error and stop deserializing. I would like it to continue, but just inform the user of the field mismatch. Is there a way to do this?


Solution

  • You can do something like this:

    using Newtonsoft.Json;
    using Newtonsoft.Json.Serialization;
    using System;
    
    namespace NewtonsoftJsonSample
    {
      public static class Program
      {
        public static void Main(string[] args)
        {
          var json = "{'name': 'john', 'age': 45, 'city': 'Bristol'}".Replace("'", "\"");
    
          // remember to set an error handler and to raise an error each time a member is missing
          // during deserialization
          var settings = new JsonSerializerSettings
          {
            Error = OnError,
            MissingMemberHandling = MissingMemberHandling.Error
          };
    
          var deserialized = JsonConvert.DeserializeObject<Character>(json, settings);
    
          Console.WriteLine("Deserialized object: {0}", deserialized);
          Console.ReadLine();
    
          static void OnError(object sender, ErrorEventArgs args) 
          {
            Console.WriteLine("Unable to find member '{0}' on object of type {1}", args.ErrorContext.Member, args.ErrorContext.OriginalObject.GetType().Name);
            
            // set the current error as handled
            args.ErrorContext.Handled = true;
          }
        }
      }
    
      public class Character
      {
        public string Name { get; set; }
    
        public override string ToString()
        {
          return $"Name: {this.Name}";
        }
      }
    }
    

    Basically you need to use both MissingMemberHandling and Error properties of JsonSerializerSettings class.