public partial class ModelStatusDictionary<T> where T : new() { static readonly DynamicMethod<T> _dynamicMethod = new DynamicMethod<T>(); /// <summary> /// 判断指定特性的属性 /// </summary> /// <param name="obj">对象</param> /// <param name="NonStance">是否获取基类的属性</param> /// <param name="NonProperty">排除的属性</param> /// <returns></returns> public static (bool state, string message) ModelVerified(T obj, bool NonStance = true, ICollection<string> NonProperty = null) { bool isEmpty = true; string msge = string.Empty; var ps = typeof(T).GetProperties(); if (!NonStance) ps = typeof(T).GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); if (NonProperty != null) ps = ps.Where(x => !NonProperty.Contains(x.Name)).ToArray(); var vModel = (from p in ps where p.GetCustomAttribute<DisplayNameAttribute>(true) != null select new { name = p.Name, dname = p.GetCustomAttribute<DisplayNameAttribute>(true).DisplayName, velue = _dynamicMethod.GetValue(obj, p.Name), }).Distinct().ToList(); var fiel = vModel.Where(x => !Isfield(x.velue)).ToList(); if (fiel.Count > 0) { isEmpty = false; msge = $"{string.Join(",", fiel.Select(x => x.dname).ToList())},Required fields cannot be empty!"; } return (isEmpty, msge); } /// <summary> /// 两个类型一样的对象做比较 /// </summary> /// <param name="model">A</param> /// <param name="modelData">B</param> public static (bool state, List<ModelEqualDictionary> dictionary) ModelEquals(T lastModel, T newModel) { bool isEquals = true; var ps = typeof(T).GetProperties(); var _last = GetObject(ps, lastModel);// (from p in ps var _new = GetObject(ps, newModel); var fields = _new.Except(_last).Where(x => !string.IsNullOrWhiteSpace(x.dname)).Select(x => new ModelEqualDictionary() { DisplayName = x.dname, LostValue = _last.Where(y => y.name == x.name).FirstOrDefault().value, NewValue = x.value }).ToList(); if (fields != null) if (fields.Any()) isEquals = false; return (isEquals, fields); } static IEnumerable<dynamic> GetObject(PropertyInfo[] property, object model) { if (model == null) { model = new T(); } var dy = (from p in property where p.GetCustomAttribute<DisplayNameAttribute>(true) != null select new { name = p.Name, dname = p.GetCustomAttribute<DisplayNameAttribute>(true).DisplayName, value = GetModelValue(model, p), }); return dy; } /// <summary> /// 两个类型一样的对象做比较 /// </summary> /// <param name="model">A</param> /// <param name="modelData">B</param> /// <param name="noProperty">C</param> public static (bool state, List<ModelEqualDictionary> dictionary) ModelEqual(T lastModel, T newModel,bool nonProperty = false,ICollection<string> NonProperty = null) { bool isEquals = true; var ps = typeof(T).GetProperties(); if (NonProperty != null) { ps = ps.Where(x => !NonProperty.Contains(x.Name)).ToArray(); } var _last = nonProperty ? GetNonPropertyModel(ps,lastModel): GetModel(ps, lastModel); var _new = nonProperty ? GetNonPropertyModel(ps, newModel) : GetModel(ps, newModel); var fields = _new.Except(_last).Select(x => new ModelEqualDictionary() { DisplayName = x.dname, LostValue = _last.Where(y => y.name == x.name).FirstOrDefault().value, NewValue = x.value }).ToList(); if (fields != null) if (fields.Any()) isEquals = false; return (isEquals, fields); } static IEnumerable<dynamic> GetNonPropertyModel(PropertyInfo[] property, object model) { var a = property.Where(p => p.GetCustomAttribute<IsRequiredAttribute>(true) != null).ToList(); var dy = (from p in property where p.GetCustomAttribute<IsRequiredAttribute>(true) != null select new { name = p.Name, dname = p.GetCustomAttribute<IsRequiredAttribute>(true).IsRequired, value = GetModelValue(model, p), }); return dy; } static IEnumerable<dynamic> GetModel(PropertyInfo[] property, object model) { var a = property.Where(p => p.GetCustomAttribute<IsRequiredAttribute>(true) != null).ToList(); var dy = (from p in property where p.GetCustomAttribute<IsRequiredAttribute>(true) != null select new { name = p.Name, dname = p.GetCustomAttribute<IsRequiredAttribute>(true).IsRequired, value = GetModelValue(model, p), }); return dy; } static object GetModelValue(object obj, PropertyInfo property) { object value = string.Empty; if (getPropertyType(property.PropertyType) == typeof(Nullable)) { var nextObj = obj.GetType().GetProperty(property.Name).GetValue(obj, null); if (property.PropertyType.BaseType.Name == "Enum") { value = nextObj; } else if (nextObj != null) { if (getPropertyType(nextObj.GetType()) == typeof(DateTime)) { value = nextObj; } else { var ps = nextObj.GetType().GetProperties(); var thisObj = GetObject(ps, nextObj); value = string.Join(",", thisObj ?? thisObj.Select(x => x.value).ToList()); } } } else { value = obj.GetType().GetProperty(property.Name).GetValue(obj, null); } return value; } static bool Isfield(object value) { if (value == null) return false; var val = value.GetType().ToString(); switch (val) { case "System.Boolean": return value == null ? false : true; case "System.Byte": return value == null ? false : true; case "System.SByte": return value == null ? false : true; case "System.Char": return string.IsNullOrWhiteSpace(value.ToString()) ? false : true; case "System.Decimal": return value == null ? false : true; case "System.Double": return value == null ? false : true; case "System.Single": return value == null ? false : true; case "System.Int32": return value == null ? false : true; case "System.UInt32": return value == null ? false : true; case "System.Int64": return value == null ? false : true; case "System.UInt64": return value == null ? false : true; case "System.Object": return value == null ? false : true; case "System.Int16": return value == null ? false : true; case "System.UInt16": return value == null ? false : true; case "System.String": return string.IsNullOrWhiteSpace(value.ToString()) ? false : true; case "System.DateTime.Date": return value == null ? false : true; case "System.DateTime": return value == null ? false : true; case "System.Guid": return value == null ? false : true; default: return true; } } static Type getPropertyType(Type obj) { if (obj == null) return typeof(DBNull); var val = obj.ToString(); switch (val) { case "System.Boolean": return typeof(Boolean); case "System.Byte": return typeof(Byte); case "System.SByte": return typeof(SByte); case "System.Char": return typeof(char); case "System.Decimal": return typeof(Decimal); case "System.Double": return typeof(Double); case "System.Single": return typeof(Single); case "System.Int32": return typeof(Int32); case "System.UInt32": return typeof(UInt32); case "System.Int64": return typeof(Int64); case "System.UInt64": return typeof(UInt64); case "System.Object": return typeof(Object); case "System.Int16": return typeof(Int16); case "System.UInt16": return typeof(UInt16); case "System.String": return typeof(string); case "System.DateTime.Date": return typeof(DateTime); case "System.DateTime": return typeof(DateTime); case "System.Guid": return typeof(Guid); case "System.Enum": return typeof(Enum); default: return typeof(Nullable); } } } public class ModelEqualDictionary { public string DisplayName { get; set; } public object LostValue { get; set; } public object NewValue { get; set; } }