2017-07-29 2 views
0

Lors de la désérialisation d'un objet JSON avec des objets imbriqués, avec une propriété obligatoire sur l'un des objets imbriqués, la désérialisation ne génère pas d'exception. Mais si j'ajoute la décoration JsonProperty.Required à l'objet de base, elle le fait (comme je m'y attendais). Cela se produit lorsque la chaîne d'entrée est le type tout à fait incorrect, mais est correctement formaté JSON. Ainsi, l'entrée problématique est "{\" Errors \ ": [\" Ceci est une erreur \ "]}" (qui est la réponse d'un webservice, soit un tableau de messages d'erreur comme celui-ci, soit c'est une UserInformationRequest correctement sérialisée). Code pour clarifier:Json.NET désérialisant l'objet imbriqué ignore JsonProperty.Required

base de l'objet JsonProperty fonctionne correctement:

public class UserInformation 
    { 
     public string ID; 
     ... 
     public string LoginName; 
     ... 
    } 

    public class UserInformationRequest 
    { 
     [JsonProperty(Required = Required.Always)] 
     public string TimeStamp; 
     public UserInformation User; 
    } 
    ... 
    public static UserInformationRequest GetUserInformationRequestFromString(string userInformation) 
    { 
     try 
     { 
      return JsonConvert.DeserializeObject<UserRequestInformation>(userInformation); 
     } 
     catch (Exception ex) 
     { 
      //exception thrown when userInformation.TimeStamp is null, as expected 
      return null; 
     } 
    } 

Nested JsonProperty ne fonctionne pas correctement:

public class UserInformation 
    { 
     public string ID; 
     ... 
     [JsonProperty(Required = Required.Always)] 
     public string LoginName; 
     ... 
    } 

    public class UserInformationRequest 
    { 
     public string TimeStamp; 
     public UserInformation User; 
    } 
    ... 
    public static UserInformationRequest GetUserInformationRequestFromString(string userInformation) 
    { 
     try 
     { 
      return JsonConvert.DeserializeObject<UserRequestInformation>(userInformation); 
     } 
     catch (Exception ex) 
     { 
      //never gets here - no exception thrown if userInformation.User.LoginName is null 
      return null; 
     } 
    } 

Compte tenu de cela, lors d'une tentative de désérialiser le tableau des erreurs dans le UserInformationRequest, un exception est correctement levée s'il existe un JsonProperty sur l'objet de base, mais il n'est jamais levé si l'objet imbriqué contient un objet JsonProperty.

travail dotnetfiddles démontrant la question: JsonProperty sur l'objet de base: https://dotnetfiddle.net/qvyPfP JsonProperty sur l'objet imbriqué: https://dotnetfiddle.net/M3F0rb

+0

Pourriez-vous montrer la chaîne JSON « Userinformation » reçu comme paramètre dans la méthode « GetUserInformationRequestFromString » s'il vous plaît? –

+0

@emkayultra, dans quelle (s) version (s) de .Net et Json.Net voyez-vous ce problème? –

+0

@JonLopezGarcia - premier exemple: "{\" TimeStamp \ ": null, \" Utilisateur \ ": {\" ID \ ": 12345, \" LoginName \ ": \" nom d'utilisateur \ "}}"} ET second exemple : "{\" TimeStamp \ ": \" 2017-07-29 10:31:53 \ ", \" Utilisateur \ ": {\" ID \ ": 12345, \" LoginName \ ": null}}" – emkayultra

Répondre

2

Si vous marquez également votre utilisateur propriété dans le UserInformationRequest classe avec le [JsonProperty (Obligatoire = Obligatoire.Toujours)] Attribut,

Le désérialiseur semble regarder à l'intérieur de l'UserInformation pour le Le nom de connexion doit être non nul comme demandé.

Here-vous votre deuxième exemple avec l'attribut sur l'utilisateur propriété

+0

Cela semble résoudre le problème. Cependant, que faire si je ne veux pas que l'utilisateur soit requis, mais si l'utilisateur est fourni, alors il doit avoir LoginName – emkayultra

+0

Eh bien, si nous considérons attentivement, c'est exactement ce qui se passe. Si vous fournissez une propriété ** User ** et que l'attribut requis est sur la propriété ** LoginName **, une exception sera générée. Voir [ici] (https://dotnetfiddle.net/Mso1H6). Si vous ne fournissez rien sur une propriété ** User ** dans la chaîne json, le désérialiseur ignorera complètement le champ de la classe. Si vous ne voulez pas que le comportement soit ainsi, et forcez le désérialiseur à s'occuper d'une propriété ** User ** dans le json, cela signifie que vous voulez que le champ soit rempli (en d'autres termes, être Champs obligatoires).Utiliser l'attribut requis –

+0

Cela a du sens, merci pour votre aide et votre clarification. Marquer votre réponse comme "la" réponse. – emkayultra