101

I have the following code:

return (DataTable)JsonConvert.DeserializeObject(_data, (typeof(DataTable)));

Then, I tried:

var jsonSettings = new JsonSerializerSettings
{
    NullValueHandling = NullValueHandling.Ignore
};

return (DataTable)JsonConvert.DeserializeObject<DataTable>(_data, jsonSettings);

The return line is throwing the error:

{"Error converting value \"\" to type 'System.Double'."}

Lots of solutions online suggesting creating custom Class with nullable types but this won't work for me. I can't expect the json to be in a certain format. I have no control over the column count, column type, or column names.

4
  • 1
    Perhaps you should just use LINQ to JSON instead, and get a JObject instead of creating a DataTable? Commented Aug 4, 2015 at 15:22
  • If you need to convert DataTable use the dedicated converter DataTableConverter Commented Aug 4, 2015 at 15:26
  • 2
    Can you share an example of the JSON that is causing the problem? Commented Aug 4, 2015 at 15:42
  • @Candide Same error when using return JsonConvert.DeserializeObject<DataTable>(_data, new DataTableConverter()); Commented Aug 4, 2015 at 16:27

4 Answers 4

264

You can supply settings to JsonConvert.DeserializeObject to tell it how to handle null values, in this case, and much more:

var settings = new JsonSerializerSettings
                    {
                        NullValueHandling = NullValueHandling.Ignore,
                        MissingMemberHandling = MissingMemberHandling.Ignore
                    };
var jsonModel = JsonConvert.DeserializeObject<Customer>(jsonString, settings);
Sign up to request clarification or add additional context in comments.

4 Comments

This is the perfect answer - I've been scouring solutions and finally one that works. Hero status.
MissingMemberHandling = MissingMemberHandling.Ignore is default. No need to add it.
I got an error when deserializing the primitive type (long, int) properties in my class. The json comes from different api which i cannot control. The generic solution worked for me. Thank you Thomas
imo these should be the default settings for the Deserializer. It shouldn't bug out and break your code by default just because a null value was encountered
37

An alternative solution for Thomas Hagström, which is my prefered, is to use the property attribute on the member variables.

For example when we invoke an API, it may or may not return the error message, so we can set the NullValueHandling property for ErrorMessage:


    public class Response
    {
        public string Status;

        public string ErrorCode;

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string ErrorMessage;
    }


    var response = JsonConvert.DeserializeObject<Response>(data);

The benefit of this is to isolate the data definition (what) and deserialization (use), the deserilazation needn’t to care about the data property, so that two persons can work together, and the deserialize statement will be clean and simple.

1 Comment

A downside of this, in my humble opinion, is that you couple a (fairly straightforward) data class to a specific library's implementation details. I guess it depends on your implementation.
6

You can subscribe to the 'Error' event and ignore the serialization error(s) as required.

    static void Main(string[] args)
    {
        var a = JsonConvert.DeserializeObject<DataTable>("-- JSON STRING --", new JsonSerializerSettings
        {
            Error = HandleDeserializationError
        });
    }

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

3 Comments

This ignores the error all right. But the DataTable object returned is null.
Can you post the JSON string and then i will alter my answer to better suit.
After trying everything else, and struggling with the absurdly bad "ArgumentNullException" which randomly occurs anywhere in 100,000s lines of JSON ... this was the first thing that worked. It's embarassing that JSON APIs are so bad at error reporting :(.
4

ASP.NET CORE: The accepted answer works perfectly. But in order to make the answer apply globally, in startup.cs file inside ConfigureServices method write the following:

    services.AddControllers().AddNewtonsoftJson(options =>
    {
        options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
    });

The answer has been tested in a .Net Core 3.1 project.

2 Comments

without context about what services you are accessing, the answer would be both incomplete and wrong.
This is actually very good answer for contemporary code since the problem of setting global JSON deserialization options keeps surfacing up a lot.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.