Ignore parsing errors during JSON.NET data parsing

JsonError Handlingjson.netDeserialization

Json Problem Overview


I have an object with predefined data structure:

public class A
{
    public string Id {get;set;}
    public bool? Enabled {get;set;}
    public int? Age {get;set;}
}

and JSON is supposed to be

{ "Id": "123", "Enabled": true, "Age": 23 }

I want to handle JSON error in positive way, and whenever server returns unexpected values for defined data-types I want it to be ignore and default value is set (null).

Right now when JSON is partially invalid I'm getting JSON reader exception:

{ "Id": "123", "Enabled": "NotABoolValue", "Age": 23 }

And I don't get any object at all. What I want is to get an object:

new A() { Id = "123", Enabled = null, Age = 23 }

and parsing warning if possible. Is it possible to accomplish with JSON.NET?

Json Solutions


Solution 1 - Json

To be able to handle deserialization errors, use the following code:

var a = JsonConvert.DeserializeObject<A>("-- JSON STRING --", new JsonSerializerSettings
    {
        Error = HandleDeserializationError
    });

where HandleDeserializationError is the following method:

public void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
    var currentError = errorArgs.ErrorContext.Error.Message;
    errorArgs.ErrorContext.Handled = true;
}

The HandleDeserializationError will be called as many times as there are errors in the json string. The properties that are causing the error will not be initialized.

Solution 2 - Json

Same thing as Ilija's solution, but a oneliner for the lazy/on a rush (credit goes to him)

var settings = new JsonSerializerSettings { Error = (se, ev) => { ev.ErrorContext.Handled = true; } };
JsonConvert.DeserializeObject<YourType>(yourJsonStringVariable, settings);

Props to Jam for making it even shorter =)

Solution 3 - Json

There is another way. for example, if you are using a nuget package which uses newton json and does deseralization and seralization for you. You may have this problem if the package is not handling errors. then you cant use the solution above. you need to handle in object level. here becomes OnErrorAttribute useful. So below code will catch any error for any property, you can even modify within the OnError function and assign default values

public class PersonError
{
  private List<string> _roles;

  public string Name { get; set; }
  public int Age { get; set; }

  public List<string> Roles
  {
    get
    {
        if (_roles == null)
        {
            throw new Exception("Roles not loaded!");
        }

        return _roles;
    }
    set { _roles = value; }
  }

  public string Title { get; set; }

  [OnError]
  internal void OnError(StreamingContext context, ErrorContext errorContext)
  {
    errorContext.Handled = true;
  }
}

see https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlexey StrakhView Question on Stackoverflow
Solution 1 - JsonIlija DimovView Answer on Stackoverflow
Solution 2 - JsonGaspa79View Answer on Stackoverflow
Solution 3 - JsonEmilView Answer on Stackoverflow