JsonSerializerSettings更改属性名称的大小写,但不更改属性属性的名称

时间:2017-02-07 14:28:11

标签: c# json jsonserializer

我正在使用我的类属性的驼峰外壳的以下设置。

JsonSerializerSettings settings = new JsonSerializerSettings()
        {
            ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
        };

对象中的某些属性属于其他类类型。我不想改变那些属性的情况。

例如:

Public Class CaseToChange
{
    public string StringProperty{get;set;} //Change to camelCase
    public SomeOtherType OtherTypeProperty{get;set;} //Change name of this to camelCase but not property name of "SomeOtherType"

}

如何使用JsonSerializerSettings实现此目的?

2 个答案:

答案 0 :(得分:3)

如下所示,只需添加JsonProperty属性,如果您不希望整个对象树使用camelCasing,则不要使用CamelCasePropertyNamesContractResolver

public class CaseToChange
{
    [JsonProperty("stringProperty")]
    public string StringProperty { get; set; } //Change to camelCase

    [JsonProperty("otherTypeProperty")]
    public SomeOtherType OtherTypeProperty { get; set; } //Change name of this to camelCase but not property name of "SomeOtherType"
}

答案 1 :(得分:3)

如果您可以修改要添加Json.NET serialization attributes的类型,最简单的方法是将[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]添加到CaseToChange类型:

[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class CaseToChange
{
    public string StringProperty { get; set; } //Change to camelCase
    public SomeOtherType OtherTypeProperty { get; set; } //Change name of this to camelCase but not property name of "SomeOtherType"
}

(或者,如果您使用的是早于9.0.1的Json.NET版本,请将[JsonProperty("camelCaseName")]添加到this answer中的每个媒体资源中。)

如果您无法修改类型并且必须仅通过序列化程序设置来追踪CaseToChange的属性,则可以创建custom contract resolver,以返回CaseToChange的驼峰名称且未修改其他类型的名称。以下是诀窍:

public class OverrideContractResolver : ContractResolverDecorator
{
    readonly Dictionary<Type, IContractResolver> overrides;

    public OverrideContractResolver(IEnumerable<KeyValuePair<Type, IContractResolver>> overrides, IContractResolver baseResolver)
        : base(baseResolver)
    {
        if (overrides == null)
            throw new ArgumentNullException();
        this.overrides = overrides.ToDictionary(p => p.Key, p => p.Value);
    }

    public override JsonContract ResolveContract(Type type)
    {
        IContractResolver resolver;
        if (overrides.TryGetValue(type, out resolver))
            return resolver.ResolveContract(type);
        return base.ResolveContract(type);
    }
}

public class ContractResolverDecorator : IContractResolver
{
    readonly IContractResolver baseResolver;

    public ContractResolverDecorator(IContractResolver baseResolver)
    {
        if (baseResolver == null)
            throw new ArgumentNullException();
        this.baseResolver = baseResolver;
    }

    #region IContractResolver Members

    public virtual JsonContract ResolveContract(Type type)
    {
        return baseResolver.ResolveContract(type);
    }

    #endregion
}

然后使用以下设置进行序列化:

var settings = new JsonSerializerSettings
{
    ContractResolver =
        new OverrideContractResolver(
            new Dictionary<Type, IContractResolver> { { typeof(CaseToChange), new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() } },
            new Newtonsoft.Json.Serialization.DefaultContractResolver()),
};

结果JSON将如下所示:

{
  "stringProperty": "string property",
  "otherTypeProperty": {
    "FooProperty": "foo",
    "BarProperty": 101
  }
}

示例fiddle

为获得最佳效果,您可能需要cache instances of the contract resolver