问题
I am using below settings for camel casing of my class property.
JsonSerializerSettings settings = new JsonSerializerSettings()
{
ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver()
};
Some of the property in the object are of some other class type. I do not want to change case of those properties.
Eg:
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"
}
How to achieve this with JsonSerializerSettings?
回答1:
If you can modify your types to add Json.NET serialization attributes, the easiest thing to do would be to add [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] to your CaseToChange
type:
[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"
}
(Or, if you are using a version of Json.NET earlier than 9.0.1, add [JsonProperty("camelCaseName")]
to each property as in this answer.)
If you cannot modify the type and must camel-case the properties of CaseToChange
only through serializer settings, you can create a custom contract resolver that returns camel-cased names for CaseToChange
and unmodified names for other types. The following does the trick:
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
}
Then serialize with settings as follows:
var settings = new JsonSerializerSettings
{
ContractResolver =
new OverrideContractResolver(
new Dictionary<Type, IContractResolver> { { typeof(CaseToChange), new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver() } },
new Newtonsoft.Json.Serialization.DefaultContractResolver()),
};
And the resulting JSON will look like:
{
"stringProperty": "string property",
"otherTypeProperty": {
"FooProperty": "foo",
"BarProperty": 101
}
}
Sample fiddle.
For optimal performance you may want to cache instances of the contract resolver.
回答2:
Simply add the JsonProperty attribute as shown below and don't use the CamelCasePropertyNamesContractResolver
if you don't want camelCasing for the whole object tree.
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"
}
来源:https://stackoverflow.com/questions/42092359/jsonserializersettings-to-change-case-of-property-name-but-not-name-of-property