使用JsonReader而不是JsonSerializer时,自定义JsonConverter不起作用 [英] Custom JsonConverter not working when using JsonReader instead of JsonSerializer

查看:289
本文介绍了使用JsonReader而不是JsonSerializer时,自定义JsonConverter不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类 Foo 及其定义如下的 FooConverter :

I have a class Foo and its FooConverter as defined below:

[JsonConverter(typeof(FooConverter))]
public class Foo
{
    public string Something { get; set; }
}

public class FooConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteValue(((Foo)value).Something);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var str = reader.ReadAsString();
        if (str == null)
        {
            throw new JsonSerializationException();
        }    
        // return new Foo {Something = serializer.Deserialize<string>(reader)};
        return new Foo {Something = str};
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(Foo);
    }
}

序列化效果很好.但是反序列化时:

Serializing works fine. But when deserializing:

var foo = JsonConvert.DeserializeObject<Foo>("\"something\"");

它抛出 JsonSerializationException ,因为 reader.ReadAsString 为null.
但是我不明白为什么它必须为 null ... reader.ReadAsString 可以完美地找到我是否手动执行的操作:

it throws JsonSerializationException because reader.ReadAsString is null.
But I don't understand why it has to be null... reader.ReadAsString works perfectly find if I'm doing it manually like so:

var reader = new JsonTextReader(new StringReader("\"something\""));
var str = reader.ReadAsString(); // str is now `something` NOT null

尽管我可以使用 ReadJson 中的 serializer.Deserialize< string>(reader)来修复 FooConverter ,但我仍然想了解为什么 reader.ReadAsString FooConverter.ReadJson 中失败.

Although I can fix FooConverter by using serializer.Deserialize<string>(reader) in ReadJson, I still want to understand why reader.ReadAsString fails in FooConverter.ReadJson.

推荐答案

根据文档 JsonReader.ReadAsString():

从源中读取作为字符串的 next JSON令牌.

但是,当 JsonConverter.ReadJson() 被调用时,阅读器已经位于与要反序列化的对象相对应的第一个JSON令牌上.因此,通过调用 ReadAsString(),您将舍弃该值并尝试读取流中的下一个令牌-但没有令牌,因此引发了异常.

However, when JsonConverter.ReadJson() is called, the reader is already positioned on the first JSON token corresponding to the object being deserialized. Thus, by calling ReadAsString() you discard that value and try to read the next token in the stream -- but there is none, so you throw an exception.

此外,在 ReadJson()的末尾,您的代码必须将阅读器定位在与要转换的对象相对应的最后一个JSON令牌上.因此,在JSON只是简单的原语的情况下,阅读器根本不应该得到进一步的改进.

Further, At the end of ReadJson() your code must have positioned the reader at the last JSON token corresponding to the object being converted. So, in the case where the JSON is simply a primitive, the reader should not get advanced at all.

通过 ReadJson()确保阅读器始终正确定位的一种简单方法是调用

A simple way to guarantee that the reader is always correctly positioned by ReadJson() is to call JToken.Load(). This always leaves the reader positioned at the end of the token that was loaded. Afterwards, you can check to see that what was loaded was as expected. E.g., if the JSON has an object where a string was expected, rather than leaving the reader incorrectly positioned, the converter should throw an exception rather than leave the reader incorrectly positioned.

StringIdConverter :序列化/反序列化属性是一个值,而不是一个对象 给出了一个示例.您可以对其进行如下修改:

StringIdConverter from Json.Net: Serialize/Deserialize property as a value, not as an object gives an example of this. You could modify it as follows:

public class FooConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader);
        if (!(token is JValue))
            throw new JsonSerializationException("Token was not a primitive");
        return new Foo { Something = (string)token };
    }

这篇关于使用JsonReader而不是JsonSerializer时,自定义JsonConverter不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆