如何让 Newtonsoft.Json 按照我想要的方式序列化属性名称

And*_*sen 4 .net json.net .net-5

我试图以这样的 JSON 结束:

{"KIBANA_INDEX":"whatever"}
Run Code Online (Sandbox Code Playgroud)

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

[JsonProperty(PropertyName ="KIBANA_INDEX")]
public string KibanaIndex{ get; set; }
Run Code Online (Sandbox Code Playgroud)

我最终得到这样的 JSON:

{"kibanA_INDEX":"whatever"}
Run Code Online (Sandbox Code Playgroud)

有什么办法可以让 Newtonsoft.Json 屈服于我的意愿吗?

Bri*_*ers 5

默认情况下,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; } 
}
Run Code Online (Sandbox Code Playgroud)

输出:

{"KIBANA_INDEX":"whatever"}
Run Code Online (Sandbox Code Playgroud)

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

我怀疑您实际上正在使用CamelCasePropertyNamesContractResolver. 此解析器将使所有属性名称以驼峰式大小写形式输出,包括您通过属性指定名称的属性名称[JsonProperty]。这是同样的示例,只不过更改为使用 a 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

{"kibanA_INDEX":"whatever"}
Run Code Online (Sandbox Code Playgroud)

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

如果这不是您想要的行为,则很容易改变。为此,您只需将解析器内的OverrideSpecifiedNames属性设置为,如下所示。(请注意,我在本示例中向类添加了另一个属性,以表明驼峰式大小写仍然适用于没有属性的属性。)NamingStrategyfalseFoo[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; }
}
Run Code Online (Sandbox Code Playgroud)

输出:

{"KIBANA_INDEX":"whatever","anotherProperty":"whatever"}
Run Code Online (Sandbox Code Playgroud)

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