1
votes

impossible de désérialiser la valeur nulle en c #

J'utilise le code ci-dessous pour renvoyer Task mais je ne sais pas comment désérialiser la valeur nulle.

Comment gérer le code si la valeur finalResult est Null.

public async Task<T> PostAsync<T>(JObject parameters)
{
    string sasURL = await GenerateLogicAppSASUrl();
    var param = new StringContent(parameters.ToString(), Encoding.UTF8, "application/json");
    var httpCall = await client.PostAsync(sasURL, param);
    var result = await httpCall.Content.ReadAsStringAsync();
    var finalResult = JObject.Parse(result)["Column1"]?.ToString();  
    return  JsonConvert.DeserializeObject<T>(finalResult); // what to return if finalResult value here is null
}

p>


6 commentaires

Je pense qu'une question similaire a été répondue ici: stackoverflow.com/questions/31813055/...


Quelle est la valeur exacte des données ?


La valeur finalResult sera nulle ou des données de type générique


retourne null, n'essayez pas de désérialiser, dans tous les cas Newtonsoft Json peut gérer les valeurs nulles et elles peuvent être désérialisées selon le paramètre


Utilisant ?? erreur de lancement comme "Opérateur '??' ne peut pas être appliqué aux opérandes de type 'chaîne' et 'T' "


@MrinalKamboj Cette ligne essaie simplement de désérialiser finalResult s'il est nul, sinon le retourne simplement tel quel ...


3 Réponses :


3
votes

JsonConvert.DeserializeObject () lève ArgumentNullException lorsque l'argument est nul.

Vous pouvez soit lancer une exception si votre finalResult code > la variable est nulle, ou renvoie null de votre méthode au lieu de la désérialiser:

return finalResult == null ? default(T): JsonConvert.DeserializeObject<T>(finalResult);


2 commentaires

@ chrisb-de OP a mentionné qu'il avait une valeur nulle


Bien sur. await httpCall.Content.ReadAsStringAsync () permet de récupérer null. Mais je ne vois aucune restriction sur T lui-même. Lorsque vous appelez la méthode comme ceci PostAsync (paramètres) , le résultat attendu peut ne pas être nul du tout.



2
votes

Solution 1:

return (finalResult != null) ? JsonConvert.DeserializeObject<T>(finalResult) : default(T)

Exemple Json.Net pour comprendre le paramètre ci-dessus

void Main()
{
    Test t = new Test 
    {
     Str = null,
     Val=1
    };

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

    var json = JsonConvert.SerializeObject(t,jsonSettings);

    json.Dump();    

    var result = JsonConvert.DeserializeObject<Test>(json, jsonSettings);

    result.Dump();
}

public class Test
{
    public string Str {get;set;}

    public int Val {get; set;}
}

Résultats:

 entrez la description de l'image ici

Explication:

  1. Les paramètres Json de gestion des valeurs nulles ignorent la valeur nulle lors de la sérialisation
  2. Lors de la désérialisation, la même valeur est introduite avec une valeur nulle
  3. La valeur nulle doit appartenir aux champs et non à l'objet entier, si l'objet entier est nul, il n'y a pas de sérialisation, de désérialisation requise, il peut être préempté via la logique

Solution 2:

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

var result = JsonConvert.DeserializeObject<T>(data, jsonSettings); // jsonSettings are explicitly supplied

Ma préférence est Solution1 car elle gérera les valeurs nulles en interne au niveau de la bibliothèque Serializer


8 commentaires

Solution1 lançant une erreur comme "System.ArgumentNullException: 'La valeur ne peut pas être nulle. Nom du paramètre: valeur'"


Vous obtenez une exception de l'appel Json.Net DeserializeObject alors je serais surpris, c'est la manière par défaut documentée


@Mrinal Kaboj: votre première solution nécessite des paramètres supplémentaires pour JsonConvert.DeserializeObject. J'imagine avoir ces paramètres partout dans le code. À mon avis, un cauchemar. Le simple retour de la valeur par défaut lorsque les données sont nulles semble être le moyen le plus propre.


@ chrisb-de n'est pas aussi mauvais que nous utilisons des modèles comme Factory pour éviter la création d'objets répétitifs et rendre le code propre. En fait, ces paramètres peuvent également être au niveau du projet


Pourquoi devriez-vous configurer cela au niveau du projet ou n'importe où ailleurs, alors qu'un simple if (data == null) renvoie default; suffirait? je ne vois pas l'intérêt d'introduire plus de complexité pour résoudre un problème aussi trivial et prévisible. Je préfère donc la deuxième solution. :-)


@ chrisb-de, utilisé par défaut (T), cela a résolu mon problème.Réponse courte et simple, merci


@ chrisb-de, un paramètre de sérialiseur par défaut est censé être à l'échelle du projet ou global avec une portée de paramètres spécifiques pour quelques constructions logiques. L'instruction qui vérifie et retourne null est un code répétitif, une telle logique est toujours préférable d'être gérée via Serializer au lieu d'un code personnalisé. Maintient la conception propre.


@chandrasekhar vérifie ma réponse mise à jour qui explique le fonctionnement des paramètres du sérialiseur pour gérer la valeur nulle. La valeur nulle doit être des champs de l'objet, l'objet complet ne peut pas être nul



0
votes

Vous pouvez créer une méthode de chaîne d'extension comme celle-ci:

public static dynamic Deserialize(this string stg, Type typeWanted)
    {
         var model = Activator.CreateInstance(typeWanted);

        if (string.IsNullOrEmpty(stg))
            return model;

        model = JsonConvert.DeserializeObject(stg, typeWanted);

        return model;
    }


0 commentaires