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

无需令牌选择器,如何用对象值自动部分替换JSON属性

问题描述

给定如下C#模型:

public class Fruit
{
    public int Id { get; set; }

    public string FruitName { get; set; }
}

以及如下JSON字符串:

{
  "Id": 1,
  "FruitName": "Apple",
  "Currency": "USD"
}

要求不使用令牌选择器,通过编程方式替换JSON中Id和FruitName的属性值,同时保留Currency这类模型中不存在的属性。

已知可以通过逐个赋值实现:

FruitJson["Id"] = Fruit.Id;
FruitJson["FruitName"] = Fruit.FruitName;

但希望基于已有Fruit对象实现更通用的方案,比如类似以下逻辑:

dynamic fruitJson = JObject.Parse(json);
Fruit fruit = new Fruit { Id = 1, FruitName = "Orange" };
fruitJson.ReplaceOnlyPropertiesThatExistInObject(fruit);

执行后期望输出:

{
  "Id": 1,
  "FruitName": "Orange",
  "Currency": "USD"
}

尝试过的方法都会误删Currency属性,已知JsonSerializer.Populate可以用JSON填充对象,但需要反向操作(用对象更新JSON,保留额外属性)。


解决方案

方案一:反射遍历属性更新JObject

通过反射获取目标对象的所有公共属性,遍历后更新JObject中对应的键,完全保留JSON原有额外属性。

代码实现:

using Newtonsoft.Json.Linq;
using System.Reflection;

// 解析原始JSON字符串
JObject fruitJson = JObject.Parse(json);
// 待更新的Fruit实例
Fruit fruit = new Fruit { Id = 1, FruitName = "Orange" };

// 获取Fruit类型的所有公共实例属性
PropertyInfo[] properties = typeof(Fruit).GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo prop in properties)
{
    // 获取对象的属性值
    object propValue = prop.GetValue(fruit);
    // 检查JObject中是否存在对应键,存在则更新值
    if (fruitJson.ContainsKey(prop.Name))
    {
        fruitJson[prop.Name] = JToken.FromObject(propValue);
    }
}

// 输出更新后的JSON
string updatedJson = fruitJson.ToString();

方案二:封装为JObject扩展方法

如果需要重复使用该逻辑,可封装成扩展方法,实现需求中设想的ReplaceOnlyPropertiesThatExistInObject调用方式:

using Newtonsoft.Json.Linq;
using System.Reflection;

public static class JObjectExtensions
{
    public static void ReplaceOnlyPropertiesThatExistInObject<T>(this JObject jObject, T sourceObject)
    {
        if (sourceObject == null)
            throw new ArgumentNullException(nameof(sourceObject));

        PropertyInfo[] properties = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);

        foreach (PropertyInfo prop in properties)
        {
            object propValue = prop.GetValue(sourceObject);
            if (jObject.ContainsKey(prop.Name))
            {
                jObject[prop.Name] = JToken.FromObject(propValue);
            }
        }
    }
}

调用方式:

dynamic fruitJson = JObject.Parse(json);
Fruit fruit = new Fruit { Id = 1, FruitName = "Orange" };
fruitJson.ReplaceOnlyPropertiesThatExistInObject(fruit);

补充说明

  • 以上代码依赖Newtonsoft.Json(Json.NET)库;若使用System.Text.Json,可通过JsonNode实现类似逻辑,遍历对象属性后更新对应节点值。
  • 反射方式具备通用性,后续Fruit类新增属性时,无需修改更新逻辑,会自动同步JSON中对应键的值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 15:47:45