web-dev-qa-db-ja.com

JSON.NETデータ解析中の解析エラーを無視する

定義済みのデータ構造を持つオブジェクトがあります。

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

jSONは

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

JSONエラーを積極的に処理し、サーバーが定義済みのデータ型に対して予期しない値を返すたびに、無視してデフォルト値を設定(null)する必要があります。

現在、JSONが部分的に無効な場合、JSONリーダーの例外が発生します。

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

そして、私はまったくオブジェクトを取得しません。私が欲しいのはオブジェクトを取得することです:

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

可能な場合は警告を解析します。 JSON.NETで達成することは可能ですか?

53
Alexey Strakh

逆シリアル化エラーを処理できるようにするには、次のコードを使用します。

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

ここで、HandleDeserializationErrorは次のメソッドです。

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

HandleDeserializationErrorは、json文字列にエラーがある回数だけ呼び出されます。エラーの原因となっているプロパティは初期化されません。

92
Ilija Dimov

Ilijaのソリューションと同じですが、怠け者/ラッシュのワンライナー(クレジットは彼にあります)

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

さらに短くするためのJamの小道具=)

7
Gaspa79

別の方法があります。たとえば、newton jsonを使用し、脱塩と脱塩を行うnugetパッケージを使用している場合。パッケージがエラーを処理していない場合、この問題が発生する可能性があります。その後、上記のソリューションを使用することはできません。オブジェクトレベルで処理する必要があります。ここでOnErrorAttributeが便利になります。したがって、以下のコードはプロパティのエラーをキャッチし、OnError関数内で変更してデフォルト値を割り当てることもできます

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

https://www.newtonsoft.com/json/help/html/SerializationErrorHandling.htm を参照してください

1
batmaci