【问题标题】:How to get Newtonsoft.Json to serialize a property name the way I want如何让 Newtonsoft.Json 以我想要的方式序列化属性名称
【发布时间】:2021-05-05 13:05:20
【问题描述】:

我试图以这样的 JSON 结尾:

{"KIBANA_INDEX":"whatever"}

但是当我尝试像这样使用JsonPropertyAttribute 时:

[JsonProperty(PropertyName ="KIBANA_INDEX")]
public string KibanaIndex{ get; set; }

我最终得到了这样的 JSON:

{"kibanA_INDEX":"whatever"}

有什么方法可以让 Newtonsoft.Json 服从我的意愿?

【问题讨论】:

  • @Qpirate 会起作用吗?问题是属性名称,而不是属性值,我是否必须手动滚动 KIBANA_INDEX 属性所在的整个(相当大的)对象......在这种情况下,使用 json 毫无意义。完全没有...
  • 我还有一些疑惑。我尝试了相同的代码,并且能够将 {"KIBANA_INDEX":"whatever"} 作为序列化响应。我不确定我是否理解确切的问题。您是否尝试序列化一个大模型以获得这样的 JSON?
  • 我进一步研究了它,得到了与@Sangeethnandakumar 相同的响应,但我使用的是一个简单的类,我们可以得到你的完整模型吗?您还有自定义序列化程序设置吗?可能有一个合同解析器在做这种奇怪的行为

标签: .net json.net .net-5


【解决方案1】:

默认情况下,Json.Net 不会那样做。如果您在 [JsonProperty] 属性中提供特定名称,序列化程序将使用它,您应该在输出中看到它。下面是一个示例程序来演示:

using System;
using Newtonsoft.Json;
                    
public class Program
{
    public static void Main()
    {
        var foo = new Foo { KibanaIndex = "whatever" };
        var json = JsonConvert.SerializeObject(foo);
        Console.WriteLine(json);
    }
}

public class Foo
{
    [JsonProperty(PropertyName = "KIBANA_INDEX")]
    public string KibanaIndex { get; set; } 
}

输出:

{"KIBANA_INDEX":"whatever"}

在这里提琴:https://dotnetfiddle.net/N753GP

我怀疑您实际上使用的是CamelCasePropertyNamesContractResolver。此解析器将导致所有属性名称以驼峰形式输出,包括您通过[JsonProperty] 属性指定名称的属性名称。这里还是同样的例子,只是改为使用CamelCasePropertyNamesContractResolver

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
                    
public class Program
{
    public static void Main()
    {
        var foo = new Foo { KibanaIndex = "whatever" };
        var resolver = new CamelCasePropertyNamesContractResolver();
        var settings = new JsonSerializerSettings { ContractResolver = resolver };
        var json = JsonConvert.SerializeObject(foo, settings);
        Console.WriteLine(json);
    }
}

这是输出,应该看起来很熟悉:

{"kibanA_INDEX":"whatever"}

小提琴:https://dotnetfiddle.net/KBhreA

如果这不是你想要的行为,很容易改变。为此,您只需将解析器中NamingStrategy 上的OverrideSpecifiedNames 属性设置为false,如下所示。 (请注意,我在此示例中向 Foo 类添加了另一个属性,以表明驼峰式大小写仍然适用于 具有 [JsonProperty] 属性的属性。)

using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
                    
public class Program
{
    public static void Main()
    {
        var foo = new Foo { KibanaIndex = "whatever", AnotherProperty = "whatever" };
        var resolver = new CamelCasePropertyNamesContractResolver();
        resolver.NamingStrategy.OverrideSpecifiedNames = false;
        var settings = new JsonSerializerSettings { ContractResolver = resolver };
        var json = JsonConvert.SerializeObject(foo, settings);
        Console.WriteLine(json);
    }
}

public class Foo
{
    [JsonProperty(PropertyName = "KIBANA_INDEX")]
    public string KibanaIndex { get; set; } 
    
    public string AnotherProperty { get; set; }
}

输出:

{"KIBANA_INDEX":"whatever","anotherProperty":"whatever"}

小提琴:https://dotnetfiddle.net/0qeP3o

【讨论】:

  • 你完全正确!我不知道我们在没有关闭 OverrideSpecifiedNames 的情况下设置了 CamelCasePropertyNamesContractResolver。谢谢!
  • 没问题;很高兴我能帮上忙!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多