我希望能够使用CamelCasePropertyNameContractResolver
,但会覆盖特定属性名称。为此,我使用JsonProperty
属性。这种方法很好,除非我选择的名称是完全大写的。任何想法有什么不对或如何绕过它?
在下面的示例中,当我不使用CamelCasePropertyNameContractResolver时,Bar
被序列化为"BAR"
,但在我使用解析器时序列化为"bar"
。 1}}和Foo
在两种情况下均已正确序列化。
CamelCaseProperty
答案 0 :(得分:8)
原因您看到CamelCasePropertyNamesContractResolver
有意设计为覆盖dictionary keys和explicitly set property names的大小写,可以从{{ {3}}:
public CamelCasePropertyNamesContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
};
}
如果您不想这样做,您可以选择多种方法来阻止显式名称的大写,而无需创建自己的自定义合约解析程序类型。
首先,您可以使用reference source DefaultContractResolver
进行序列化:
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }
};
var output2 = JsonConvert.SerializeObject(foo, settings);
这会使NamingStrategy = new CamelCaseNamingStrategy()
保留默认值false
。
其次,如果您无权访问框架的合约解析程序,则可以在特定属性上设置CamelCaseNamingStrategy.OverrideSpecifiedNames
,如下所示:
public class FooBar
{
public string CamelCaseProperty { get; set; }
[JsonProperty("fOO")]
public string Foo { get; set; }
[JsonProperty("BAR", NamingStrategyType = typeof(DefaultNamingStrategy))]
public string Bar { get; set; }
}
第三,如果您希望整个对象忽略当前合约解析程序的命名策略,则可以将JsonPropertyAttribute.NamingStrategyType = typeof(DefaultNamingStrategy)
应用于您的对象:
[JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))]
public class FooBar
{
public string CamelCaseProperty { get; set; }
[JsonProperty("fOO")]
public string Foo { get; set; }
[JsonProperty("BAR")]
public string Bar { get; set; }
}
注意:
虽然也可以修改[JsonObject(NamingStrategyType = typeof(TNamingStrategy))]
实例的NamingStrategy
,但由于后者为CamelCasePropertyNamesContractResolver
,如果您的应用尝试,这可能会导致意外的副作用使用CamelCasePropertyNamesContractResolver
的多个实例。 DefaultContractResolver
不存在这样的问题,因此在需要对套管逻辑进行任何自定义时使用它会更安全。
使用或继承DefaultContractResolver
时,您可能希望shares contract information globally across all instances of each type获得最佳效果,因为它不会在每种类型的所有实例中全局共享合同信息。
我不知道为什么Json.NET的骆驼案例解析器会被设计为覆盖指定的名称,这可能是出于历史原因。
命名策略最初是在cache the contract resolver中引入的,所以这个答案仅适用于该版本及以后。
答案 1 :(得分:0)
使用ContractResolver时不遵守JsonProperty属性。
解决此问题的方法是覆盖ContractResolver:
public class MyResolver : CamelCasePropertyNamesContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var property = base.CreateProperty(member, memberSerialization);
if(member.GetCustomAttribute<JsonPropertyAttribute>() is JsonPropertyAttribute jsonProperty)
{
property.PropertyName = jsonProperty.PropertyName;
}
return property;
}
}
使用你的解析器:
var output2 = JsonConvert.SerializeObject(foo, new JsonSerializerSettings { ContractResolver = new MyResolver() });