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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM