/// <summary> /// Constructor. /// </summary> /// <param name="data">data that causes the error.</param> /// <param name="serializableData">SerializableData associated to error.</param> /// <param name="propertyInfo">PropertyInfo associated to error.</param> /// <param name="fieldInfo">FieldInfo associated to error.</param> public XmlSerializationException(object data, SerializableData serializableData, PropertyInfo propertyInfo, FieldInfo fieldInfo) { _data = data; _serializableData = serializableData; _propertyInfo = propertyInfo; _fieldInfo = fieldInfo; }
/// <summary> /// Gets true if a SerializableData is a type that can be constructed. /// </summary> /// <param name="serializableData">SerializableData to check.</param> /// <returns>True if SerializableData can be constructed.</returns> virtual protected bool IsCreateableSerializableData(SerializableData serializableData) { Type type = GetType(serializableData); TypeCode typeCode = Type.GetTypeCode(type); ConstructorInfo[] constructors = type.GetConstructors(); if (constructors.Length == 0 && !type.IsValueType) { return(false); } foreach (ConstructorInfo constructor in constructors) { if (constructor.GetParameters().Length == 0) { return(true); } } if (typeCode == TypeCode.Object) { return(true); } return(false); }
/// <summary> /// Writes an xml node. /// </summary> /// <param name="xmlNode">Xml node.</param> /// <param name="serializableData">SerializableData to write in the XmlNode.</param> virtual protected void WriteXml(XmlNode xmlNode, SerializableData serializableData) { XmlElement xmlElementClass = null; try { xmlElementClass = _xmlDocument.CreateElement(GetFormattedText(serializableData.TagName)); // xmlElementClass = _xmlDocument.CreateCDataSection(serializableData.TagName); } catch { throw new XmlSerializationException(_xmlDocument, serializableData); } xmlElementClass.Attributes.Append(CreateXmlAttribute("value", serializableData.Value)); xmlElementClass.Attributes.Append(CreateXmlAttribute("type", serializableData.Type)); xmlElementClass.Attributes.Append(CreateXmlAttribute("assembly", serializableData.Assembly)); xmlElementClass.Attributes.Append(CreateXmlAttribute("assemblyQualifiedName", serializableData.AssemblyQualifiedName)); xmlElementClass.Attributes.Append(CreateXmlAttribute("name", serializableData.FieldName)); xmlNode.AppendChild(xmlElementClass); foreach (SerializableData data in serializableData.SerializableDataCollection) { WriteXml(xmlElementClass, data); } }
/// <summary> /// Creates a System.Array. /// </summary> /// <param name="serializableData">Reference SerializableData.</param> /// <returns>Created array.</returns> virtual protected object CreateArray(SerializableData serializableData) { object data = null; try { Type type = GetType(serializableData.SerializableDataCollection[0]); System.Array array = System.Array.CreateInstance(type, serializableData.SerializableDataCollection.Count); for (int i = 0; i < serializableData.SerializableDataCollection.Count; i++) { object internalData = null; if (!IsBaseType(type)) { internalData = Compose(serializableData.SerializableDataCollection[i]); } else { internalData = ConvertType(serializableData.SerializableDataCollection[i]); } array.SetValue(internalData, i); } data = array; FillObject(ref data, serializableData); } catch { throw new XmlSerializationException(data, serializableData); } return(data); }
/// <summary> /// Finds the XmlClassSerializable attribute of the data. /// </summary> /// <param name="data">Data in which searching.</param> /// <param name="serializableData">Reference SerializableData.</param> /// <param name="dataMembers">Data mebers</param> virtual protected void FindClassFields(object data, SerializableData serializableData, Collection <DataMember> dataMembers) { Type type = data.GetType(); for (int i = 0; i < dataMembers.Count; i++) { SerializableData newSerializableData = new SerializableData(); if (GetXmlClassSerializableAttribute(dataMembers[i].TypeInfo) != null) { object field = type.InvokeMember(dataMembers[i].DataInfo.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty, null, data, null); newSerializableData.FieldName = dataMembers[i].DataInfo.Name; if (!FindXmlSerializableClassAttribute(field, newSerializableData)) { continue; } } else { newSerializableData = CreateSerializableData(data, dataMembers[i]); if (newSerializableData == null) { continue; } } serializableData.SerializableDataCollection.Add(newSerializableData); } FillCollection(data, serializableData); }
/// <summary> /// Gets the object from SerializableData. /// </summary> /// <param name="serializableData">SerializableData in which there are object informations.</param> /// <returns>Build Object.</returns> virtual protected object GetObject(SerializableData serializableData) { object rightObject = null; Type rightType = GetType(serializableData); TypeCode typeCode = Type.GetTypeCode(rightType); if (IsCreateableSerializableData(serializableData)) { rightObject = CreateObject(serializableData); } else { try { rightObject = ConvertType(serializableData); } catch { throw new XmlSerializationException(rightObject, serializableData); } } FillObject(ref rightObject, serializableData); return(rightObject); }
/// <summary> /// Fills data with fields values specified in SerializableData. /// </summary> /// <param name="data">Data to fill.</param> /// <param name="serializableData">Fields values used to fill the data.</param> virtual protected void FillObject(ref object data, SerializableData serializableData) { foreach (SerializableData member in serializableData.SerializableDataCollection) { FillObjectField(data, data.GetType(), member); } }
/// <summary> /// Writes an xml file. /// </summary> /// <param name="fileName">Xml file to write.</param> /// <param name="serializableData">SerializableData to read.</param> public void WriteXml(string fileName, SerializableData serializableData) { CreateXmlDeclaration(); WriteXml(_xmlDocument, serializableData); _xmlDocument.Save(fileName); }
/// <summary> /// Composes an object from a SerializableData. /// </summary> /// <param name="serializableData">SerializableData from which create an object.</param> /// <returns>Build object.</returns> virtual public object Compose(SerializableData serializableData) { object data = CreateObject(serializableData); FillObject(ref data, serializableData); return(data); }
/// <summary> /// Creates a collection. /// </summary> /// <param name="serializableData">Reference SerializableData.</param> /// <returns>Created collection.</returns> virtual protected object CreateCollection(SerializableData serializableData) { object data = CreateObject(serializableData); Type type = data.GetType(); foreach (SerializableData internalData in serializableData.SerializableDataCollection) { object parameters = Compose(internalData); Filler(data, data.GetType(), new object[] { parameters }, internalData); } return(data); }
/// <summary> /// Reads an xml file. /// </summary> /// <param name="fileName">Xml file to read.</param> /// <param name="serializableData">SerializableData to fill.</param> /// <returns>Filled class</returns> public object ReadXml(string fileName, SerializableData serializableData) { _xmlDocument.Load(fileName); try { ReadXml(_xmlDocument.ChildNodes[1], serializableData); } catch { throw new XmlSerializationException(_xmlDocument, serializableData); } return(serializableData); }
/// <summary> /// Create a SerializableData from an object and a DataMember. /// </summary> /// <param name="data">Reference data.</param> /// <param name="dataMember">Reference DataMember.</param> /// <returns>New SerializableData.</returns> virtual protected SerializableData CreateSerializableData(object data, DataMember dataMember) { bool foundAttribute = true; XmlFieldSerializable attribute = GetXmlFieldSerializableAttribute(dataMember.DataInfo); if (attribute == null || attribute.TagName == string.Empty) { foundAttribute = false; } object value = null; SerializableData newSerializableData = new SerializableData(); BindingFlags flags = GetFlags(data.GetType()); PropertyInfo property = GetProperty(dataMember.DataInfo.ReflectedType, dataMember.DataInfo.Name, flags); if (property != null && property.CanRead) { value = property.GetGetMethod(true).Invoke(data, null); } else { FieldInfo field = GetField(dataMember.DataInfo.ReflectedType, dataMember.DataInfo.Name, flags); if (field != null) { value = field.GetValue(data); } //value = dataMember.DataInfo.ReflectedType.InvokeMember(dataMember.DataInfo.Name, flags, null, data, null); else { return(null); } } newSerializableData.Type = dataMember.TypeInfo.FullName; newSerializableData.Assembly = dataMember.TypeInfo.Assembly.ToString(); newSerializableData.AssemblyQualifiedName = dataMember.TypeInfo.AssemblyQualifiedName; newSerializableData.Value = value != null?value.ToString() : string.Empty; newSerializableData.TagName = foundAttribute ? attribute.TagName : dataMember.TypeInfo.Name; newSerializableData.FieldName = dataMember.DataInfo.Name; FillCollection(value, newSerializableData); return(newSerializableData); }
/// <summary> /// Create a SerializableData from an object. FieldName will be empty. /// </summary> /// <param name="data">Reference Data.</param> /// <param name="serializableData">new SerializableData.</param> virtual protected void CreateSerializableData(object data, SerializableData serializableData) { Type type = data.GetType(); bool foundAttribute = true; XmlClassSerializable attribute = GetXmlClassSerializableAttribute(type); if (attribute == null || attribute.TagName == string.Empty) { foundAttribute = false; } serializableData.Type = type.FullName; serializableData.Assembly = type.Assembly.ToString(); serializableData.AssemblyQualifiedName = type.AssemblyQualifiedName; serializableData.Value = foundAttribute ? string.Empty : data.ToString(); serializableData.TagName = foundAttribute ? attribute.TagName : type.Name; }
/// <summary> /// Finds the XmlClassSerializable attribute of the data and fill the SerializableData. /// </summary> /// <param name="data">Data to serialize.</param> /// <param name="serializableData">SerializableData to fill with found attributes.</param> virtual protected bool FindXmlSerializableClassAttribute(object data, SerializableData serializableData) { Type type = data.GetType(); XmlClassSerializable attribute = GetXmlClassSerializableAttribute(type); if (attribute == null) { return(false); } CreateSerializableData(data, serializableData); Collection <DataMember> dataMembers = new Collection <DataMember>(); FillDataMembers(type, dataMembers, true, attribute.Deep, GetFlags(type, attribute)); FindClassFields(data, serializableData, dataMembers); return(true); }
/// <summary> /// Creates an object, a collection, an array or other. /// </summary> /// <param name="serializableData">Reference SerializableData.</param> /// <returns>New build object.</returns> virtual protected object GetNewObject(SerializableData serializableData) { object rightObject = null; Type rightType = GetType(serializableData); if (rightType.IsArray) { rightObject = CreateArray(serializableData); } else if (IsCollection(rightType)) { rightObject = CreateCollection(serializableData); } else { rightObject = GetObject(serializableData); } return(rightObject); }
/// <summary> /// Reads an XmlNode. /// </summary> /// <param name="xmlNode">XmlNode to read.</param> /// <param name="serializableData">SerializableData to fill.</param> virtual protected void ReadXml(XmlNode xmlNode, SerializableData serializableData) { XmlAttribute xmlAttributeName = xmlNode.Attributes["name"]; XmlAttribute xmlAttributeType = xmlNode.Attributes["type"]; XmlAttribute xmlAttributeAssembly = xmlNode.Attributes["assembly"]; XmlAttribute xmlAttributeAssemblyQualifiedName = xmlNode.Attributes["assemblyQualifiedName"]; string alias = xmlNode.Name; XmlAttribute xmlAttributeValue = xmlNode.Attributes["value"]; serializableData.TagName = alias; serializableData.Type = xmlAttributeType.Value; serializableData.Assembly = xmlAttributeAssembly.Value; serializableData.AssemblyQualifiedName = xmlAttributeAssemblyQualifiedName.Value; serializableData.FieldName = xmlAttributeName.Value; serializableData.Value = xmlAttributeValue.Value; foreach (XmlNode xmlChildNode in xmlNode.ChildNodes) { SerializableData newSerializableData = new SerializableData(); serializableData.SerializableDataCollection.Add(newSerializableData); ReadXml(xmlChildNode, newSerializableData); } }
/// <summary> /// Creates an object of specified type defined in SerializableData. /// </summary> /// <param name="serializableData">Reference SerializableData.</param> /// <returns>Build object.</returns> virtual protected object CreateObject(SerializableData serializableData) { object obj = null; Type type = GetType(serializableData); if (type != null) { obj = Activator.CreateInstance(type, null); } else { throw new XmlSerializationException(null, serializableData); } System.Runtime.Remoting.ObjectHandle objH = obj as System.Runtime.Remoting.ObjectHandle; if (objH != null) { obj = objH.Unwrap(); } return(obj); }
/// <summary> /// If the data derives from System.Collections.ICollection, it fills serializableData. /// Can override this function to customize the filling in a user collection. /// </summary> /// <param name="data">Data to check.</param> /// <param name="serializableData">SerializableData to fill.</param> virtual protected bool FillCollection(object data, SerializableData serializableData) { if (!IsCollection(data)) { return(false); } System.Collections.ICollection collection = data as System.Collections.ICollection; foreach (object internalData in collection) { SerializableData newSerializableData = new SerializableData(); XmlClassSerializable attribute = GetXmlClassSerializableAttribute(internalData.GetType()); if (!FindXmlSerializableClassAttribute(internalData, newSerializableData)) { Type type = internalData.GetType(); Collection <DataMember> dataMembers = new Collection <DataMember>(); FillDataMembers(type, dataMembers, false, IsDeepSerializable(type), GetFlags(type, attribute)); if (dataMembers.Count == 0) { continue; } CreateSerializableData(internalData, newSerializableData); FindClassFields(internalData, newSerializableData, dataMembers); } serializableData.SerializableDataCollection.Add(newSerializableData); } return(true); }
/// <summary> /// Changes the SerializableData object in the correct object type and assigns it the value. /// </summary> /// <param name="serializableData">SerializableData to convert.</param> /// <returns>Right object.</returns> virtual protected object ConvertType(SerializableData serializableData) { object rightObject = null; Type type = GetType(serializableData); TypeCode typeCode = Type.GetTypeCode(type); switch (typeCode) { case TypeCode.Boolean: if (serializableData.Value == string.Empty) { rightObject = false; } else { rightObject = bool.Parse(serializableData.Value); } break; case TypeCode.Byte: if (serializableData.Value == string.Empty) { rightObject = 0; } else { rightObject = Byte.Parse(serializableData.Value); } break; case TypeCode.Char: if (serializableData.Value == string.Empty) { rightObject = char.MinValue; } else { rightObject = Char.Parse(serializableData.Value); } break; case TypeCode.DateTime: if (serializableData.Value == string.Empty) { rightObject = DateTime.Now; } else { rightObject = DateTime.Parse(serializableData.Value); } break; case TypeCode.Decimal: if (serializableData.Value == string.Empty) { rightObject = decimal.MinValue; } else { rightObject = Decimal.Parse(serializableData.Value); } break; case TypeCode.Double: if (serializableData.Value == string.Empty) { rightObject = double.MinValue; } else { rightObject = double.Parse(serializableData.Value); } break; case TypeCode.Int16: if (serializableData.Value == string.Empty) { rightObject = Int16.MinValue; } else { rightObject = Int16.Parse(serializableData.Value); } break; case TypeCode.Int32: if (serializableData.Value == string.Empty) { rightObject = Int32.MinValue; } else { rightObject = Int32.Parse(serializableData.Value); } break; case TypeCode.Int64: if (serializableData.Value == string.Empty) { rightObject = Int64.MinValue; } else { rightObject = Int64.Parse(serializableData.Value); } break; case TypeCode.SByte: if (serializableData.Value == string.Empty) { rightObject = SByte.MinValue; } else { rightObject = SByte.Parse(serializableData.Value); } break; case TypeCode.Single: if (serializableData.Value == string.Empty) { rightObject = Single.MinValue; } else { rightObject = Single.Parse(serializableData.Value); } break; case TypeCode.String: rightObject = serializableData.Value; break; case TypeCode.UInt16: if (serializableData.Value == string.Empty) { rightObject = UInt16.MinValue; } else { rightObject = UInt16.Parse(serializableData.Value); } break; case TypeCode.UInt32: if (serializableData.Value == string.Empty) { rightObject = UInt32.MinValue; } else { rightObject = UInt32.Parse(serializableData.Value); } break; case TypeCode.UInt64: if (serializableData.Value == string.Empty) { rightObject = UInt64.MinValue; } else { rightObject = UInt64.Parse(serializableData.Value); } break; case TypeCode.DBNull: if (serializableData.Value == string.Empty) { rightObject = null; } else { rightObject = Convert.ToBoolean(serializableData.Value); } break; case TypeCode.Empty: if (serializableData.Value == string.Empty) { rightObject = null; } else { rightObject = Convert.ToBoolean(serializableData.Value); } break; } return(rightObject); }
/// <summary> /// Fills a data. /// </summary> /// <param name="dataToFill">data to fill.</param> /// <param name="type">Type of the data.</param> /// <param name="parameters">Parameters used to fill.</param> /// <param name="serializableData">Reference SerializableData.</param> protected virtual void Filler(object dataToFill, Type type, object[] parameters, SerializableData serializableData) { XmlClassSerializable attribute = GetXmlClassSerializableAttribute(type); bool deep = IsDeepSerializable(type); // bool deep = attribute != null ? attribute.Deep : true; // BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.SetField | BindingFlags.SetProperty; BindingFlags flags = GetFlags(type, attribute); PropertyInfo property = GetProperty(type, serializableData.FieldName, flags); FieldInfo field = GetField(type, serializableData.FieldName, flags); try { if ((property != null && property.CanWrite) || (field != null && !field.IsLiteral)) { type.InvokeMember(serializableData.FieldName, flags, null, dataToFill, parameters); } else if (!type.BaseType.Equals(typeof(object)) && type.BaseType != null && deep) { FillObjectField(dataToFill, type.BaseType, serializableData); } else if (IsCollection(type) && !IsArray(type)) { InvokeAddingMethod(dataToFill, parameters); } } catch { throw new XmlSerializationException(dataToFill, serializableData, property, field); } }
/// <summary> /// Fills a single field of the data. /// </summary> /// <param name="data">Data to fill.</param> /// <param name="type">Type of the data to fill.</param> /// <param name="serializableData">Field value.</param> virtual protected void FillObjectField(object data, Type type, SerializableData serializableData) { object rightObject = GetNewObject(serializableData); Filler(data, type, new object[] { rightObject }, serializableData); }
/// <summary> /// Gets the right type present in the SerializableData. /// </summary> /// <param name="serializableData">Reference SerializableData.</param> /// <returns>Type.</returns> protected Type GetType(SerializableData serializableData) { return(Type.GetType(serializableData.AssemblyQualifiedName)); }
/// <summary> /// Constructor. /// </summary> /// <param name="data">data that causes the error.</param> /// <param name="serializableData">SerializableData associated to error.</param> public XmlSerializationException(object data, SerializableData serializableData) { _data = data; _serializableData = serializableData; }