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

C#如何将JSON子属性反序列化到父类属性中?

当然可以搞定!这种把JSON里嵌套的子属性映射到父类平级属性的需求,在.NET里用主流的JSON序列化库都能实现,我给你详细讲讲两种常用方案:

使用Newtonsoft.Json(Json.NET)实现映射

这是.NET生态里老牌且功能丰富的JSON库,处理这种映射非常简单,推荐优先用这个方案:

方法1:利用JsonProperty特性的路径映射

直接在你的Issue类属性上添加JsonProperty特性,指定对应的JSON嵌套路径即可:

public class Issue 
{ 
    public int? id { get; set; } 

    [JsonProperty(PropertyName = "project.id")]
    public int project_id { get; set; } 

    [JsonProperty(PropertyName = "project.name")]
    public string project_name { get; set; } 
}

反序列化的时候直接调用常规方法就行:

string json = "{ \"issue\" : { \"id\": 1, \"project\": { \"id\":1, \"name\":\"name of project\" } } }";
// 先提取issue节点的内容(也可以把Issue包装到对应类里,这里只处理核心对象)
var issueJson = JObject.Parse(json)["issue"].ToString();
var issue = JsonConvert.DeserializeObject<Issue>(issueJson);

方法2:自定义Json转换器(适合复杂场景)

如果你的映射逻辑更复杂,还可以写一个自定义转换器来手动处理:

public class IssueConverter : JsonConverter<Issue>
{
    public override Issue ReadJson(JsonReader reader, Type objectType, Issue existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var jo = JObject.Load(reader);
        var issue = new Issue();
        issue.id = (int?)jo["id"];
        issue.project_id = (int)jo["project"]["id"];
        issue.project_name = (string)jo["project"]["name"];
        return issue;
    }

    public override void WriteJson(JsonWriter writer, Issue value, JsonSerializer serializer)
    {
        // 如果需要序列化回JSON,这里可以编写对应的逻辑
        var jo = new JObject();
        jo["id"] = value.id;
        jo["project"] = new JObject
        {
            ["id"] = value.project_id,
            ["name"] = value.project_name
        };
        jo.WriteTo(writer);
    }
}

使用转换器时,在序列化选项里添加即可:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new IssueConverter());
var issue = JsonConvert.DeserializeObject<Issue>(issueJson, settings);
使用System.Text.Json实现映射

如果你用的是.NET Core 3.0+或者.NET 5+,默认的System.Text.Json也能实现,不过它原生不支持路径映射,需要用下面两种方式:

方法1:自定义Json转换器

写一个专属的转换器来手动解析嵌套属性:

public class IssueConverter : JsonConverter<Issue>
{
    public override Issue Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using JsonDocument doc = JsonDocument.ParseValue(ref reader);
        var root = doc.RootElement;
        
        var issue = new Issue();
        issue.id = root.GetProperty("id").GetInt32();
        
        var projectElement = root.GetProperty("project");
        issue.project_id = projectElement.GetProperty("id").GetInt32();
        issue.project_name = projectElement.GetProperty("name").GetString();
        
        return issue;
    }

    public override void Write(Utf8JsonWriter writer, Issue value, JsonSerializerOptions options)
    {
        // 序列化逻辑(按需实现)
        writer.WriteStartObject();
        writer.WriteNumber("id", value.id ?? 0);
        writer.WriteStartObject("project");
        writer.WriteNumber("id", value.project_id);
        writer.WriteString("name", value.project_name);
        writer.WriteEndObject();
        writer.WriteEndObject();
    }
}

使用时添加转换器到选项:

var options = new JsonSerializerOptions();
options.Converters.Add(new IssueConverter());
var issue = JsonSerializer.Deserialize<Issue>(issueJson, options);

方法2:匿名类型投影(简单场景快捷方案)

如果只是简单的映射,也可以先反序列化成JsonElement,再手动赋值:

var jsonElement = JsonSerializer.Deserialize<JsonElement>(issueJson);
var issue = new Issue
{
    id = jsonElement.GetProperty("id").GetInt32(),
    project_id = jsonElement.GetProperty("project").GetProperty("id").GetInt32(),
    project_name = jsonElement.GetProperty("project").GetProperty("name").GetString()
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:02:47