JSON序列化中属性名称的默认驼峰式大小写

Posted

技术标签:

【中文标题】JSON序列化中属性名称的默认驼峰式大小写【英文标题】:Default camel case of property names in JSON serialization 【发布时间】:2014-03-14 00:53:27 【问题描述】:

我有一堆将在某个时候序列化为 JSON 的类,为了同时遵循后端的 C# 约定和前端的 javascript 约定,我一直在定义如下属性:

[JsonProperty(PropertyName="myFoo")]
public int MyFoo  get; set; 

所以在 C# 中我可以:

MyFoo = 10;

在 Javascript 中我可以:

if (myFoo === 10)

但是对每个属性都这样做是很乏味的。是否有一种快速简便的方法来设置 JSON.Net 处理属性名称的默认方式,以便除非另有说明,否则它将自动使用驼峰式大小写?

【问题讨论】:

【参考方案1】:

您可以使用提供的类Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver:

var serializer = new JsonSerializer

    ContractResolver = new CamelCasePropertyNamesContractResolver()
;
var jobj = JObject.FromObject(request, serializer);

换句话说,您不必自己创建自定义解析器。

【讨论】:

CamelCasePropertyNamesContractResolver 实际上已经存在很长时间了。它至少早在Json.Net 4.0.2(2011 年 4 月 21 日发布)就出现了。如果您注意到,OP 的解析器甚至会继承自它。 通过 OP,我假设您的意思是提出问题的人。那里没有提到它。不过很好。 是否可以将解析器指定为类的属性?【参考方案2】:

序列化对象时,传入一些自定义设置。

var settings = new JsonSerializerSettings

    ContractResolver = new CamelCasePropertyNamesContractResolver()
;

var json = JsonConvert.SerializeObject(yourObject, settings);

【讨论】:

不确定这与@DaveKennedy 的回答有何不同。 看看两个不同之处。 a) JsonSerializer vs JsonSerializerSettings 然后 b) JsonConvert.XX vs JObject.XX 问题的重点是CamelCasePropertyNamesContractResolver,其他都是次要的。 仍然有助于查看可以在哪里使用 ContractResolvers。【参考方案3】:

JObject.FromObject 使用来自JsonConvert 默认值的默认设置。 您可以像这样分配一个 func 属性:

 JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
 
   ContractResolver = new CamelCasePropertyNamesContractResolver()
 ;

每当你调用Jobject.FromObject时,它都会使用这个函数来构造设置。

【讨论】:

【参考方案4】:

最好使用新的CamelCaseNamingStrategy(自9.0.1):

new JsonSerializerSettings()

    ContractResolver = new DefaultContractResolver
    
       NamingStrategy = new CamelCaseNamingStrategy()
    
;

默认情况下它不会覆盖JsonPropert('Name') 设置的自定义名称。 (您可以通过CamelCaseNamingStrategy(bool, bool) ctor 更改行为。)因此,不需要像@Matt Burland 的回答那样创建自定义类。

【讨论】:

你知道第一个包含 CamelCaseNamingStrategy 的 Newtonsoft.Json 版本吗? @vezenkov since 9.0.1 根据更新日志。【参考方案5】:

您可以使用自定义contract resolver:

class MyContractResolver : DefaultContractResolver

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    
        var properties = base.CreateProperties(type, memberSerialization);

        foreach (var property in properties)
        
            property.PropertyName = char.ToLower(property.PropertyName[0]) + string.Join("", property.PropertyName.Skip(1));
        

        return properties;
    

并像这样使用它:

class MyClass

    public int MyProperty  get; set; 
    public int MyProperty2  get; set; 


var json = JsonConvert.SerializeObject(new MyClass(), 
                Formatting.Indented, 
                new JsonSerializerSettings  ContractResolver = new MyContractResolver() );

【讨论】:

【参考方案6】:

由于接受的答案是仅链接,我添加了我最终使用的实际代码(以防链接失效)。它与链接中的内容大致相同:

// Automatic camel casing because I'm bored of putting [JsonProperty] on everything
// See: http://harald-muehlhoff.de/post/2013/05/10/Automatic-camelCase-naming-with-JsonNET-and-Microsoft-Web-API.aspx#.Uv43fvldWCl
public class CamelCase : CamelCasePropertyNamesContractResolver

    protected override JsonProperty CreateProperty(MemberInfo member,
        MemberSerialization memberSerialization)
    
        var res = base.CreateProperty(member, memberSerialization);

        var attrs = member.GetCustomAttributes(typeof(JsonPropertyAttribute), true);

        if (attrs.Any())
        
            var attr = (attrs[0] as JsonPropertyAttribute);
            if (res.PropertyName != null && attr.PropertyName != null)
                res.PropertyName = attr.PropertyName;
        

        return res;
    

我所做的唯一更改是在 if 子句中添加了attr.PropertyName != null,因为我添加了以下内容:

[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string SomeProperty  get; set; 

并且不想指定PropertyName(所以它是空的)。以上将在 JSON 中序列化为someProperty

【讨论】:

【参考方案7】:

在 .NET 5.0 中,您可以使用 System.Text.Json 并在 JsonSerializerOptions 中指定 ProperyNamingPolicy

System.Text.Json.JsonSerializerOptions.PropertyNamingPolicy

Here's 指向 Microsoft 文档页面的链接,该页面将属性设置为使用驼峰式大小写。

var serializeOptions = new JsonSerializerOptions

    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
    WriteIndented = true
;
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);

public class WeatherForecastWithPropertyNameAttribute

    public DateTimeOffset Date  get; set; 
    public int TemperatureCelsius  get; set; 
    public string Summary  get; set; 
    [JsonPropertyName("Wind")]
    public int WindSpeed  get; set; 

JSON 输出


  "date": "2019-08-01T00:00:00-07:00",
  "temperatureCelsius": 25,
  "summary": "Hot",
  "Wind": 35

【讨论】:

【参考方案8】:
public static JsonSerializer FormattingData()

   var jsonSerializersettings = new JsonSerializer 
   ContractResolver = new CamelCasePropertyNamesContractResolver() ;
   return jsonSerializersettings;



public static JObject CamelCaseData(JObject jObject) 
   
     var expandoConverter = new ExpandoObjectConverter();
     dynamic camelCaseData = 
     JsonConvert.DeserializeObject(jObject.ToString(), 
     expandoConverter); 
     return JObject.FromObject(camelCaseData, FormattingData());

【讨论】:

扩展对象有助于解析将Pascalcase转换为CamelCase

以上是关于JSON序列化中属性名称的默认驼峰式大小写的主要内容,如果未能解决你的问题,请参考以下文章

在每个控制器的 ASP.NET WebAPI 上强制使用 CamelCase

Net Core中使用Newtonsoft.Json进行序列化保持原有大小写

如何在 Groovy 中的 JSON 转换器方法中保留字母大小写?

Newtonsoft.Json 序列化小写首字母

如何摆脱告诉我将 svg 属性更改为驼峰式大小写的反应错误警告?

JsonSerializerSettings 更改属性名称的大小写,但不更改属性的名称