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



我正在尝试反序列化以下JSON(它在https://jsonlint.com/):

{"pandoc-api-version":[1,22],"meta":{"title":{"t":"MetaBlocks","c":[{"t":"Para","c":[{"t":"Str","c":"Dynamic"},{"t":"Space"},{"t":"Str","c":"Language"},{"t":"Space"},{"t":"Str","c":"Runtime"}]},{"t":"Para","c":[]}]}},"blocks":[{"t":"Para","c":[{"t":"Strong","c":[{"t":"Str","c":"Bill"},{"t":"Space"},{"t":"Str","c":"Chiles"},{"t":"Space"},{"t":"Str","c":"and"},{"t":"Space"},{"t":"Str","c":"Alex"},{"t":"Space"},{"t":"Str","c":"Turner"}]}]},{"t":"Para","c":[{"t":"Emph","c":[{"t":"Strong","c":[{"t":"Str","c":"Reading"},{"t":"Space"},{"t":"Str","c":"this"},{"t":"Space"},{"t":"Str","c":"Document:"}]}]}]}]}

分为以下类别:

internal record TagContent(string T, OneOf<TagContent[], string>? C);
internal class RawPandoc {
[JsonProperty] public int[] PandocApiVersion = default!;
[JsonProperty] public Dictionary<string, TagContent> Meta = default!;
[JsonProperty] public TagContent[] Blocks = default!;
}

使用以下代码:

var settings = new JsonSerializerSettings {
ContractResolver = new DefaultContractResolver { NamingStrategy = new KebabCaseNamingStrategy() },
Converters = new JsonConverter[] { new OneOfJsonConverter() }
};
var pandoc = JsonConvert.DeserializeObject<RawPandoc>(s, settings);

我得到以下错误:

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

我该如何解决此问题?


为了完整性,这里是OneOfJsonConverter的当前和不完整代码。OneOf是C#中的并集类型库:

using OneOf;
namespace PandocFilters {
public class OneOfJsonConverter : JsonConverter {
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) {
if (value is IOneOf of) {
value = of.Value;
}
serializer.Serialize(writer, value);
}

public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) {
if (reader.Value is null) { return null; }
// TODO not implemented yet
return reader.Value;
}

public override bool CanConvert(Type objectType) => objectType.UnderlyingIfNullable().GetInterfaces().Contains(typeof(IOneOf));
}
}

问题是您没有在ReadJson实现中推进读取器。您声明您的转换器可以处理IOneOf对象,因此JSON.NET希望您的转换器实际读取并处理它,但到目前为止它什么也不做。因此,ReadJson被调用(在json中第一个数组的开头,该数组应该被反序列化为OneOf(,然后在它返回之后-读取器位置仍然是以前的位置(在数组的开头(,这不是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;
}

相关内容

  • 没有找到相关文章

最新更新