Winform及WPF项目中经常会用到类似SystemSetting.xml等类似的文件用于保存CLIENT的数据,比如登录过的用户名或密码以及其他设置。所以就想到一个解决方法,可以用到所有有此需求的项目中去,避免重复写代码。
1.创建一个Attribute类,用于指定属性在XML文件中的Path
public class NodePathAttribute : Attribute { public string NodePath { get; set; } public string DefaultValue { get; set; } public NodePathAttribute(string nodePath) { NodePath = nodePath; } public NodePathAttribute(string nodePath,string defaultValue) :this(nodePath) { DefaultValue = defaultValue; } }
2.SystemSetting类用于定义要读取和保存的属性,SystemSetting继续XMLSettingBase
1 namespace ConsoleApplication2 2 { 3 public class SystemSetting : XMLSettingBase 4 { 5 #region Property 6 7 #region HostLocationSetting 8 9 /// <summary> 10 /// host wcf service location 11 /// </summary> 12 [NodePath("/Settings/HostLocationSetting/HostLocation")] 13 public string HostLocation { get; set; } 14 15 /// <summary> 16 /// host wcf service port 17 /// </summary> 18 [NodePath("/Settings/HostLocationSetting/HostPort")] 19 public int? HostPort { get; set; } 20 21 #endregion 22 23 #region SystemFolderSetting 24 25 /// <summary> 26 /// NiceLable sdk niceengine5wr.dll path 27 /// </summary> 28 [NodePath("/Settings/SystemFolderSetting/NiceEngineFolderPath")] 29 public string NiceEngineFolderPath 30 { 31 get; 32 set; 33 } 34 35 #endregion 36 37 #region SearchSetting 38 39 /// <summary> 40 /// Main program 41 /// </summary> 42 [NodePath("/Settings/SearchSetting/MainProgram")] 43 public string MainProgram 44 { 45 get; 46 set; 47 } 48 49 /// <summary> 50 /// Sub program 51 /// </summary> 52 [NodePath("/Settings/SearchSetting/SubProgram")] 53 public string SubProgram 54 { 55 get; 56 set; 57 } 58 59 /// <summary> 60 /// Get/Set Date Range to auto setting and search condition 61 /// </summary> 62 [NodePath("/Settings/SearchSetting/DateRange")] 63 public int? DateRange 64 { 65 get; 66 set; 67 } 68 69 /// <summary> 70 /// Get/Set Date Range unit 0:days;1:weeks;2:months;3:years 71 /// </summary> 72 [NodePath("/Settings/SearchSetting/DateRangeUnit")] 73 public int? DateRangeUnit 74 { 75 get; 76 set; 77 } 78 79 /// <summary> 80 /// search status 81 /// </summary> 82 [NodePath("/Settings/SearchSetting/Status")] 83 public FileStatus? Status 84 { 85 get; 86 set; 87 } 88 89 /// <summary> 90 /// Skip printed order 91 /// </summary> 92 [NodePath("/Settings/SearchSetting/SkipPrintedOrder")] 93 public bool? SkipPrintedOrder 94 { 95 get; 96 set; 97 } 98 99 #endregion 100 101 #region PrintSetting 102 103 [NodePath("/Settings/PrintSetting/ReturnQCResult")] 104 public bool? ReturnQCResult { get; set; } 105 106 [NodePath("/Settings/PrintSetting/ActualPrintQuantity")] 107 public bool? ActualPrintQuantity { get; set; } 108 109 [NodePath("/Settings/PrintSetting/MOSeperator")] 110 public bool? MOSeperator { get; set; } 111 112 [NodePath("/Settings/PrintSetting/SKUSeperator")] 113 public string SKUSeperator { get; set; } 114 115 #endregion 116 117 #region LoginSetting 118 119 [NodePath("/Settings/LoginSetting/UserName")] 120 public string UserName { get; set; } 121 122 [NodePath("/Settings/LoginSetting/Password")] 123 public string Password { get; set; } 124 125 [NodePath("/Settings/LoginSetting/Language")] 126 public string Language { get; set; } 127 128 #endregion 129 130 #endregion 131 132 #region Ctor 133 134 public SystemSetting(string filePath) 135 :base(filePath) 136 { 137 138 } 139 140 #endregion 141 } 142 }
public class XMLSettingBase { #region Field protected string _filePath = null; protected XmlDocument _xmlDocument = null; public delegate void SettingChange(); #endregion #region Ctor public XMLSettingBase(string filePath) { _filePath = filePath; _xmlDocument = new XmlDocument(); _xmlDocument.Load(filePath); } #endregion #region Event public event SettingChange OnSettingChangeEvent; #endregion #region Method /// <summary> /// init system setting /// </summary> public void LoadData() { PropertyInfo[] propertyInfoes = this.GetType().GetProperties(); if (propertyInfoes == null && propertyInfoes.Length == 0) { return; } //load each setting value foreach (var propertyInfo in propertyInfoes) { NodePathAttribute customerAttribute = propertyInfo.GetCustomAttribute<NodePathAttribute>(); if (customerAttribute == null) { continue; } string propertyValue = string.Empty; if (_xmlDocument.SelectSingleNode(customerAttribute.NodePath) != null) { propertyValue = GetXmlNodeValue(customerAttribute.NodePath); } else { CreateNode(customerAttribute.NodePath); propertyValue = customerAttribute.DefaultValue; } //whether need to decrypt value EncryptAttribute encryptAttribute = propertyInfo.GetCustomAttribute<EncryptAttribute>(); if (encryptAttribute == null) { SetPropertyInfoValue(propertyInfo, this, propertyValue); } else { SetPropertyInfoValue(propertyInfo, this, Decrypt(propertyValue, encryptAttribute.EncryptPassword)); } } LoadExtendData(); } public virtual void LoadExtendData() { return; } /// <summary> /// save data to xml file. /// </summary> public void SaveData() { PropertyInfo[] propertyInfoes = this.GetType().GetProperties(); if (propertyInfoes == null && propertyInfoes.Length == 0) { return; } //load each setting value foreach (var propertyInfo in propertyInfoes) { NodePathAttribute customerAttribute = propertyInfo.GetCustomAttribute<NodePathAttribute>(); if (customerAttribute == null) { continue; } object propertyValue = propertyInfo.GetValue(this); //whether need to decrypt value EncryptAttribute encryptAttribute = propertyInfo.GetCustomAttribute<EncryptAttribute>(); if (encryptAttribute == null) { SetXmlNodeValue(customerAttribute.NodePath, propertyValue != null ? propertyValue.ToString() : string.Empty); } else { SetXmlNodeValue(customerAttribute.NodePath, propertyValue != null ? Encrypt(propertyValue.ToString(), encryptAttribute.EncryptPassword) : string.Empty); } } _xmlDocument.Save(_filePath); } /// <summary> /// refresh system setting /// </summary> public void Refresh() { //save data SaveData(); //reload the data. LoadData(); //triggering event if (OnSettingChangeEvent != null) { OnSettingChangeEvent(); } } public string GetXmlNodeValue(string strNode) { try { XmlNode xmlNode = _xmlDocument.SelectSingleNode(strNode); return xmlNode.InnerText; } catch (Exception ex) { throw ex; } } public void SetXmlNodeValue(string strNode, string value) { try { XmlNode xmlNode = _xmlDocument.SelectSingleNode(strNode); xmlNode.InnerText = value; } catch (Exception ex) { throw ex; } } /// <summary> /// convert the datatable to list /// </summary> /// <param name="dt"></param> /// <returns></returns> private void SetPropertyInfoValue(PropertyInfo propertyInfo, object obj, object value) { //check value if (value == null || string.IsNullOrWhiteSpace(value.ToString())) { return; } string strValue = value.ToString(); if (propertyInfo.PropertyType.IsEnum) { propertyInfo.SetValue(obj, Enum.Parse(propertyInfo.PropertyType, strValue), null); } else { string propertyTypeName = propertyInfo.PropertyType.Name; switch (propertyTypeName) { case "Int32": case "Int64": case "Int": int intValue; int.TryParse(strValue, out intValue); propertyInfo.SetValue(obj, intValue, null); break; case "Long": long longValue; long.TryParse(strValue, out longValue); propertyInfo.SetValue(obj, longValue, null); break; case "DateTime": DateTime dateTime; DateTime.TryParse(strValue, out dateTime); propertyInfo.SetValue(obj, dateTime, null); break; case "Boolean": Boolean bv = false; if ("1".Equals(value) || "true".Equals(strValue.ToLower())) { bv = true; } propertyInfo.SetValue(obj, bv, null); break; case "Nullable`1": if (propertyInfo.PropertyType.GenericTypeArguments[0].IsEnum) { propertyInfo.SetValue(obj, Enum.Parse(propertyInfo.PropertyType.GenericTypeArguments[0], strValue), null); } else { switch (propertyInfo.PropertyType.GenericTypeArguments[0].FullName) { case "System.Int32": case "System.Int64": case "System.Int": int intV; int.TryParse(strValue, out intV); propertyInfo.SetValue(obj, intV, null); break; case "System.DateTime": DateTime dtime; DateTime.TryParse(strValue, out dtime); propertyInfo.SetValue(obj, dtime, null); break; case "System.Boolean": Boolean boolv = false; if ("1".Equals(value) || "true".Equals(strValue.ToLower())) { boolv = true; } propertyInfo.SetValue(obj, boolv, null); break; default: propertyInfo.SetValue(obj, strValue, null); break; } } break; default: propertyInfo.SetValue(obj, strValue, null); break; } } } /// <summary> /// Decrypt text /// </summary> /// <param name="value"></param> /// <param name="password"></param> /// <returns></returns> private string Decrypt(string value, string password) { Encryption encryption = new Encryption(); string outMsg = null; //Decrypt if (!string.IsNullOrEmpty(value)) { encryption.DesDecrypt(value, password, out outMsg); } return outMsg; } /// <summary> /// Enctypr text /// </summary> /// <param name="value"></param> /// <param name="password"></param> /// <returns></returns> private string Encrypt(string value, string password) { Encryption encryption = new Encryption(); string outMsg = null; if (encryption.DesEncrypt(value, password, out outMsg)) { return outMsg; } else { return string.Empty; } } public void CreateNode(string strNode) { string[] nodes = strNode.Split(new[] { @"/" }, StringSplitOptions.RemoveEmptyEntries); var tempNode = new StringBuilder(); for (int i = 0; i < nodes.Length; i++) { string parentNodePath = tempNode.ToString(); tempNode.Append(@"/"); tempNode.Append(nodes[i]); //此节点不存在,则创建此结点 if (_xmlDocument.SelectSingleNode(tempNode.ToString()) == null) { XmlNode newNode = _xmlDocument.CreateElement(nodes[i]); //寻找父结点 XmlNode parentNode = _xmlDocument.SelectSingleNode(parentNodePath); if (parentNode != null) { parentNode.AppendChild(newNode); } } } _xmlDocument.Save(_filePath); } #endregion }
3.测试用类
1 这是需要操作的文件 2 <?xml version="1.0" encoding="utf-8" ?> 3 <Settings> 4 <HostLocationSetting> 5 <HostLocation></HostLocation> 6 <HostPort></HostPort> 7 </HostLocationSetting> 8 <SystemFolderSetting> 9 <NiceEngineFolderPath></NiceEngineFolderPath> 10 </SystemFolderSetting> 11 <SearchSetting> 12 <MainProgram></MainProgram> 13 <SubProgram></SubProgram> 14 <Status></Status> 15 <SkipPrintedOrder>true</SkipPrintedOrder> 16 <DateRange>1</DateRange> 17 <DateRangeUnit>0</DateRangeUnit> 18 </SearchSetting> 19 <PrintSetting> 20 <ReturnQCResult>false</ReturnQCResult> 21 <ActualPrintQuantity></ActualPrintQuantity> 22 <MOSeperator>true</MOSeperator> 23 <SKUSeperator></SKUSeperator> 24 </PrintSetting> 25 <LoginSetting> 26 <UserName></UserName> 27 <Password></Password> 28 <Language></Language> 29 </LoginSetting> 30 31 </Settings> 32 33 34 测试代码如下 35 namespace ConsoleApplication2 36 { 37 class Program 38 { 39 static void Main(string[] args) 40 { 41 SystemSetting systemSetting = new SystemSetting(@"Config/SystemSetting.xml"); 42 43 systemSetting.LoadData(); 44 45 Console.WriteLine(systemSetting.HostLocation); 46 Console.WriteLine(systemSetting.Status); 47 Console.WriteLine(systemSetting.SkipPrintedOrder); 48 49 systemSetting.HostLocation = "192.168.15.171"; 50 systemSetting.Status = FileStatus.PARTIAL_PRINTED; 51 systemSetting.SkipPrintedOrder = true; 52 53 systemSetting.Refresh(); 54 55 systemSetting.LoadData(); 56 57 Console.WriteLine(systemSetting.HostLocation); 58 Console.WriteLine(systemSetting.Status); 59 Console.WriteLine(systemSetting.SkipPrintedOrder); 60 61 Console.ReadKey(); 62 63 } 64 } 65 }