it-swarm.com.de

Ignorieren Sie die Analysefehler bei der JSON.NET-Datenanalyse

Ich habe ein Objekt mit vordefinierter Datenstruktur:

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

und JSON soll sein 

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

Ich möchte JSON-Fehler positiv behandeln, und wenn der Server unerwartete Werte für definierte Datentypen zurückgibt, möchte ich, dass er ignoriert wird und der Standardwert festgelegt ist (null).

Wenn JSON teilweise ungültig ist, erhalte ich eine JSON-Leser-Ausnahme:

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

Und ich bekomme überhaupt kein Objekt ... Was ich will, ist ein Objekt zu bekommen: 

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

und Parsen der Warnung wenn möglich ... Ist es möglich, mit JSON.NET zu arbeiten?

46
Alexey Strakh

Um Deserialisierungsfehler behandeln zu können, verwenden Sie den folgenden Code:

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

wobei HandleDeserializationError die folgende Methode ist:

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

Die Variable HandleDeserializationError wird so oft aufgerufen, wie Fehler in der Json-Zeichenfolge vorhanden sind. Die Eigenschaften, die den Fehler verursachen, werden nicht initialisiert.

79
Ilija Dimov

Das Gleiche wie Ilijas Lösung, aber ein Oneliner für die Faulenzer/auf eine Eile (Kredit geht an ihn)

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

Requisiten auf Jam, um es noch kürzer zu machen =)

5
Gaspa79

Es geht auch anders. Zum Beispiel, wenn Sie ein Nuget-Paket verwenden, das Newton Json verwendet und Deseralisierung und Seralisierung für Sie durchführt. Möglicherweise liegt dieses Problem vor, wenn das Paket keine Fehler behandelt. dann können Sie die Lösung oben nicht verwenden. Sie müssen auf Objektebene arbeiten. Hier wird OnErrorAttribute nützlich. Der folgende Code fängt jeden Fehler für eine Eigenschaft ab. Sie können sogar die Funktion OnError ändern und Standardwerte zuweisen

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;
  }
}

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

0
batmaci