標籤:
1、動態決定資料是否要序列化
我的需求是這樣的,我用了一款資料庫的組件叫Dos.ORM,確實方便了不少,但是在用的時候,我發現一個問題,比如我定義的表中有一個欄位添加時間,修改時間,這些都是預設的,在添加的時候,不需要賦值,但是我從前端傳過來,就會是一個DateTime.MinValue。我不希望去更改它。但是我從資料庫裡面查詢欄位的時候,我又希望擷取這些資料。所以不能簡單的在Model上面加上是否序列化的屬性。
下面是我的JsonHelper類
using Help.DataService.Business.Common;using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Help.DataService.Business{ public static class JsonHelper { public static string SerializeObject(object param) { if (param != null) { return JsonConvert.SerializeObject(param); } return string.Empty; } public static T DeserializeObject<T>(string json) where T : class { if (!string.IsNullOrEmpty(json)) { return JsonConvert.DeserializeObject<T>(json); } return default(T); } public static RESULT ParseModel<INPUT, RESULT>(INPUT data) where INPUT : class where RESULT : class { if (data == null) { return null; } var jSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; string[] props = { "ModifyTime", "AddTime" }; jSetting.ContractResolver = new LimitPropsContractResolver(props, false); string json = JsonConvert.SerializeObject(data, jSetting); if (!string.IsNullOrEmpty(json)) { // 空值和預設值,就不需要還原序列化,Dos.ORM組件裡面如果DateTime為0001-01-01的話,操作資料庫會不成功 return JsonConvert.DeserializeObject<RESULT>(json, jSetting); } return default(RESULT); } public static R ParseViewModel<I, R>(I data) where I : class where R : class { string json = SerializeObject(data); return DeserializeObject<R>(json); } }}
LimitPropsContractResolver類的代碼如下:
using Newtonsoft.Json.Serialization;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;namespace Help.DataService.Business.Common{ /// <summary> /// 動態決定屬性是否序列化 /// </summary> public class LimitPropsContractResolver : DefaultContractResolver { /// <summary> /// 屬性列表 /// </summary> private string[] props = null; /// <summary> /// 是否包含 /// </summary> private bool retain; /// <summary> /// 建構函式 /// </summary> /// <param name="props">props</param> /// <param name="isretain">isretain(包含還是排除)</param> public LimitPropsContractResolver(string[] props, bool isretain = true) { this.props = props; this.retain = isretain; } protected override IList<JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization) { IList<JsonProperty> list = base.CreateProperties(type, memberSerialization); if (props == null || props.Length == 0) { return list; } // 只列出清單保留的屬性 var ret = list.Where(p => { if (retain) { return this.props.Contains(p.PropertyName); } else { return !this.props.Contains(p.PropertyName); } }).ToList(); return ret; } }}
2、用C#調java的服務。
結果報錯為資料沒有查到,想不通,後來調試java代碼發現,又是還原序列化問題。因為C#的代碼是第一個字母大寫,java代碼是第一個字母小寫,這樣就導致還原序列化之後,java完全沒有擷取到任何參數,雖然C#已經傳遞過去了。在不改變java代碼的前提下,我只能改C#代碼了。好在有現成的方法,不過不是很常用,如下:
CamelCasePropertyNamesContractResolver cal = new CamelCasePropertyNamesContractResolver();JsonSerializerSettings setting = new JsonSerializerSettings();setting.ContractResolver = cal;string json = JsonConvert.SerializeObject(vo, setting);
3、相關資料
Newtonsoft.Json進階用法
C#Json序列化和還原序列化