/// <summary> /// 得到类型的Fields信息 /// </summary> /// <param name="type"></param> /// <returns></returns> public static TypeFields GetTypeFields(Type type) { TypeFields result = TypeFieldsCache.Instance.GetOrAddNewValue(type, (cache, key) => { TypeFields tf = new TypeFields(); FillFieldsInfo(type, tf.Fields); tf._XElementSerializable = (XElementSerializableAttribute.GetCustomAttribute(type, typeof(XElementSerializableAttribute)) != null); Attribute[] attrs = NonXElementSerializedFieldsAttribute.GetCustomAttributes(type, typeof(NonXElementSerializedFieldsAttribute)); foreach (KeyValuePair <TypeFieldInfo, ExtendedFieldInfo> kp in tf.Fields) { kp.Value.IsNotSerialized = kp.Value.FieldInfo.IsNotSerialized; if (kp.Value.IsNotSerialized == false) { kp.Value.IsNotSerialized = Array.Exists(attrs, attr => { NonXElementSerializedFieldsAttribute nfa = (NonXElementSerializedFieldsAttribute)attr; return(nfa.OwnerType == kp.Key.ObjectType && nfa.FieldName == kp.Value.FieldInfo.Name); }); } } cache.Add(key, tf); return(tf); }); return(result); }
private void SerializePropertiesToNodes(XElement parent, object graph, XmlSerializeContext context) { TypeFields tf = TypeFields.GetTypeFields(graph.GetType()); foreach (KeyValuePair <TypeFieldInfo, ExtendedFieldInfo> kp in tf.Fields) { ExtendedFieldInfo efi = kp.Value; if (efi.IsNotSerialized == false && OnFieldCanXElementSerialize(efi)) { object data = GetValueFromObject(efi.FieldInfo, graph); if ((data == null || data == DBNull.Value) == false) { if (Type.GetTypeCode(data.GetType()) == TypeCode.Object) { int objID = 0; if (context.ObjectContext.TryGetValue(data, out objID) == false) { objID = context.CurrentID; context.ObjectContext.Add(data, objID); context.ContainerTypeName = graph.GetType().AssemblyQualifiedName + "." + efi.FieldInfo.Name; SerializeObjectToNode(parent, data, context); } XElement propertyElem = parent.AddChildElement("F"); propertyElem.SetAttributeValue("n", efi.AlternateFieldName); propertyElem.SetAttributeValue("v", objID); propertyElem.SetAttributeValue("r", true); propertyElem.SetAttributeValue("oti", context.GetTypeID(kp.Key.ObjectType)); if (efi.IgnoreDeserializeError) { propertyElem.SetAttributeValue("ide", efi.IgnoreDeserializeError); } } else { XElement propertyElem = parent.AddChildElement("F"); propertyElem.SetAttributeValue("n", efi.AlternateFieldName); propertyElem.SetAttributeValue("v", data); propertyElem.SetAttributeValue("oti", context.GetTypeID(kp.Key.ObjectType)); if (efi.IgnoreDeserializeError) { propertyElem.SetAttributeValue("ide", efi.IgnoreDeserializeError); } } } } } }
/// <summary> /// 得到类型具体的Field信息 /// </summary> /// <param name="type"></param> /// <param name="fieldName"></param> /// <returns></returns> public static ExtendedFieldInfo GetTypeField(Type type, string fieldName) { (type != null).FalseThrow <ArgumentNullException>("type"); fieldName.CheckStringIsNullOrEmpty("fieldName"); TypeFields tf = GetTypeFields(type); ExtendedFieldInfo fi; TypeFieldInfo tfi = new TypeFieldInfo() { ObjectType = type, FieldName = fieldName }; tf.Fields.TryGetValue(tfi, out fi).FalseThrow("不能在类型{0}中找到字段{1}", type.FullName, fieldName); return(fi); }
private XElement SerializeObjectToNode(XElement parent, object graph, XmlSerializeContext context) { System.Type type = graph.GetType(); type.IsSerializable.FalseThrow <SerializationException>("XElementFormatter错误,序列化对象类型时{0}, 子类型{1}不可序列化", context.ContainerTypeName, type.AssemblyQualifiedName); XElement node = context.RootElement.AddChildElement("O"); int objID = context.CurrentID++; node.SetAttributeValue("id", objID); if (this.OutputShortType) { node.SetAttributeValue("shortType", type.Name); } node.SetAttributeValue("oti", context.GetTypeID(type)); if (graph is IXElementSerializable) { node.SetAttributeValue("cs", "true"); ((IXElementSerializable)graph).Serialize(node, context); } else { if (TypeFields.GetTypeFields(type).XElementSerializable) { if (graph is IEnumerable) { SerializeIEnumerableObject(node, (IEnumerable)graph, context); } SerializePropertiesToNodes(node, graph, context); } else { node.AddChildElement("Value", SerializationHelper.SerializeObjectToString(graph, SerializationFormatterType.Binary)); } } return(node); }
private void DeserializeNodesToProperties(XElement parent, object graph, XmlDeserializeContext context) { TypeFields tf = TypeFields.GetTypeFields(graph.GetType()); foreach (KeyValuePair <TypeFieldInfo, ExtendedFieldInfo> kp in tf.Fields) { ExtendedFieldInfo efi = kp.Value; if (efi.IsNotSerialized == false && OnFieldCanXElementSerialize(efi)) { System.Type realType = efi.FieldInfo.FieldType; var propertiesElement = from property in parent.Descendants("F") where (property.AttributeWithAlterName("name", "n", string.Empty) == efi.AlternateFieldName || property.AttributeWithAlterName("name", "n", string.Empty) == efi.FieldInfo.Name) && context.TypeContext[property.AttributeWithAlterName("ownerTypeID", "oti", -1)] == kp.Key.ObjectType select property; if (propertiesElement.FirstOrDefault() == null) { propertiesElement = from property in parent.Descendants("Field") where (property.AttributeWithAlterName("name", "n", string.Empty) == efi.AlternateFieldName || property.AttributeWithAlterName("name", "n", string.Empty) == efi.FieldInfo.Name) && context.TypeContext[property.AttributeWithAlterName("ownerTypeID", "oti", -1)] == kp.Key.ObjectType select property; } XElement propertyElement = propertiesElement.FirstOrDefault(); if (propertyElement != null) { object data = null; if (propertyElement.AttributeWithAlterName("isRef", "r", false) == true) { XElement objectElement = GetObjectElementByID(context.RootElement, propertyElement.AttributeWithAlterName("value", "v", 0)); if (objectElement != null) { bool ignoreError = propertyElement.Attribute("ide", false); if (ignoreError == false) { XElementFieldSerializeAttribute attr = AttributeHelper.GetCustomAttribute <XElementFieldSerializeAttribute>(efi.FieldInfo); if (attr != null) { ignoreError = attr.IgnoreDeserializeError; } } data = DeserializeNodeToObject(objectElement, ignoreError, context); SetValueToObject(efi.FieldInfo, graph, data); } } else { data = propertyElement.AttributeWithAlterName("value", "v", TypeCreator.GetTypeDefaultValue(realType)); if (Convertible(realType, data)) { SetValueToObject(efi.FieldInfo, graph, ConvertData(efi.FieldInfo, data)); } } } } } DeserializeXmlSerilizableList(parent, graph, context); }