C# 使用自定义转换器反序列化联合类型之一时出现意外标记:StartObject

C# 使用自定义转换器反序列化联合类型之一时出现意外标记:StartObject,c#,json.net,C#,Json.net,我正在尝试反序列化以下JSON(在上验证): ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,

我正在尝试反序列化以下JSON(在上验证):

,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,“Space”},{“t”“:”Str“,”c“:”and“},{”t“:”Space“},{”t“:”Alex“,”{”t“:”Space“},{”t“:”Str“,”c“:”,”t“,”Para“,”c“:”{”t“:”Emph“,”c“:[{”t“:”Str t“,”c“:”Reading“,{”t“,”t“:”Space Str},{”t“,”t“,”Str t“,”t“,”这“,”t“,”t“,{”t“,”t“,”t“,”t“,”这一“,”t“,”t“,”这一“,”t“,”,”t“,”这一“,” 分为以下几类:

内部记录标记内容(字符串T,C中的一个);
内部类RawPandoc{
[JsonProperty]public int[]PandocApiVersion=default!;
[JsonProperty]公共字典元=默认值!;
[JsonProperty]公共标记内容[]块=默认值!;
}
使用以下代码:

var设置=新的JsonSerializerSettings{
ContractResolver=new DefaultContractResolver{NamingStrategy=new KebabCaseNamingStrategy()},
Converters=new-JsonConverter[]{new-OneOfJsonConverter()}
};
var pandoc=JsonConvert.DeserializeObject,设置;
我得到以下错误:

反序列化对象时出现意外标记:StartObject。路径“meta.title.c[0]”,第1行,第69位。

我如何解决这个问题


为完整起见,以下是
OneOfJsonConverter
的当前代码和不完整代码。是C#中的联合类型库:

使用其中一个;
名称空间过滤器{
JsonConverter的公共类:JsonConverter{
public override void WriteJson(JsonWriter writer,object?value,JsonSerializer序列化程序){
if(值为IOneOf){
价值=价值的价值;
}
serializer.Serialize(writer,value);
}
公共重写对象?ReadJson(JsonReader阅读器,类型objectType,对象?existingValue,JsonSerializer序列化程序){
如果(reader.Value为null){return null;}
//TODO尚未实施
返回reader.Value;
}
public override bool CanConvert(Type objectType)=>objectType.underyingifnullable().GetInterfaces().Contains(typeof(IOneOf));
}
}

问题在于,在
ReadJson
实现中,您没有推进阅读器。您声明您的转换器可以处理一组对象,因此JSON.NET希望您的转换器能够实际读取和处理它,但到目前为止它什么也不做。因此调用了
ReadJson
(在json中第一个数组的开始处,应该反序列化为OneOf),然后在返回后-reader位置仍然是它之前的位置(在数组的开始处),这不是json.NET所期望的。然后,它无法继续读取下一个对象,因为违反了它的假设。因此,只需实现
ReadJson
,同时您可以推进一个阅读器,例如:

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) {
    // advance reader as expected
    var eitherStringOrArray = JObject.ReadFrom(reader);
    return reader.Value;
}

其中一种
联合类型对开发人员来说很有趣,但对反序列化程序来说就不那么有趣了。我认为JSON.NET不理解您要做的事情,您的转换器也不理解,因为它可能在返回或实例化
reader.Value
后会抛出一些地方。这可能是一个新问题,但是如何从阅读器生成
TagContent
实例呢?当
JObject.ReadFrom(reader)
返回
JArray
的实例时;我认为创建转换器的通用版本,使用任何一个值都是相当复杂的。使用这个特定的类很容易,只需检查它是否是JArray,如果是,则将其反序列化为
TagContent[]
,并返回一个值。否则它应该是一个字符串,所以也要这样做,并用字符串返回其中一个。但一般情况远比这复杂。