如何在C#中反序列化包含属性类型标识的JSON字符串
解决方案
不需要更换第三方库,基于Newtonsoft.Json实现自定义JsonConverter即可适配该特殊结构,整体逻辑简洁,后续扩展也方便。
步骤1:实现自定义转换器
转换器核心逻辑:自动识别每个属性外层的类型包装结构,直接提取实际值赋值给实体属性。
using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Reflection; public class TypedWrapperConverter : JsonConverter { public override bool CanConvert(Type objectType) { // 此处替换为你自己实体类所在的命名空间即可 return objectType.IsClass && objectType.Namespace == "YourEntityNamespace"; } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jsonObj = JObject.Load(reader); var instance = Activator.CreateInstance(objectType); foreach (PropertyInfo prop in objectType.GetProperties()) { // 读取JsonProperty配置的字段名匹配JSON键 JsonPropertyAttribute jsonAttr = prop.GetCustomAttribute<JsonPropertyAttribute>(); string jsonKey = jsonAttr?.PropertyName ?? prop.Name; if (jsonObj.TryGetValue(jsonKey, out JToken valueToken) && valueToken is JObject typeWrapObj) { // 提取类型包装对象里的第一个值,就是实际的属性值 JToken actualValue = typeWrapObj.First.First(); prop.SetValue(instance, actualValue.ToObject(prop.PropertyType, serializer)); } } return instance; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { // 不需要序列化回原结构可直接抛出异常 throw new NotImplementedException(); } }
步骤2:定义实体类
给实体类标注自定义转换器,属性按常规写法配置JsonProperty即可。
[JsonConverter(typeof(TypedWrapperConverter))] public class MyModel { [JsonProperty("session_id")] public string SessionId { get; set; } [JsonProperty("title_id_type")] public string TitleIdType { get; set; } [JsonProperty("event_name")] public string EventName { get; set; } [JsonProperty("event_type")] public string EventType { get; set; } [JsonProperty("event_step")] public int EventStep { get; set; } [JsonProperty("country")] public string Country { get; set; } [JsonProperty("event_params")] public Dictionary<string, string> EventParams { get; set; } [JsonProperty("device_id_map")] public Dictionary<string, string> DeviceIdMap { get; set; } [JsonProperty("experiment_id_list")] public List<object> ExperimentIdList { get; set; } }
步骤3:调用反序列化
// 你的原始JSON字符串 string rawJson = "你从API拿到的JSON字符串"; // 先解析外层数组,取value字段 JArray jArray = JArray.Parse(rawJson); JToken valueToken = jArray[0]["value"]; // 直接转成目标实体 MyModel result = valueToken.ToObject<MyModel>();
补充说明
- 如果外层JSON数组包含多个元素,遍历
jArray逐个提取value字段反序列化即可 - 如需支持序列化回原结构,补充实现
WriteJson方法即可 - 嵌套的自定义类只要添加同样的转换器属性即可自动适配
内容的提问来源于stack exchange,提问作者Tiago B
相关产品推荐
相关产品推荐

