如果name为大写,则Newtonsoft JsonConvert.SerializeObject忽略JsonProperty

时间:2018-02-06 16:30:31

标签: c# .net serialization json.net

我希望能够使用CamelCasePropertyNameContractResolver,但会覆盖特定属性名称。为此,我使用JsonProperty属性。这种方法很好,除非我选择的名称是完全大写的。任何想法有什么不对或如何绕过它?

在下面的示例中,当我不使用CamelCasePropertyNameContractResolver时,Bar被序列化为"BAR",但在我使用解析器时序列化为"bar"Foo在两种情况下均已正确序列化。

CamelCaseProperty

2 个答案:

答案 0 :(得分:8)

原因您看到CamelCasePropertyNamesContractResolver有意设计为覆盖dictionary keysexplicitly 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; }
}

注意:

答案 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() });