Newtonsoft JsonConvert.SerializeObject如果名称为大写,则忽略JsonProperty [英] Newtonsoft JsonConvert.SerializeObject ignoring JsonProperty if name is uppercase

查看:277
本文介绍了Newtonsoft JsonConvert.SerializeObject如果名称为大写,则忽略JsonProperty的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够使用CamelCasePropertyNameContractResolver,但要为特定的属性名称覆盖它.为此,我使用JsonProperty属性.除非我选择的名称全为大写,否则此方法工作正常.有任何想法出什么问题或如何解决吗?

I want to be able to use the CamelCasePropertyNameContractResolver but override it for specific property names. For this, I use the JsonProperty attribute. This works fine except when the name that I choose is fully uppercase. Any ideas what's wrong or how to get around it?

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

In the example below, Bar is serialized to "BAR" when I don't use the CamelCasePropertyNameContractResolver, but is serialized to "bar" when I do use the resolver. Foo and CamelCaseProperty are serialized correctly in both scenarios.

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace ConsoleTester
{
    class Program
    {
        static void Main(string[] args)
        {
            var foo = new FooBar {CamelCaseProperty = "test", Foo = "test", Bar = "test" };
            var output = JsonConvert.SerializeObject(foo);
            // output "CamelCaseProperty", "fOO", "BAR"

            var output2 = JsonConvert.SerializeObject(foo, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() });
            // output "camelCaseProperty", "fOO", "bar"
        }
    }

    public class FooBar
    {
        public string CamelCaseProperty { get; set; }
        [JsonProperty("fOO")]
        public string Foo { get; set; }
        [JsonProperty("BAR")]
        public string Bar { get; set; }
    }
}

推荐答案

原因,您看到的原因是CamelCasePropertyNamesContractResolver旨在覆盖

The reason you are seeing this is that CamelCasePropertyNamesContractResolver is intentionally designed to override the casing of dictionary keys and explicitly set property names, as can be see from the reference source:

public CamelCasePropertyNamesContractResolver()
{
    NamingStrategy = new CamelCaseNamingStrategy
    {
        ProcessDictionaryKeys = true,
        OverrideSpecifiedNames = true
    };
}

如果您不希望这样做,则可以使用多个选项来防止在不创建自己的自定义合同解析器类型的情况下使用显式名称进行大小写.

If you don't want that, you have several options to prevent casing of explicit names without creating your own custom contract resolver type.

首先,您可以使用 NamingStrategy = new CamelCaseNamingStrategy() :

Firstly, you could serialize using a DefaultContractResolver with NamingStrategy = new CamelCaseNamingStrategy():

var settings = new JsonSerializerSettings 
{ 
    ContractResolver = new DefaultContractResolver { NamingStrategy = new CamelCaseNamingStrategy() }
};
var output2 = JsonConvert.SerializeObject(foo, settings);

这会将 CamelCaseNamingStrategy.OverrideSpecifiedNames 保留为默认值.

This leaves CamelCaseNamingStrategy.OverrideSpecifiedNames at its default value of false.

其次,如果您无权访问框架的合同解析器,则可以设置

Secondly, if you don't have access to the contract resolver of your framework, you could set JsonPropertyAttribute.NamingStrategyType = typeof(DefaultNamingStrategy) on specific properties, like so:

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; }
}

第三次,如果您想让整个对象忽略当前合同解析器的命名策略,则可以应用

Thirdly, if you want your entire object to ignore the naming strategy of the current contract resolver, you can apply [JsonObject(NamingStrategyType = typeof(TNamingStrategy))] to your object:

[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; }
}

注意:

  • While it is also possible to modify the NamingStrategy of an instance of CamelCasePropertyNamesContractResolver, since the latter shares contract information globally across all instances of each type, this can lead to unexpected side-effects if your application tries to use multiple instances of CamelCasePropertyNamesContractResolver. No such problem exists with DefaultContractResolver, so it is safer to use when any customization of casing logic is required.

使用或子类化DefaultContractResolver时,您可能想要缓存合同解析器,以获得最佳性能,因为它不会在每种类型的所有实例之间全局共享合同信息.

When using or subclassing DefaultContractResolver, you may want to cache the contract resolver for best performance, since it does not share contract information globally across all instances of each type.

我不知道为什么Json.NET的驼峰式案例解析器旨在重写指定的名称,这可能是出于历史原因.

I don't know why Json.NET's camel case resolver is designed to override specified names, it may be for historical reasons.

命名策略最初是在 Json.NET 9.0中引入的. 1 ,因此此答案仅适用于该版本及更高版本.

Naming strategies were first introduced in Json.NET 9.0.1 so this answer works only for that version and later.

这篇关于Newtonsoft JsonConvert.SerializeObject如果名称为大写,则忽略JsonProperty的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆