//把属性值转换为XML 字符窜的格式 private void valueToXmlString(StringBuilder sXml, object val, Type valType, ValueXmlSerializerAttribute cfgAtt) { if (val != null && !string.IsNullOrEmpty(val.ToString())) { if (cfgAtt != null && cfgAtt.GeneralStruct) { processObject(sXml, val, valType, true); } else { if (valType.Equals(typeof(DateTime)) && val != null) { sXml.Append(string.Format(XML_CDATA, ((DateTime)val).ToString(MB.BaseFrame.SOD.DATE_TIME_FORMATE))); //ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo) } else if (valType.IsGenericType && valType.Equals(typeof(Nullable <DateTime>)) && val != null) { sXml.Append(string.Format(XML_CDATA, ((DateTime)val).ToString(MB.BaseFrame.SOD.DATE_TIME_FORMATE))); //ToString(System.Globalization.DateTimeFormatInfo.InvariantInfo) } else { sXml.Append(string.Format(XML_CDATA, val)); } } } }
//设置引用类型的值 private void setObjectValue(object entity, PropertyInfo info, ValueXmlSerializerAttribute att, XmlNode xmlNode) { //判断是否引用集合 if (info.PropertyType.GetInterface("IList") != null) { // if (att.ReferenceModelType == null) return; object value = info.GetValue(entity, null); //判断并创建一个新的集合容器 if (value == null) { throw new MB.Util.APPException("所有继承IList接口 的对象属性,在默认的构造函数中先实例化该对象", APPMessageType.SysErrInfo); } IList lstValue = value as IList; XmlNodeList childsNodes = null; //if (att.NotExistsGroupNode) { // childsNodes = xmlNode.ParentNode.ChildNodes; //} //else { childsNodes = xmlNode.ChildNodes; // } if (childsNodes.Count == 0) { return; } string nodeName = info.Name; foreach (XmlNode lstChild in childsNodes) { if (lstChild.NodeType != XmlNodeType.Element) { continue; } object childEntity = createObjectByXmlNodeAttribute(lstChild, null); if (childEntity == null) { continue; } lstValue.Add(childEntity); fillProperty(childEntity, childEntity.GetType(), lstChild); } } else if (info.PropertyType.IsValueType) { object v = info.GetValue(entity, null); fillValueTypeData(ref v, info.PropertyType, xmlNode); MB.Util.MyReflection.Instance.InvokePropertyForSet(entity, info.Name, v); } else { object proVal = createObjectByXmlNodeAttribute(xmlNode, info.PropertyType); if (proVal != null) { MB.Util.MyReflection.Instance.InvokePropertyForSet(entity, info.Name, proVal); fillProperty(proVal, proVal.GetType(), xmlNode); } } }
private void fillProperty(object entity, Type entityType, XmlNode xmlNode, bool exceptCheckDataMember) { PropertyInfo[] pros = entityType.GetProperties(); foreach (PropertyInfo info in pros) { if (info.IsSpecialName || !info.CanWrite) { continue; } if (!exceptCheckDataMember) { if (_PropertysIsDataMember.ContainsKey(info)) { if (!_PropertysIsDataMember[info]) { continue; } } else { DataMemberAttribute att = Attribute.GetCustomAttribute(info, typeof(DataMemberAttribute)) as DataMemberAttribute; _PropertysIsDataMember[info] = att != null; if (att == null) { continue; } } } ValueXmlSerializerAttribute cfgAtt = null; if (_PropertysXmlAtt.ContainsKey(info)) { cfgAtt = _PropertysXmlAtt[info]; } else { cfgAtt = Attribute.GetCustomAttribute(info, typeof(ValueXmlSerializerAttribute)) as ValueXmlSerializerAttribute; _PropertysXmlAtt.Add(info, cfgAtt); } if (cfgAtt != null && !cfgAtt.Switch) { continue; } XmlNode propertyNode = getNodeByNodeName(xmlNode.ChildNodes, info.Name); if (propertyNode == null) { continue; } if (string.IsNullOrEmpty(propertyNode.InnerText)) { continue; } if (info.PropertyType.IsValueType || string.Compare(info.PropertyType.Name, "String", true) == 0) { if (cfgAtt != null && cfgAtt.GeneralStruct) { XmlNode refrenceNode = getNodeByNodeName(xmlNode.ChildNodes, info.Name); if (refrenceNode != null) { setObjectValue(entity, info, cfgAtt, refrenceNode); } } else { object val = propertyNode.InnerText.Trim(); //考虑到Enum 的值都是通过描述来配置的,所以这里需要特殊处理一下。 if (info.PropertyType.IsEnum) { val = Enum.Parse(info.PropertyType, val.ToString()); } MB.Util.MyReflection.Instance.InvokePropertyForSet(entity, info.Name, val); } } else if (info.PropertyType.IsArray) { string val = propertyNode.InnerText.Trim(); if (string.IsNullOrEmpty(val)) { continue; } if (string.Compare(info.PropertyType.Name, "String[]", true) == 0) { string[] aVals = val.Split(','); MB.Util.MyReflection.Instance.InvokePropertyForSet(entity, info.Name, aVals); } else { throw new MB.Util.APPException("在 实体对象XML 反系列化 时,对于数组类型,目前只支持String[] 如果还需要其它的再追加", APPMessageType.SysErrInfo); } } else { XmlNode refrenceNode = getNodeByNodeName(xmlNode.ChildNodes, info.Name); if (refrenceNode != null) { setObjectValue(entity, info, cfgAtt, refrenceNode); } } } }
//系列化节点开头的标记 private void writeFirstMarker(StringBuilder sXml, string nodeName, Type dataType, ValueXmlSerializerAttribute cfgAtt) { sXml.Append("<"); sXml.Append(nodeName); if (dataType != null) { Type realType = MB.Util.MyReflection.Instance.GetPropertyType(dataType); if (cfgAtt != null) { if (cfgAtt.CreateByInstanceType) { sXml.Append(" " + string.Format(XML_NODE_ATT, XML_NODE_ATT_DATATYPE, realType.FullName + "," + realType.Assembly.FullName)); } else if (!string.IsNullOrEmpty(cfgAtt.ValueType)) { sXml.Append(" " + string.Format(XML_NODE_ATT, XML_NODE_ATT_DATATYPE, cfgAtt.ValueType)); } } } sXml.Append(">"); }
private void processObject(StringBuilder sXml, object val, Type entityType, bool exceptCheckDataMember) { Type ty = entityType; PropertyInfo[] pros = ty.GetProperties(); foreach (PropertyInfo info in pros) { if (info.IsSpecialName) { continue; } if (!exceptCheckDataMember) { if (_PropertysIsDataMember.ContainsKey(info)) { if (!_PropertysIsDataMember[info]) { continue; } } else { object[] att = info.GetCustomAttributes(typeof(DataMemberAttribute), true); _PropertysIsDataMember[info] = att != null && att.Length > 0; if (att == null || att.Length == 0) { continue; } } } ValueXmlSerializerAttribute cfgAtt = null; if (_PropertysXmlAtt.ContainsKey(info)) { cfgAtt = _PropertysXmlAtt[info]; } else { cfgAtt = Attribute.GetCustomAttribute(info, typeof(ValueXmlSerializerAttribute)) as ValueXmlSerializerAttribute; _PropertysXmlAtt.Add(info, cfgAtt); } if (cfgAtt != null && !cfgAtt.Switch) { continue; } Type proType = info.PropertyType; object v = info.GetValue(val, null); writeFirstMarker(sXml, info.Name, proType, cfgAtt); if (info.PropertyType.IsValueType || string.Compare(info.PropertyType.Name, "String", true) == 0) { valueToXmlString(sXml, v, info.PropertyType, cfgAtt); } else if (info.PropertyType.IsArray) { if (v == null) { continue; } if (string.Compare(info.PropertyType.Name, "String[]", true) == 0) { string[] avs = (string[])v; valueToXmlString(sXml, string.Join(",", avs), info.PropertyType, cfgAtt); } else { throw new MB.Util.APPException(string.Format("实体对象的系列化,属性数组类型只支持string[] 类型, {0} 类型暂时不支持", info.PropertyType.Name)); } } else { if (v == null) { continue; } IList lstEntity = v as IList; if (lstEntity != null) { foreach (object o in lstEntity) { if (o == null) { continue; } Type childDataType = o.GetType(); if (childDataType.IsValueType || string.Compare(childDataType.Name, "String", true) == 0) { valueToXmlString(sXml, v, childDataType, cfgAtt); continue; } writeFirstMarker(sXml, CHILD_ITEM, childDataType, cfgAtt); processObject(sXml, o, childDataType); writeLastMarker(sXml, CHILD_ITEM); } } else { processObject(sXml, v, info.PropertyType); } } writeLastMarker(sXml, info.Name); } }