私はNewtonsoft JSON.NET JsonConverter
を持っています。タイプが抽象クラスであるプロパティを逆シリアル化するのに役立ちます。その要旨は次のようになります。null以外Pet
を持ってPerson
をデシリアライズするときこれが正常に動作しますカスタムJsonConverterのReadJsonメソッドでnullオブジェクトを扱う
public abstract class Animal
{ }
public class Cat : Animal
{
public int Lives { get; set; }
}
public class Parrot : Animal
{
public string StopPhrase { get; set; }
}
public class Person
{
[JsonConverter(typeof(PetConverter))]
public Animal Pet { get; set; }
}
:ここ
public class PetConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Animal);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jsonObject = JObject.Load(reader);
if (jsonObject["Lives"] != null) return jsonObject.ToObject<Cat>(serializer);
if (jsonObject["StopPhrase"] != null) return jsonObject.ToObject<Parrot>(serializer);
return null;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{ throw new NotImplementedException(); }
}
それが扱うクラスです。しかしPet
がnullの場合、このとの最初の行にReadJson
法の改JsonReaderException
:種類の例外「Newtonsoft.Json.JsonReaderException」はNewtonsoft.Json.dllで発生したが、中に処理されなかった
ユーザーコード追加情報:JsonReaderからJObjectを読み取る際のエラー。現在のJsonReaderアイテムはオブジェクトではありません:Null。パス「ペット」、行1、位置11
私はthe Custom JsonConverterドキュメントをチェックしましたが、それは書き込みコンバータについて過ぎません。
if (reader.Value == null) return null; // this inverts the [Test] results
をしかし、私は得る:私は次のことを試してみた
JsonSerializationException:デシリアライズオブジェクトを終えた後、JSON文字列で見つかった追加のテキストを。
のプロパティがの場合です。
要するに、この状況を処理する適切な方法は何ですか?特に「私が試し持っているものを」少し、私は1つの可能性を見つけるの書き込み中に、質問を書きながら
[TestFixture]
public class JsonConverterTests
{
[Test]
public void Cat_survives_serialization_roundtrip()
{
var person = new Person { Pet = new Cat { Lives = 9 } };
var serialized = JsonConvert.SerializeObject(person);
var deserialized = JsonConvert.DeserializeObject<Person>(serialized);
Assert.That(deserialized.Pet, Is.InstanceOf<Cat>());
Assert.That((deserialized.Pet as Cat).Lives, Is.EqualTo(9));
}
[Test]
public void Parrot_survives_serialization_roundtrip()
{
var person = new Person { Pet = new Parrot { StopPhrase = "Lorrie!" } };
var serialized = JsonConvert.SerializeObject(person);
var deserialized = JsonConvert.DeserializeObject<Person>(serialized);
Assert.That(deserialized.Pet, Is.InstanceOf<Parrot>());
Assert.That((deserialized.Pet as Parrot).StopPhrase, Is.EqualTo("Lorrie!"));
}
[Test]
public void Null_property_does_not_break_converter()
{
var person = new Person { Pet = null };
var serialized = JsonConvert.SerializeObject(person);
var deserialized = JsonConvert.DeserializeObject<Person>(serialized);
Assert.That(deserialized.Pet, Is.Null);
}
}
および/またはあなたが 'JToken'としてあなたのJSONをロードし、'のためにチェックすることができtoken.Type == JTokenType.Null'です。実際には、あなたのソリューションは最高のようです。 – dbc
私の場合、nullを返すとき、 'reader'は正しい状態を持っていませんでした。したがって、私は答えのソリューションと[dbc]の提案の組み合わせを思いついた。if(reader.TokenType == JsonToken.Null){JToken.Load(reader); nullを返す。 } '。 – JanDotNet