【问题标题】:Default camel case of property names in JSON serializationJSON序列化中属性名称的默认驼峰式大小写
【发布时间】: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 处理属性名称的默认方式,以便除非另有说明,否则它将自动使用驼峰式大小写?

【问题讨论】:

    标签: c# json json.net camelcasing


    【解决方案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
            猜你喜欢
            • 1970-01-01
            • 2014-10-22
            • 1970-01-01
            • 1970-01-01
            • 2015-07-29
            • 1970-01-01
            • 2020-10-12
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多