前言
專案開發中不管是前臺還是后臺都會遇到煩人的null,資料庫表中欄位允許空值,則代碼物體類中對應的欄位型別為可空型別Nullable<>,如int?,DateTime?,null值欄位序列化回傳的值都為null,前臺對應欄位賦值需要做null值判斷,怎么才能全域把null替換為空,
本文分享WebAPI介面服務統一回傳null替換為空的方法,
一、分析問題
.NET Core中使用Newtonsoft.Json進行序列化,WebAPI介面回傳格式通過Startup.cs類全域設定,想是否可以通過配置把null替換為空值?于是找到了Newtonsoft.Json在序列化和反序列化期間如何處理空值和默認值的屬性,具體配置代碼如下:
1 public void ConfigureServices(IServiceCollection services) 2 { 3 //配置Mvc + json 序列化 4 services.AddMvc() 5 .AddNewtonsoftJson(options => 6 { 7 //資料格式首字母小寫 不使用駝峰 小駝峰firstName 大駝峰 FirstName 8 options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 9 //使用默認方式,不更改元資料的key的大小寫 10 //options.SerializerSettings.ContractResolver = new DefaultContractResolver(); 11 // 忽略回圈參考 12 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 13 // 設定時間格式 14 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 15 //忽略空值 不包含屬性的null序列化 16 //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 17 //忽略默認值和null 1、不包含屬性默認值和null 18 //options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Igno 19 }) 20 }
1、空值的處理
序列化和反序列化時需要忽略值為null的屬性,設定SerializerSettings.NullValueHandling的值
- NullValueHandling.Ignore 序列化和反序列化物件時忽略空值,
- NullValueHandling.Include 序列化和反序列化物件時包含空值,
2、默認值的處理
序列化和反序列化時需要忽略默認值屬性,設定SerializerSettings.DefaultValueHandling的值
- DefaultValueHandling.Ignore 序列化和反序列化時忽略默認值
- DefaultValueHandling.Include序列化和反序列化時包含默認值
3、示例代碼
1 /*包含屬性的默認值與null序列化*/ 2 { 3 "Name": null, 4 "Age": 0, 5 "Partner": null, 6 "Salary": 0.0 7 } 8 /*不包含屬性的默認值序列化*/ 9 { 10 "Name": "Hello World", 11 "Age": 28 12 } 13 /*不包含屬性的null序列化*/ 14 { 15 "Name": "Hello World", 16 "Age": 28, 17 "Salary": 0.0 18 }
通過上面的分析:一種是不包含屬性的默認值序列化,另一種是不包含屬性的null序列化,都不能滿足目前的需求介面統一回傳的null序列化為空,
二、解決問題
1、專案WebAPI默認回傳的JSON結果格式如下:
1 { 2 "code": 0, 3 "msg": "查詢成功", 4 "data": { 5 "id": 1, 6 "title": "炎炎夏日暖暖肚", 7 "describe": "", 8 "author": null, 9 "authorId": null, 10 "linkSource": null, 11 "author_Picture": null, 12 "content": "炎炎夏日,很多人喜歡吃些寒涼的食物解暑,可這種做法非常傷身,", 13 } 14 }
2、需要解決的問題把所有的null替換為空,具體如下圖所示:

3、解決方案
需要自己寫一個NullToEmptyStringResolver類,然后重寫CamelCasePropertyNamesContractResolver,但是該方法只能解決string型別null→""的問題,對其他可空型別無效,比如:int?、DateTime?等,
1 public class NullToEmptyStringResolver : CamelCasePropertyNamesContractResolver 2 { 3 /// <summary> 4 /// 創建屬性 5 /// </summary> 6 /// <param name="type">型別</param> 7 /// <param name="memberSerialization">序列化成員</param> 8 /// <returns></returns> 9 protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 10 { 11 return type.GetProperties().Select(c => 12 { 13 var jsonProperty = base.CreateProperty(c, memberSerialization); 14 jsonProperty.ValueProvider = new NullToEmptyStringValueProvider(c); 15 return jsonProperty; 16 }).ToList(); 17 } 18 } 19 20 public class NullToEmptyStringValueProvider : IValueProvider 21 { 22 private readonly PropertyInfo _memberInfo; 23 /// <summary> 24 /// 建構式 25 /// </summary> 26 /// <param name="memberInfo"></param> 27 public NullToEmptyStringValueProvider(PropertyInfo memberInfo) 28 { 29 _memberInfo = memberInfo; 30 } 31 32 /// <summary> 33 /// 獲取Value 34 /// </summary> 35 /// <param name="target"></param> 36 /// <returns></returns> 37 public object GetValue(object target) 38 { 39 var result = _memberInfo.GetValue(target); 40 if (_memberInfo.PropertyType == typeof(string) && result == null) 41 result = string.Empty; 42 return result; 43 } 44 45 /// <summary> 46 /// 設定Value 47 /// </summary> 48 /// <param name="target"></param> 49 /// <param name="value"></param> 50 public void SetValue(object target, object value) 51 { 52 _memberInfo.SetValue(target, value); 53 } 54 }
在Startup.cs代碼里面修改,標記為紅色的代碼,如下所示:
1 //配置MVC+JSON序列化 2 services 3 .AddMvc(options =>{options.EnableEndpointRouting = false;}) 4 .AddNewtonsoftJson(options => 5 { 6 //使用默認方式,不更改元資料的key的大小寫 7 //options.SerializerSettings.ContractResolver = new DefaultContractResolver(); 8 //資料格式首字母小寫 不使用駝峰 小駝峰firstName 大駝峰 FirstName 9 //options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 10 options.SerializerSettings.ContractResolver = new NullToEmptyStringResolver(); 11 // 忽略回圈參考 12 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; 13 // 設定時間格式 14 options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss"; 15 //忽略空值 不包含屬性的null序列化 16 //options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; 17 //忽略默認值和null 1、不包含屬性默認值和null 18 //options.SerializerSettings.DefaultValueHandling = DefaultValueHandling.Igno 19 })
修改完配置,重新運行完成,實作null替換為空的效果,運行結果如下所示:
1 { 2 "code": 0, 3 "msg": "查詢成功!", 4 "data": { 5 "id": 1, 6 "title": "炎炎夏日暖暖肚", 7 "describe": "", 8 "author": "", 9 "authorId": "", 10 "linkSource": "", 11 "author_Picture": "", 12 "source": 0, 13 "content": "炎炎夏日,很多人喜歡吃些寒涼的食物解暑,可這種做法非常傷身," 14 } 15 }
三、總結
.NET Core下Newtonsoft.Json序列化時字串null替換成空,通過ContractResolver類為屬性添加一些序列化設定、自定義屬性名、設定時間格式、有選擇性的序列化屬性等,實作WebAPI回傳JSON格式統一化,
優秀是一種習慣,歡迎大家關注學習

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/247904.html
標籤:.NET技术
