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);