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

.NET中如何使用JsonConvert.DeserializeObject仅反序列化所需属性

两种基于JsonConvert的实现方案,无需使用JObject.Parse手动解析全量JSON

可以根据是否允许修改原有LinkedInUser类结构二选一:


方案1:自定义JsonConverter(无需修改原有LinkedInUser类,推荐)

完全不改动你已定义的LinkedInUser结构,仅新增一个转换器类即可实现适配:

第一步:编写自定义转换器

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using project.DTOs.Models;

public class LinkedInUserConverter : JsonConverter<LinkedInUser>
{
    public override LinkedInUser ReadJson(JsonReader reader, Type objectType, LinkedInUser existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jsonObj = JObject.Load(reader);
        var user = new LinkedInUser();
        
        // 解析FirstName:优先匹配首选 locale 对应的值,无匹配则取localized下第一个值
        var firstNameNode = jsonObj["firstName"];
        if (firstNameNode != null)
        {
            var localizedFirstName = firstNameNode["localized"] as JObject;
            var preferredLocale = firstNameNode["preferredLocale"];
            string localeKey = $"{preferredLocale["language"]}_{preferredLocale["country"]}";
            user.FirstName = localizedFirstName.TryGetValue(localeKey, out var firstNameVal) 
                ? firstNameVal.ToString() 
                : localizedFirstName?.First?.First?.ToString();
        }

        // 解析LastName,逻辑同FirstName
        var lastNameNode = jsonObj["lastName"];
        if (lastNameNode != null)
        {
            var localizedLastName = lastNameNode["localized"] as JObject;
            var preferredLocale = lastNameNode["preferredLocale"];
            string localeKey = $"{preferredLocale["language"]}_{preferredLocale["country"]}";
            user.LastName = localizedLastName.TryGetValue(localeKey, out var lastNameVal) 
                ? lastNameVal.ToString() 
                : localizedLastName?.First?.First?.ToString();
        }
        // JSON多余字段会自动忽略,无需额外处理
        return user;
    }

    public override void WriteJson(JsonWriter writer, LinkedInUser value, JsonSerializer serializer)
    {
        // 仅需反序列化场景可直接留空或抛出未实现异常
        throw new NotImplementedException();
    }
}

第二步:反序列化时指定转换器

var linkedInUser = JsonConvert.DeserializeObject<LinkedInUser>(
    await GetData(token), 
    new LinkedInUserConverter()
);

方案2:扩展LinkedInUser类(无需额外开发转换器,完全不涉及JObject操作)

如果允许调整原有LinkedInUser的内部结构,可以通过嵌套属性映射+反序列化回调实现适配,调用方代码完全不用改:

using Newtonsoft.Json;
using System.Runtime.Serialization;

namespace project.DTOs.Models
{
    public class LinkedInUser
    {
        [JsonIgnore] // 标记忽略,因为JSON对应字段是嵌套对象而非字符串
        public string FirstName { get; set;}
        [JsonIgnore]
        public string LastName { get; set; }  

        // 新增内部属性映射JSON的嵌套结构
        [JsonProperty("firstName")]
        internal LinkedInNameDto FirstNameDto { get; set; }
        [JsonProperty("lastName")]
        internal LinkedInNameDto LastNameDto { get; set; }

        // 反序列化完成后自动执行赋值逻辑
        [OnDeserialized]
        internal void OnDeserializedMethod(StreamingContext context)
        {
            if (FirstNameDto != null)
            {
                string localeKey = $"{FirstNameDto.PreferredLocale.Language}_{FirstNameDto.PreferredLocale.Country}";
                FirstName = FirstNameDto.Localized.TryGetValue(localeKey, out var val) ? val : FirstNameDto.Localized.First().Value;
            }
            if (LastNameDto != null)
            {
                string localeKey = $"{LastNameDto.PreferredLocale.Language}_{LastNameDto.PreferredLocale.Country}";
                LastName = LastNameDto.Localized.TryGetValue(localeKey, out var val) ? val : LastNameDto.Localized.First().Value;
            }
        }
    }

    // 内部辅助类,无需对外暴露
    internal class LinkedInNameDto
    {
        public Dictionary<string, string> Localized { get; set; }
        public LinkedInLocaleDto PreferredLocale { get; set; }
    }

    internal class LinkedInLocaleDto
    {
        public string Country { get; set; }
        public string Language { get; set; }
    }
}

调整完成后直接用你原来的反序列化代码即可:

var linkedInUser = JsonConvert.DeserializeObject<LinkedInUser>(await GetData(token));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:15:03