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?
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.
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”.
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, 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.
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
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.
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.
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
.
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; }
}
Another workable approach:
JsonConvert.SerializeObject(myObject,
Newtonsoft.Json.Formatting.None,
new JsonSerializerSettings {
NullValueHandling = NullValueHandling.Ignore
});
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; }
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With