如何用Json.NET反序列化Minecraft JSON中字符串与对象混合的集合?
解决Json.NET反序列化混合字符串/对象数组的问题
针对你遇到的Minecraft JSON中values数组混合字符串和对象的场景,用Json.NET的自定义Json转换器就能搞定,具体步骤如下:
1. 定义TagValue类
先把目标实体类写好,给Required设置默认值:
public class TagValue { public string Name { get; set; } public bool Required { get; set; } = false; // 默认值设为false }
2. 实现自定义Json转换器
创建一个继承JsonConverter<TagValue>的转换器,在ReadJson方法里处理两种不同的JSON元素类型:
public class TagValueConverter : JsonConverter<TagValue> { public override TagValue ReadJson(JsonReader reader, Type objectType, TagValue existingValue, bool hasExistingValue, JsonSerializer serializer) { // 根据当前JSON token的类型分支处理 switch (reader.TokenType) { case JsonToken.String: // 字符串类型:直接用字符串值初始化TagValue,Required保留默认值 return new TagValue { Name = reader.Value.ToString() }; case JsonToken.StartObject: // 对象类型:用JObject加载后反序列化为TagValue var jObject = JObject.Load(reader); return jObject.ToObject<TagValue>(serializer); default: throw new JsonSerializationException($"不支持的token类型:{reader.TokenType}"); } } // 可选:如果需要将TagValue序列化回JSON,重写此方法 public override void WriteJson(JsonWriter writer, TagValue value, JsonSerializer serializer) { if (value.Required == false) { // Required为默认值时,直接输出字符串 writer.WriteValue(value.Name); } else { // 否则输出完整对象 serializer.Serialize(writer, value); } } }
3. 应用转换器完成反序列化
有两种方式使用这个转换器:
方式一:给属性添加特性标记
假设你的根实体类是这样的:
public class MinecraftTag { // 给values属性绑定转换器 [JsonConverter(typeof(TagValueConverter))] public List<TagValue> Values { get; set; } }
直接执行反序列化:
var json = @"{""Values"": [""minecraft:dirt"", {""Name"":""minecraft:stone"", ""Required"":true}]}"; var tag = JsonConvert.DeserializeObject<MinecraftTag>(json);
方式二:在序列化设置中注入转换器
如果不想修改实体类,可以在反序列化时传入配置:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new TagValueConverter()); var tag = JsonConvert.DeserializeObject<MinecraftTag>(json, settings);
核心逻辑说明
- 转换器通过
JsonReader.TokenType判断当前元素是字符串还是对象,分别做映射处理 - 字符串元素直接赋值给
TagValue.Name,Required保持默认的false - 对象元素正常反序列化为
TagValue,JSON中的Required字段会覆盖默认值
内容的提问来源于stack exchange,提问作者devvoid
相关产品推荐
相关产品推荐

