【问题标题】:C# JSON.NET convention that follows Ruby property naming conventions?遵循 Ruby 属性命名约定的 C# JSON.NET 约定?
【发布时间】:2010-10-13 10:53:01
【问题描述】:

我正在使用http://json.codeplex.com/,并且正在与基于 Ruby 的 Rest API 交谈。问题是大多数属性都有一个 ruby​​ 下划线命名约定。我想知道是否有人知道一种方法,这样我就可以避免添加大量 JsonProperty。

例如,我想避免添加 JsonProperty 属性并在序列化程序设置中内置一个约定,以便它知道尝试将带有下划线的属性映射到 .NET 命名约定:)

public class Member
{
    [JsonProperty(PropertyName = "avatar_url")]
    public string AvatarUrl { get; set; }

    [JsonProperty(PropertyName = "twitter_screen_name")]
    public string TwitterScreenName { get; set; }

    [JsonProperty(PropertyName = "website_url")]
    public string WebSiteUrl { get; set; }
}

【问题讨论】:

    标签: c# ruby api json.net


    【解决方案1】:

    更新 - 2016 年 9 月:

    Json.NET 9.0.1 有 SnakeCaseNamingStrategy。您可以使用它来自动拥有 twitter_screen_name 样式属性。


    DefaultContractResolver 继承并覆盖 ResolvePropertyName 以根据需要格式化属性名称。

    CamelCasePropertyNamesContractResolver 对属性名称进行了类似的全局更改。

    【讨论】:

    • 感谢 James 试一试,并将我的发现发布在这里,以供可能遇到这种情况的其他人使用。
    • 仅供参考,通常使用命名策略的合约解析器可能存在巨大的性能问题。使用一个 (90TPS) 与不使用 (600TPS) 时吞吐量大幅下降。
    • 重用合约解析器。每次创建一个新的都会强制反射在每次序列化/反序列化时发生。
    【解决方案2】:

    阅读:http://nyqui.st/json-net-newtonsoft-json-lowercase-keys

    public class UnderscoreMappingResolver : DefaultContractResolver 
        {
            protected override string ResolvePropertyName(string propertyName)
            {
                return System.Text.RegularExpressions.Regex.Replace(
                    propertyName, @"([A-Z])([A-Z][a-z])|([a-z0-9])([A-Z])", "$1$3_$2$4").ToLower(); 
            }
        }
    

    【讨论】:

    • 这不适用于具有两个连续大写字母的属性。 ThisIsATest 变为 this_is_atest
    【解决方案3】:

    从版本 9 开始,存在一个新的命名策略属性来执行此操作,并且它具有内置的 SnakeCaseNamingStrategy 类。使用下面的代码将contractResolver注册为SerializerSettings.ContractResolver

    var contractResolver = new DefaultContractResolver();
    contractResolver.NamingStrategy = new SnakeCaseNamingStrategy();
    

    默认情况下,该类不包括字典,也不会覆盖任何手动设置的属性值。这些是可以在重载中传递的两个参数:

    // true parameter forces handling of dictionaries
    // false prevents the serializer from changing anything manually set by an attribute
    contractResolver.NamingStrategy = new SnakeCaseNamingStrategy(true, false);
    

    【讨论】:

      【解决方案4】:

      这个对我有用

      var settings = new JsonSerializerSettings
      {
          ContractResolver = new PascalCaseToUnderscoreContractResolver()
      };
      var rawJson = "{ test_property:'test' }"
      var myObject = JsonConvert.DeserializeObject<MyObjectType>(rawJson, settings);
      

      使用 Humanizer 函数“下划线”

      https://www.nuget.org/packages/Humanizer/1.37.7

      http://humanizr.net/#underscore

      public class PascalCaseToUnderscoreContractResolver : DefaultContractResolver
      {
          protected override string ResolvePropertyName(string propertyName) => propertyName.Underscore();
      }
      

      MyObjectType 类

      public Class MyObjectType
      {
          public string TestProperty {get;set;}
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-21
        • 1970-01-01
        • 2012-12-03
        • 1970-01-01
        • 2010-11-18
        • 1970-01-01
        • 1970-01-01
        • 2012-02-16
        相关资源
        最近更新 更多