带有下划线的Newton CamelCase问题 [英] Newton CamelCase Issue with underscore

查看:55
本文介绍了带有下划线的Newton CamelCase问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,当我序列化具有HTTP_VERB键的C#字典时,它会在JSON结构而不是hTTP_VERB或http_verb中变成 httP_VERB ,我希望骆驼的情况会成功.

I've notice that when I serialize C# dictionary which has key of HTTP_VERB it turn into httP_VERB in the JSON structure instead of hTTP_VERB or http_verb I expected the camel case will make it.

这是我用来重现此问题的代码:

This is the code I use to reproduce the issue:

  class Program {
    static void Main(string[] args) {

      var settings = new JsonSerializerSettings();

      settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
      settings.NullValueHandling = NullValueHandling.Ignore;

      var headers = new Dictionary<string, string>();
      headers["SessionID"] = "123456";
      headers["HTTP_VERB"] = "POST";
      headers["HTTPVERSION"] = "1";
      var data = new
      {
        headers = headers
      };

      string serializedEvent = JsonConvert.SerializeObject(data, settings);

      if (serializedEvent.Contains("httP_VERB")) {
        Console.WriteLine("Something is wrong with this camel case");
      }
      else {
        Console.WriteLine("Sucess");
      }

    }
  }

推荐答案

无法通过CamelCasePropertyNamesContractResolver方式将字符串转换为驼峰式大小写,但是您可以轻松编写自己的ContractResolver.

There's no way to make CamelCasePropertyNamesContractResolver convert strings to camel case the way you want, but you can easily write your own ContractResolver.

我在 CsCss 项目中使用了PascalCase转换.经过一点调整,结果如下:

I've used PascalCase conversion in my CsCss project. After a bit of adaptation, here's the result:

public enum IdentifierCase
{
    Camel,
    Pascal,
}

public class CustomPropertyNamesContractResolver : DefaultContractResolver
{
    private static readonly CultureInfo Culture = CultureInfo.InvariantCulture;

    public CustomPropertyNamesContractResolver (bool shareCache = false)
        : base(shareCache)
    {
        Case = IdentifierCase.Camel;
        PreserveUnderscores = true;
    }

    public IdentifierCase Case { get; set; }
    public bool PreserveUnderscores { get; set; }

    protected override string ResolvePropertyName (string propertyName)
    {
        return ChangeCase(propertyName);
    }

    private string ChangeCase (string s)
    {
        var sb = new StringBuilder(s.Length);

        bool isNextUpper = Case == IdentifierCase.Pascal, isPrevLower = false;
        foreach (var c in s) {
            if (c == '_') {
                if (PreserveUnderscores)
                    sb.Append(c);
                isNextUpper = true;
            }
            else {
                sb.Append(isNextUpper ? char.ToUpper(c, Culture) : isPrevLower ? c : char.ToLower(c, Culture));
                isNextUpper = false;
                isPrevLower = char.IsLower(c);
            }
        }
        return sb.ToString();
    }

    // Json.NET implementation for reference
    private static string ToCamelCase (string s)
    {
        if (string.IsNullOrEmpty(s) || !char.IsUpper(s[0]))
            return s;
        var sb = new StringBuilder();
        for (int i = 0; i < s.Length; ++i) {
            if (i == 0 || i + 1 >= s.Length || char.IsUpper(s[i + 1]))
                sb.Append(char.ToLower(s[i], Culture));
            else {
                sb.Append(s.Substring(i));
                break;
            }
        }
        return sb.ToString();
    }
}

此转换器同时支持PascalCasecamelCase.似乎可以按照您期望的方式转换属性名称.

This converter supports both PascalCase and camelCase. It seems to convert the property names the way you expect.

我已经从Json.NET留下了原始的ToCamelCase函数以供参考.

I've left oroginal ToCamelCase function from Json.NET for reference.

示例程序:

internal class Program
{
    private static void Main ()
    {
        var obj = new Dictionary<string, string> {
            { "SessionID", "123456" },
            { "HTTP_VERB", "POST" },
            { "HTTPVERSION", "1" },
        };
        var settings = new JsonSerializerSettings {
            Formatting = Formatting.Indented,
            ContractResolver = new CustomPropertyNamesContractResolver()
        };
        string strCamel = JsonConvert.SerializeObject(obj, settings);
        Console.WriteLine("camelCase: \n" + strCamel);
        Console.WriteLine(strCamel.Contains("httP_VERB") ? "Something is wrong with this camel case" : "Success");
        settings.ContractResolver = new CustomPropertyNamesContractResolver {
            Case = IdentifierCase.Pascal,
            PreserveUnderscores = false,
        };
        string strPascal = JsonConvert.SerializeObject(obj, settings);
        Console.WriteLine("PascalCase: \n" + strPascal);
        Console.ReadKey();
    }
}

输出:

camelCase:
{
  "sessionId": "123456",
  "http_Verb": "POST",
  "httpversion": "1"
}
Success
PascalCase:
{
  "SessionId": "123456",
  "HttpVerb": "POST",
  "Httpversion": "1"
}

这篇关于带有下划线的Newton CamelCase问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆