今天在遇到這麼個問題,項目上有一部分功能須要訪問web api, 這個api請求和相應的數據格式都是使用JSON,JSON中的field命名方式是如下劃線分割的,好比"project_name", "account_id"等等。可是在C#中命名方式通常都爲Camel-Case,這樣若是使用Json.NET的默認設置序列化和反序列化對象的話就形成屬性名不一致的狀況。web
這時,咱們就能夠經過Json.NET中的ContractResolver來實現實現屬性的映射,好比將ProjectName映射爲project_name:json
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方式命名的屬性名轉換爲如下劃線分割的方式。api
接着,使用UnderlineSplitContractResolver替代默認的DefaultContractRelover就能夠達到想要的效果:ide
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 -> ProjectNameui