web-dev-qa-db-fra.com

Gestion de la valeur Null possible lors de la conversion de JSON en classe C #

J'ai rencontré un problème intéressant lors de la conversion de données d'API en classe C # dans UWP.

J'ai une API qui renvoie les dimensions de l'image, comme ceci:

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

J'ai également une classe dont les propriétés correspondent aux données JSON, générées par json2csharp.com .

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

Et je convertis le JSON en classe C # en utilisant quelque chose comme ceci:

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

Cependant, si l'API ne connaît pas la hauteur ni la largeur, elle retourne null au lieu d'une int, comme ceci:

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

Cela provoque évidemment une exception, en particulier ce message d'erreur:

Newtonsoft.Json.JsonSerializationException: erreur lors de la conversion de la valeur {null} en type 'System.Int32'

Existe-t-il un moyen de contourner ce problème ou de gérer ce scénario?

7
Arlo

Vous pouvez rendre une int nullable en ajoutant un ?:

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

Autre que json2csharp.com, QuickType peut également vous aider à le faire:

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

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

Vous devez ajouter vous-même la propriété URL. QuickType génère également beaucoup d'autres choses pour vous, telles que ParseStringConverter custom JsonConverter.

14
Sweeper

Si vous attendez null pour vos données, utilisez des types nullable. Changez votre classe en:

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

Je suis d'accord avec les autres réponses qui suggèrent des entiers nullables. Cela semble être l'approche la plus propre. Si les entiers nuls ne sont pas une option, vous pouvez en effet essayer l'option NullValueHandling et laisser les entiers à leur valeur par défaut. Pour compléter les autres réponses ici, j'ai inclus un exemple utilisant le paramètre NullValueHandling.

Fiddle (exemple en cours sur 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; }
}
1
Fluous

Une autre approche réalisable:

JsonConvert.SerializeObject(myObject, 
                            Newtonsoft.Json.Formatting.None, 
                            new JsonSerializerSettings { 
                                NullValueHandling = NullValueHandling.Ignore
                            });
1
Majedur Rahaman

Considérez l'option Newtonsoft.Json.NullValueHandling.Ignore.

0
Boris Nikitin