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

如何让顶级类的Json.NET命名策略属性作用于嵌套类?

问题:让顶级类的Json.NET命名策略自动作用于嵌套类?

我有如下代码,在顶级类Foo上添加了[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]属性,但序列化时只有Foo的成员遵循驼峰命名,嵌套类NestedFoo的成员NestedBar没有被序列化为nestedBar:

internal class Program
{
    [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
    public class Foo
    {
        public string Bar;
        public NestedFoo NestedFoo { get; set; }
    }
    public class NestedFoo
    {
        public string NestedBar;
    }

    static void Main(string[] args)
    {
        Foo c = new();
        c.NestedFoo = new();
        c.Bar = "Bar";
        c.NestedFoo.NestedBar = "NestedBar ";
        string output = JsonConvert.SerializeObject(c, Formatting.Indented);

        Console.WriteLine(output);
    }
}

序列化输出:

{
  "bar": "Bar",
  "nestedFoo": {
    "NestedBar": "NestedBar "
  }
}

已知两种解决方案,但希望仅通过修改顶级类的属性实现需求:

  • 为每个嵌套类添加[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]属性;
  • 为JsonConvert.SerializeObject方法传入全局命名策略。

请问是否存在方法,让顶级类的命名策略属性同时作用于自身及所有嵌套属性?


解决方案

Json.NET原生不支持自动将顶级类的NamingStrategyType传递给嵌套类,要实现仅通过顶级类属性达到需求,需要自定义ContractResolver并配合类属性使用:

1. 自定义ContractResolver

创建一个继承自DefaultContractResolver的解析器,重写CreateContract方法,让嵌套类继承父对象的命名策略:

public class InheritedNamingContractResolver : DefaultContractResolver
{
    protected override JsonContract CreateContract(Type objectType)
    {
        var contract = base.CreateContract(objectType);
        
        // 获取当前父对象的JsonObject属性,继承其命名策略
        var parentObj = Serializer?.Context?.CurrentObject;
        if (parentObj != null)
        {
            var parentAttr = parentObj.GetType().GetCustomAttribute<JsonObjectAttribute>();
            if (parentAttr != null && parentAttr.NamingStrategyType != null)
            {
                contract.NamingStrategy = Activator.CreateInstance(parentAttr.NamingStrategyType) as NamingStrategy;
            }
        }
        
        return contract;
    }
}

2. 在顶级类上指定自定义Resolver和命名策略

修改Foo类的[JsonObject]属性,同时指定自定义ContractResolver和驼峰命名策略:

[JsonObject(
    ContractResolverType = typeof(InheritedNamingContractResolver),
    NamingStrategyType = typeof(CamelCaseNamingStrategy)
)]
public class Foo
{
    public string Bar;
    public NestedFoo NestedFoo { get; set; }
}

3. 序列化效果

此时重新运行代码,输出会符合预期:

{
  "bar": "Bar",
  "nestedFoo": {
    "nestedBar": "NestedBar "
  }
}

这个方案只需要修改顶级类的属性,不需要改动嵌套类或序列化方法的参数,完全符合需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 20:50:53