Sergey Kulgan
Sergey Kulgan

Reputation: 1295

Handling error of json deserialisation

How to get original json string (that was passed to JsonConvert.DeserializeObject method) from JsonSerializer.Error handler ?

public MyModel ParseFromJsonString(string jsonString)
{
     var jsonSerializerSettings = new JsonSerializerSettings()
     {
         jsonSerializerSettings.Error = OnError;
     }
     return JsonConvert.DeserializeObject<MyModel>(jsonString, jsonSerializerSettings);
}

...

private void OnError(object sender, ErrorEventArgs errorEventArgs)
{
     //How to get this from current place ?
     string originalJsonString; 
     //in log record I want to mention incoming json string that was processed by deserialization
     logger.Error("error: {0}, happened at deserialisation json: {1}", errorEventArgs.ErrorContext.Error.Message, originalJsonString);
     //allows to continues deserializing, ignoring error and prevents throwing exception
     errorEventArgs.ErrorContext.Handled = true;
 }

There are no such property in errorEventArgs, then I thought that it should be in "sender" which is instance of JsonSerializer, it contains many properties, but there I also did not found. Do not understand, why so cool package as json.net did not include this. String is a reference type, so it should be possible to store reference to the same string instance in errorEventArgs and no problems with consuming additional memory for duplicating (what can decrease performance in case of big json)

Upvotes: 2

Views: 3276

Answers (2)

EZI
EZI

Reputation: 15364

By converting your error handler to lambda, you can access it with the help of c# compiler.

public MyModel ParseFromJsonString(string jsonString)
{
    var jsonSerializerSettings = new JsonSerializerSettings()
    {
        Error = (sender, errorEventArgs) => 
        {
            //You can use your "jsonString" here
        }
    };

    return JsonConvert.DeserializeObject<MyModel>(jsonString, jsonSerializerSettings);
}

PS: How does it work? C# Closures Explained , Closures In C#

Upvotes: 3

Samuel Davidson
Samuel Davidson

Reputation: 791

I have looked through the ErrorEventArgs and there is no property with the original string within the class. However you could do something similar to EZI's answer.

Change the method signature of your OnError method to something like this:

private void OnJsonError(object sender, ErrorEventArgs errorEventArgs, string jsonString)

Then within your JsonSerializerSettings construction do the following:

var jsonSerializerSettings = new JsonSerializerSettings()
{
  Error = (sender, errorEventArgs) => { OnJsonError(sender,errorEventArgs,jsonString); }
};

That way you maintain the re-usability of the OnJsonError method while adding minimal lines of code to your original work.

Upvotes: 2

Related Questions