如何根据条件将不同JSON属性反序列化为同一C#模型属性
如何根据条件切换JSON中的allitems/customitems映射到C#模型的items属性?
嘿,这个问题我熟!你需要根据条件把JSON里的allitems或者customitems赋值给C#模型的items属性对吧?下面给你几种实用的解决办法,选适合你场景的就行:
方法一:手动反序列化后赋值(简单直接)
这种方法适合一次性的简单场景,先定义一个临时类接收JSON里的所有字段,再根据条件把对应列表赋值给目标模型:
// 临时类:用来接收JSON的完整结构 public class TempResponse { public int allitemscount { get; set; } public List<Item> allitems { get; set; } public List<Item> customitems { get; set; } } // 你的目标模型类 public class Response { public int allitemscount { get; set; } public List<Item> items { get; set; } } public class Item { public string itemid { get; set; } public string itemname { get; set; } } // 业务代码中处理 string json = "{ \"allitemscount\":2, \"allitems\":[{ \"itemid\":\"1\",\"itemname\":\"one\"}, {\"itemid\":\"2\",\"itemname\":\"two\"}], \"customitems\":[{ \"itemid\":\"3\",\"itemname\":\"three\"}, {\"itemid\":\"4\",\"itemname\":\"four\"}] }"; // 先反序列化到临时类 TempResponse tempResult = JsonConvert.DeserializeObject<TempResponse>(json); Response finalResponse = new Response(); // 复制公共字段 finalResponse.allitemscount = tempResult.allitemscount; // 根据你的业务条件选择要赋值的列表 bool shouldUseCustomItems = true; // 这里替换成你的实际条件 finalResponse.items = shouldUseCustomItems ? tempResult.customitems : tempResult.allitems;
方法二:自定义JSON转换器(优雅复用)
如果这个逻辑需要重复使用,自定义转换器会更优雅——直接把JSON反序列化成目标模型,不用手动中转。下面分别给出两种常用序列化库的实现:
基于Newtonsoft.Json的转换器
public class ResponseConverter : JsonConverter<Response> { private readonly bool _useCustomItems; // 构造时传入条件,决定用哪个列表 public ResponseConverter(bool useCustomItems) { _useCustomItems = useCustomItems; } public override Response ReadJson(JsonReader reader, Type objectType, Response existingValue, bool hasExistingValue, JsonSerializer serializer) { JObject jsonObj = JObject.Load(reader); Response response = new Response(); // 解析公共字段 response.allitemscount = jsonObj["allitemscount"].ToObject<int>(); // 根据条件选择对应的数组字段 string targetField = _useCustomItems ? "customitems" : "allitems"; response.items = jsonObj[targetField].ToObject<List<Item>>(); return response; } // 如果需要序列化Response对象,可实现此方法(可选) public override void WriteJson(JsonWriter writer, Response value, JsonSerializer serializer) { JObject jsonObj = new JObject(); jsonObj.Add("allitemscount", value.allitemscount); jsonObj.Add(_useCustomItems ? "customitems" : "allitems", JArray.FromObject(value.items)); jsonObj.WriteTo(writer); } } // 使用方式 bool useCustom = false; // 替换为你的实际条件 Response response = JsonConvert.DeserializeObject<Response>(json, new ResponseConverter(useCustom));
基于System.Text.Json的转换器(.NET Core 3.0+)
如果你用的是官方的System.Text.Json库,也可以写类似的转换器:
public class ResponseSystemTextConverter : JsonConverter<Response> { private readonly bool _useCustomItems; public ResponseSystemTextConverter(bool useCustomItems) { _useCustomItems = useCustomItems; } public override Response Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { using JsonDocument doc = JsonDocument.ParseValue(ref reader); var root = doc.RootElement; Response response = new Response(); response.allitemscount = root.GetProperty("allitemscount").GetInt32(); string targetField = _useCustomItems ? "customitems" : "allitems"; response.items = JsonSerializer.Deserialize<List<Item>>(root.GetProperty(targetField).GetRawText(), options); return response; } // 序列化方法(可选) public override void Write(Utf8JsonWriter writer, Response value, JsonSerializerOptions options) { writer.WriteStartObject(); writer.WriteNumber("allitemscount", value.allitemscount); writer.WritePropertyName(_useCustomItems ? "customitems" : "allitems"); JsonSerializer.Serialize(writer, value.items, options); writer.WriteEndObject(); } } // 使用方式 var serializerOptions = new JsonSerializerOptions(); serializerOptions.Converters.Add(new ResponseSystemTextConverter(true)); // 传入条件 Response response = JsonSerializer.Deserialize<Response>(json, serializerOptions);
简单总结一下:手动赋值适合快速实现小场景,自定义转换器适合需要多次复用的逻辑,根据你的业务需求选就好啦!
内容的提问来源于stack exchange,提问作者Ganesh
相关产品推荐
相关产品推荐

