You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Newtonsoft.Json将单属性对象JSON数组反序列化为字符串集合

解决方案:无需额外类直接反序列化单属性JSON数组为字符串集合

嘿,这个需求我太懂了——谁想为了一个单属性专门建个冗余类啊!下面给你几个实用的方法,不用额外定义ListFieldItem,直接把JSON里的ListField数组反序列成ICollection<string>:

方法1:自定义JsonConverter(推荐,通用且可复用)

写一个通用的转换器,专门处理这种“包含单属性对象的数组”,可以指定要提取的属性名,之后不管是字符串还是其他类型都能复用。

转换器代码:

public class SinglePropertyArrayConverter<T> : JsonConverter<ICollection<T>>
{
    private readonly string _targetPropertyName;

    // 构造函数传入要提取的属性名(比如这里的"Name")
    public SinglePropertyArrayConverter(string targetPropertyName)
    {
        _targetPropertyName = targetPropertyName;
    }

    public override ICollection<T> ReadJson(JsonReader reader, Type objectType, ICollection<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 加载JSON数组
        var jArray = JArray.Load(reader);
        // 初始化结果集合(如果已有实例就用现有,否则创建新的)
        var result = existingValue ?? (ICollection<T>)Activator.CreateInstance(objectType);
        
        foreach (var jObject in jArray)
        {
            // 提取指定属性的值并转换为目标类型
            var value = jObject[_targetPropertyName].ToObject<T>(serializer);
            result.Add(value);
        }
        return result;
    }

    // 如果需要序列化回去,也实现WriteJson方法(可选)
    public override void WriteJson(JsonWriter writer, ICollection<T> value, JsonSerializer serializer)
    {
        writer.WriteStartArray();
        foreach (var item in value)
        {
            writer.WriteStartObject();
            writer.WritePropertyName(_targetPropertyName);
            serializer.Serialize(writer, item);
            writer.WriteEndObject();
        }
        writer.WriteEndArray();
    }
}

在目标类中使用:

直接在ListField属性上标记转换器,指定要提取的属性名"Name":

public class ClassName
{
    public string FieldString;
    public bool FieldBool;
    public Guid FieldId;
    // 标记转换器,传入要提取的属性名
    [JsonConverter(typeof(SinglePropertyArrayConverter<string>), "Name")]
    public ICollection<string> ListField;
}

之后你原来的反序列化代码完全不用改:

var result = JsonConvert.DeserializeObject<ClassName>(jsonString);

方法2:手动解析(适合临时场景)

如果只是偶尔用一次,不想写转换器,可以先把JSON解析成JObject,手动提取各个字段的值:

// 先解析JSON为JObject
var jsonObj = JObject.Parse(jsonString);

// 手动映射每个属性
var className = new ClassName
{
    FieldString = jsonObj["FieldString"].ToString(),
    FieldBool = jsonObj["FieldBool"].ToObject<bool>(),
    FieldId = jsonObj["FieldId"].ToObject<Guid>(),
    // 遍历ListField数组,提取每个对象的Name属性
    ListField = jsonObj["ListField"]
        .Select(item => item["Name"].ToString())
        .ToList()
};

这个方法简单直接,但复用性差,适合临时处理特定JSON的场景。

额外小技巧:全局注册转换器

如果你的项目里有很多这种场景,可以把转换器全局注册到JsonSerializerSettings里,这样不用每个属性都加特性:

var settings = new JsonSerializerSettings();
// 注册针对ICollection<string>且提取"Name"属性的转换器
settings.Converters.Add(new SinglePropertyArrayConverter<string>("Name"));

var result = JsonConvert.DeserializeObject<ClassName>(jsonString, settings);

不过这种方式要注意,如果有其他ICollection<string>类型的属性不需要转换,可能会冲突,所以还是属性级别的标记更稳妥。

内容的提问来源于stack exchange,提问作者xzyvvy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 00:52:37