web-dev-qa-db-fra.com

Ignorer les erreurs d'analyse lors de l'analyse de données JSON.NET

J'ai un objet avec une structure de données prédéfinie:

public class A
{
    public string Id {get;set;}
    public bool? Enabled {get;set;}
    public int? Age {get;set;}
}

et JSON est censé être 

{ "Id": "123", "Enabled": true, "Age": 23 }

Je souhaite gérer les erreurs JSON de manière positive et chaque fois que le serveur renvoie des valeurs inattendues pour des types de données définis, je souhaite qu'il soit ignoré et la valeur par défaut définie (null).

À l'heure actuelle, lorsque JSON est partiellement invalide, j'obtiens une exception concernant le lecteur JSON:

{ "Id": "123", "Enabled": "NotABoolValue", "Age": 23 }

Et je ne reçois aucun objet du tout… .. Ce que je veux, c'est un objet: 

new A() { Id = "123", Enabled = null, Age = 23 }

et analyser les avertissements si possible . Est-il possible d'accomplir avec JSON.NET?

46
Alexey Strakh

Pour pouvoir gérer les erreurs de désérialisation, utilisez le code suivant:

var a = JsonConvert.DeserializeObject<A>("-- JSON STRING --", new JsonSerializerSettings
    {
        Error = HandleDeserializationError
    });

HandleDeserializationError est la méthode suivante:

public void HandleDeserializationError(object sender, ErrorEventArgs errorArgs)
{
    var currentError = errorArgs.ErrorContext.Error.Message;
    errorArgs.ErrorContext.Handled = true;
}

La HandleDeserializationError sera appelée autant de fois qu'il y a d'erreurs dans la chaîne json. Les propriétés à l'origine de l'erreur ne seront pas initialisées.

79
Ilija Dimov

Même chose que la solution d'Ilija, mais une solution pour les fainéants/sur une ruée (le crédit lui revient)

var settings = new JsonSerializerSettings { Error = (se, ev) => { ev.ErrorContext.Handled = true; } };
JsonConvert.DeserializeObject<YourType>(yourJsonStringVariable, settings);

Les accessoires de Jam pour le rendre encore plus court =)

5
Gaspa79

Il y a un autre moyen. Par exemple, si vous utilisez un package de nuget qui utilise newton json et effectue la déseralization et la séralisation à votre place. Vous pouvez avoir ce problème si le paquet ne gère pas les erreurs. alors vous ne pouvez pas utiliser la solution ci-dessus. vous devez gérer au niveau de l'objet. ici devient OnErrorAttribute utile. Donc, le code ci-dessous intercepte toute erreur pour une propriété, vous pouvez même le modifier dans la fonction OnError et attribuer des valeurs par défaut.

public class PersonError
{
  private List<string> _roles;

  public string Name { get; set; }
  public int Age { get; set; }

  public List<string> Roles
  {
    get
    {
        if (_roles == null)
        {
            throw new Exception("Roles not loaded!");
        }

        return _roles;
    }
    set { _roles = value; }
  }

  public string Title { get; set; }

  [OnError]
  internal void OnError(StreamingContext context, ErrorContext errorContext)
  {
    errorContext.Handled = true;
  }
}

voir https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm

0
batmaci