Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling possible null value when converting JSON to C# class

Tags:

json

c#

.net

uwp

I've run into an interesting problem when converting API data to a C# class in UWP.

I have an API that returns image dimensions, like this:

{
    "height": "25",
    "width": "25"
}

I also have a class with properties that match the JSON data, generated by json2csharp.com.

public class Image
{
    public int height { get; set; }
    public Uri url { get; set; }
    public int width { get; set; }
}

And I am converting the JSON to a C# class using something like this:

dynamic JsonData = JObject.Parse(JsonString);
Image img = JsonData.ToObject<Image>();

However, if the API does not know the height or width, it returns null instead of an int, like this:

{
    "height": null,
    "width": "25"
}

This obviously causes an exception to throw, specifically this error message:

Newtonsoft.Json.JsonSerializationException: Error converting value {null} to type 'System.Int32'

Is there some way to work around this or handle this scenario?

like image 510
Arlo Avatar asked Dec 22 '18 08:12

Arlo


People also ask

How do I allow null values in JSON?

To include null values in the JSON output of the FOR JSON clause, specify the INCLUDE_NULL_VALUES option. If you don't specify the INCLUDE_NULL_VALUES option, the JSON output doesn't include properties for values that are null in the query results.

Is null valid value in JSON?

One of the changes in RFC 7159 is that a JSON text is not defined as being an object or an array anymore but rather as being a serialized value. This means that with RFC 7159, “null” (as well as “true” and “false”) becomes a valid JSON text. So the JSON text serialized value of a null object is indeed “null”.

How do you check if a JSON object is null?

To check null in JavaScript, use triple equals operator(===) or Object is() method. If you want to use Object.is() method then you two arguments. 1) Pass your variable value with a null value. 2) The null value itself.

When serializing to JSON what happens to NULL values?

When serializing to JSON, if a value of a property in the data object is null, then it will be serialized as a JSON null. Non-existence of a property from the JSON data maps to an unset attribute in the data object space. If the property in the data object is not set (unset), then the property will not appear in the JSON data.

How to handle null and empty arrays and objects in JSON?

Handling JSON null and empty arrays and objects 1 Null values. JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types. 2 Unset property. Non-existence of a property from the JSON data maps to an unset attribute in the data object space. ... 3 Empty property

How to add null values to target JSON data?

If there is a specific need to put NULL in target JSON data then use the following workaround: Create one Expression Transformation just before the Data Processor. Add ports for which NULL values are generated. Connect port from expression transformation to Data Processor.

What is null and unset in JSON?

JSON data has the concept of null and empty arrays and objects. This section explains how each of these concepts is mapped to the data object concepts of null and unset. JSON has a special value called null which can be set on any type of data including arrays, objects, number and boolean types.


4 Answers

You can make an int nullable by adding a ?:

public class Image
{
    public int? height { get; set; }
    public Uri url { get; set; }
    public int? width { get; set; }
}

Other than json2csharp.com, QuickType can also help you do this:

public partial class Image
{
    [JsonProperty("height")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long? Height { get; set; }

    [JsonProperty("width")]
    [JsonConverter(typeof(ParseStringConverter))]
    public long Width { get; set; }
}

You have to add in the URL property yourself. QuickType also generates a bunch of other things for you as well, such as the ParseStringConverter custom JsonConverter.

like image 137
Sweeper Avatar answered Oct 31 '22 14:10

Sweeper


If you're expecting null for your data, then use nullbale types. Change your class to:

public class Image {
    public int? height { get; set; }
    public Uri url { get; set; }
    public int? width { get; set; }
}
like image 28
Racil Hilan Avatar answered Oct 31 '22 13:10

Racil Hilan


Another workable approach:

JsonConvert.SerializeObject(myObject, 
                            Newtonsoft.Json.Formatting.None, 
                            new JsonSerializerSettings { 
                                NullValueHandling = NullValueHandling.Ignore
                            });
like image 35
Majedur Avatar answered Oct 31 '22 15:10

Majedur


I agree with the other answers that suggest nullable integers. This seems like the most clean approach. If nullable integers are no option, you could indeed try the NullValueHandling option and leave the integers at their default value. As a compliment to the other answers here, I have included a example that uses the NullValueHandling setting.

Fiddle (running example on dotnetfiddle)

Code

using System;
using Newtonsoft.Json;

public class Program
{
    private static string JsonWithNull = @"{ 'height': '25', 'width': null }";

    public static void Main()
    {
        var settings = new JsonSerializerSettings()
        {
            NullValueHandling = NullValueHandling.Ignore
        };

        Image image = JsonConvert.DeserializeObject<Image>(JsonWithNull, settings);

        Console.WriteLine("The image has a height of '{0}' and a width of '{1}'", image.height, image.width);
    }
}

public class Image
{   
    public int height { get; set; }
    public Uri url { get; set; }
    public int width { get; set; }
}
like image 30
Fluous Avatar answered Oct 31 '22 14:10

Fluous