- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个 Newtonsoft JSON.NET JsonConverter
来帮助反序列化类型为抽象类的属性。它的要点是这样的:
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(); }
}
这是它处理的类:
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; }
}
这在反序列化具有非空 Pet
的 Person
时工作正常。但是,如果 Pet
为 null,则 ReadJson
方法会在第一行中断并出现此 JsonReaderException
:
An exception of type 'Newtonsoft.Json.JsonReaderException' occurred in Newtonsoft.Json.dll but was not handled in user code
Additional information: Error reading JObject from JsonReader. Current JsonReader item is not an object: Null. Path 'Pet', line 1, position 11.
我检查过 the Custom JsonConverter文档,但它仅仅是关于一个编写转换器。我尝试了以下方法:
if (reader.Value == null) return null; // this inverts the [Test] results
但后来我得到:
JsonSerializationException: Additional text found in JSON string after finishing deserializing object.
对于属性被填充的情况。
简而言之,处理这种情况的正确方法是什么?
为了完整起见,这里有一些单元测试可以证明手头的问题:
[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);
}
}
最佳答案
在写问题的时候,特别是在写“我试过什么”的时候,我找到了一个可能的解决方案:
if (reader.TokenType == JsonToken.Null) return null;
我发布这个有两个原因:
FWIW,这里是完整的 JsonConverter,用于对类型为抽象类的属性进行非常基本的反序列化处理:
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)
{
if (reader.TokenType == JsonToken.Null) return null;
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();
}
}
关于c# - 在自定义 JsonConverter 的 ReadJson 方法中处理空对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34185295/
我想要实现的目标。我有一个类,其中有一些属性/对象。我只想用我的自定义序列化程序序列化那些满足 CanConvert 条件的对象,其他对象应该默认处理。 问题是使用 [JsonConverter(ty
我无法使用 readJSON 从 JSON 读取所有键“type-X.X” oldJson 字符串: { "branch":{ "type-0.2":{"version":"0.2","rc"
我正在尝试为对象[] 创建一个 json 转换器来定义我想要的类型(例如 int32 而不是 int64)。 这是我到现在为止得到的: 对象: [JsonObject] public class ti
我想将参数传递给我的 Gruntfile.js,以便 grunt.file.readJSON 可以读取传入的文件名。我应该怎么办? grunt.initConfig({ filename:
我正在尝试为结构实现自定义 JsonConverter,但我很难让它工作。我之前为另一个类实现了一个自定义转换器并且那个工作完美,我以为我为这个做了同样的事情但是我的转换器的 ReadJson 方法从
我遇到了最奇怪的问题,希望其他人已经看到了这个问题,甚至可能已经解决了。 以前,我在 grunt.js 文件中有一组参数,用于我的 Protractor 测试。下面的简单示例: params: {
这是我的自定义 json 转换器的一部分: public class ExpandoConverter : JsonConverter { public override bool CanC
def data = readJSON text: '{"rel" : {"configVersion": "1.0","manifest" :"'+"${manifestURL}"+'"}}' wr
我正在努力设置一系列与 RequireJS r.js 编译器一起使用的 grunt 任务:1) 生成一个 .json 文件,列出目录中的所有文件2)从文件名中删除“.js”(requirejs需要这个
我有一个 Newtonsoft JSON.NET JsonConverter 来帮助反序列化类型为抽象类的属性。它的要点是这样的: public class PetConverter : JsonCo
如何在 JsonConverter.ReadJson() 中高效获取完整的 json 字符串? 我能做到: public override object ReadJson(JsonReader rea
创建自定义 Json 转换器时,需要重写的方法之一是: public override object ReadJson(JsonReader reader, Type objectType, obje
我正在将 Grunt 文件转换为 Gulp 文件。我的 Grunt 文件包含以下行 var config = grunt.file.readJSON('json/config.json'); 这一行所
先决条件: JSON.Net 11.0.2 我需要通过基于 JSON 的 REST-API 存储 UTC DateTime 往返日期/时间模式。 string utcTimestamp = DateT
我有一个 JSON 输入,其对象全部派生自基类,如下所示: public abstract class Base { public Base Parent { get; set; } } 我正
我已经创建了 JsonConverter 的实现 CanConvert 始终返回 true。 在 ReadJson 中,我有时只想使用“默认”行为,就好像 CanConvert 返回了 false 而
我正在尝试为 NetTopologySuite 几何编写自定义 JsonConverter。 我的模型: public class MyModel { public string myName
我是一名优秀的程序员,十分优秀!