私はJson.NETを使用していくつかのJSONオブジェクトをデシリアライズしようとしています。しかし、プロパティを持たないオブジェクトを逆シリアル化すると、エラーがスローされず、プロパティにアクセスするとデフォルト値が返されることがわかりました。間違ったタイプのオブジェクトをデシリアライズしたときを検出できることが重要です。サンプルコード:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Json_Fail_Test
{
class Program
{
[JsonObject(MemberSerialization.OptOut)]
private class MyJsonObjView
{
[JsonProperty("MyJsonInt")]
public int MyJsonInt { get; set; }
}
const string correctData = @"
{
'MyJsonInt': 42
}";
const string wrongData = @"
{
'SomeOtherProperty': 'fbe8c20b'
}";
static void Main(string[] args)
{
var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData);
System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());
var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData);
System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
}
}
}
このプログラムの出力は次のとおりです。42 0
静かに失敗するよりも例外をスローする方がいいでしょう。それの手前に、シリアル化がパラメーターを見つけられなかったかどうかを検出する方法がありますか?
私はJsonオブジェクトでデータを解析し、キー値ルックアップでパラメータをチェックできることを知っていますが、私がいるコードベースは上記のパターンを使用し、可能な場合は一貫性を保ちたいと思います。
Json.NetシリアライザーにはMissingMemberHandling
設定があり、Error
に設定できます。 (デフォルトはIgnore
です。)これにより、ターゲットクラスに対応するプロパティがないJSONプロパティが検出されると、デシリアライズ中にシリアライザーがJsonSerializationException
をスローします。
static void Main(string[] args)
{
try
{
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MissingMemberHandling = MissingMemberHandling.Error;
var goodObj = JsonConvert.DeserializeObject<MyJsonObjView>(correctData, settings);
System.Console.Out.WriteLine(goodObj.MyJsonInt.ToString());
var badObj = JsonConvert.DeserializeObject<MyJsonObjView>(wrongData, settings);
System.Console.Out.WriteLine(badObj.MyJsonInt.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name + ": " + ex.Message);
}
}
結果:
42
JsonSerializationException: Could not find member 'SomeOtherProperty' on object
of type 'MyJsonObjView'. Path 'SomeOtherProperty', line 3, position 33.
参照: MissingMemberHandling設定 。
必要なプロパティに[JsonProperty(Required = Required.Always)]
を追加するだけで、逆シリアル化中にプロパティが存在しない場合は例外がスローされます。
[JsonProperty(Required = Required.Always)]
public int MyJsonInt { get; set; }
必要なプロパティに次の属性を設定します。
[DataMember(IsRequired = true)]
メンバーが存在しない場合、Newtonsoft.Json.JsonSerializationExceptionがスローされます。
以下にブライアンが提案したように、クラスにもこの属性が必要です。
[DataContract]
定義クラスのメンバーを疑問符「?」で定義するだけです。 int?
:
private class MyJsonObjView
{
[JsonProperty("MyJsonInt")]
public int? MyJsonInt { get; set; }
}
初期化されていない場合は、単にnull
になります。それ以外の場合は、有効な値になります。これにより、設定をオプションにし、設定ごとに評価することができます。