zoukankan      html  css  js  c++  java
  • Json.NET 利用ContractResolver解决命名不一致问题

    今天在遇到这么个问题,项目上有一部分功能需要访问web api, 这个api请求和相应的数据格式都是使用JSON,JSON中的field命名方式是以下划线分割的,比如"project_name", "account_id"等等。但是在C#中命名方式一般都为Camel-Case,这样如果使用Json.NET的默认设置序列化和反序列化对象的话就造成属性名不一致的情况。

    这时,我们就可以通过Json.NET中的ContractResolver来实现实现属性的映射,比如将ProjectName映射为project_name:

    public class UnderlineSplitContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return CamelCaseToUnderlineSplit(propertyName);
        }
    
        private string CamelCaseToUnderlineSplit(string name)
        {
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < name.Length; i++)
            {
                var ch = name[i];
                if (char.IsUpper(ch) && i > 0)
                {
                    var prev = name[i - 1];
                    if (prev != '_')
                    {
                        if (char.IsUpper(prev))
                        {
                            if (i < name.Length - 1)
                            {
                                var next = name[i + 1];
                                if (char.IsLower(next))
                                {
                                    builder.Append('_');
                                }
                            }
                        }
                        else
                        {
                            builder.Append('_');
                        }
                    }
                }
    
                builder.Append(char.ToLower(ch));
            }
    
            return builder.ToString();
        }
    }

    代码中我继承了Json.NET中的DefaultContractResolver类,并且重写了ResolvePropertyName方法,在方法内部将以Camel-Case方式命名的属性名转换为以下划线分割的方式。

    接着,使用UnderlineSplitContractResolver替代默认的DefaultContractRelover就可以达到想要的效果:

    var settings = new JsonSerializerSettings
    { 
        ContractResolver = new UnderlineSplitContractResolver() 
    };
    
    var project = new Project(){ ProjectName = "test" };
    var json = JsonConvert.SerializeObject(project, settings);
    Console.WriteLine(json); //{ “project_name”: "test" }
    
    project = JsonConvert.DeserializeObject<Project>(json, settings);
    Console.WriteLine(project.ProjectName); //test

    通过无论是序列化还是反序列化都达到了效果,即:ProjectName -> project_name 和 project_name -> ProjectName

  • 相关阅读:
    Shell编程之数值运算(二) Theletter
    Shell编程检测某个服务是否运行实例 Theletter
    Shell编程之条件测试与比较(详解) Theletter
    eclipse中svn提交时报Previous operation has not finished; run 'cleanup' if it was interrupted错误的解决方法
    Jsp连接打印机
    Jsp中table导出到excel
    java创建图片验证码
    java利用映射表名称反射创建实体类并赋属性值
    基于方法的LINQ语句
    opencv中cvCreateImage大图片时出错
  • 原文地址:https://www.cnblogs.com/hao-dotnet/p/4229825.html
Copyright © 2011-2022 走看看