/// <summary> /// Serializes the specified obj. /// </summary> /// <param name="obj">The obj.</param> /// <returns></returns> public System.Xml.XmlElement Serialize(T obj) { Type type = obj.GetType(); try { // should the version of the object be checked before any other stuff is done? // no need to do anything if it doesn't event belong in here anyhow. // should limit to public, instance, read/write properties... PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | (BindingFlags.GetProperty & BindingFlags.SetProperty) | (BindingFlags.GetField & BindingFlags.SetField)); string rootTypeName = Util.GetReflectorNameAttributeValue(type); Version versionInfo = Util.GetTypeDescriptionProviderVersion(typeof(T)); XmlDocument doc = new XmlDocument(); XmlElement root = doc.CreateElement(rootTypeName); foreach (PropertyInfo pi in props) { bool required = Util.GetCustomAttribute <RequiredAttribute> (pi) != null; bool ignore = Util.GetCustomAttribute <ReflectorIgnoreAttribute> (pi) != null; // get the version info for the property... Version minVer = Util.GetMinimumVersion(pi); Version maxVer = Util.GetMaximumVersion(pi); Version exactVer = Util.GetExactVersion(pi); if (ignore || (!Util.IsExactVersion(exactVer, versionInfo) && !Util.IsInVersionRange(minVer, maxVer, versionInfo))) { continue; } // get node name string name = Util.GetReflectorNameAttributeValue(pi); ReflectorNodeTypes nodeType = Util.GetReflectorNodeType(pi); XmlNode node = null; object val = pi.GetValue(obj, null);; // check if it has a serializervalue attribute and get the value if it does. if (pi.PropertyType.IsEnum || (Util.IsNullable(pi.PropertyType) && Nullable.GetUnderlyingType(pi.PropertyType).IsEnum) && val != null) { Type enumType = pi.PropertyType; if (Util.IsNullable(enumType)) { enumType = Nullable.GetUnderlyingType(enumType); } FieldInfo fi = enumType.GetField(val.ToString()); SerializerValueAttribute sv = Util.GetSerializerValue(fi); if (sv != null) { val = sv.Value; } } switch (nodeType) { case ReflectorNodeTypes.Attribute: node = doc.CreateAttribute(name); if (required) { // checks if null or empty... if (val == null || val.ToString() == string.Empty) { throw new RequiredAttributeException(obj, name); } node.InnerText = Util.CheckRequired(obj, name, val).ToString(); } else { if (val != null) { node.InnerText = val.ToString(); } } if ((Util.IsNullable(pi.PropertyType) && val != null) || (val != null && !Util.IsNullable(pi.PropertyType) && !string.IsNullOrEmpty(val.ToString()))) { root.Attributes.Append(node as XmlAttribute); } break; case ReflectorNodeTypes.Element: node = doc.CreateElement(name); if (required) { // checks if null or empty... if (val == null || val.ToString() == string.Empty) { throw new RequiredAttributeException(obj, name); } } if (val != null) { Type valType = val.GetType(); if (valType.IsPrimitive || valType == typeof(string)) { node.InnerText = val.ToString(); } else { // handle clonable lists if (valType.IsGenericType && valType.GetGenericTypeDefinition().Equals(typeof(CloneableList <>))) { System.Collections.IList vlist = val as IList; foreach (object o in vlist) { if (o is ICCNetObject) { XmlNode tn = ((ICCNetObject)o).Serialize(); if (tn != null) { node.AppendChild(doc.ImportNode(tn, true)); } } else { Type o1 = o.GetType(); if (o1.IsSerializable && o1.IsClass) { try { string arrayItemName = Util.GetReflectorArrayAttributeValue(pi); XmlElement tn = doc.CreateElement(arrayItemName); tn.InnerText = o.ToString(); if (tn != null) { node.AppendChild(doc.ImportNode(tn, true)); } } catch { try { string ss = Util.GetStringSeparatorAttributeValue(pi); XmlElement ele = node as XmlElement; ele.InnerText += string.Format("{0}{1}", o.ToString(), ss); } catch { } } } } } } else if (val is HiddenPassword) // handle the hidden password object { node.InnerText = (val as HiddenPassword).GetPassword(); } else if (valType.GetInterface(typeof(ICCNetObject).FullName) != null) // handle other ICCNetObjects { XmlNode tn = ((ICCNetObject)val).Serialize(); if (tn != null) { // ignore the node that the object creates, use the one the property creates. // then import all the attributes and child nodes foreach (XmlAttribute attr in tn.Attributes) { node.Attributes.Append(doc.ImportNode(attr, true) as XmlAttribute); } foreach (XmlElement ele in tn.SelectNodes("./*")) { node.AppendChild(doc.ImportNode(ele, true)); } } } else // eveything else { string formatString = Util.GetFormatAttributeValue(pi); if (valType.GetInterface(typeof(IFormattable).FullName) != null && !string.IsNullOrEmpty(formatString)) { node.InnerText = ((IFormattable)val).ToString(formatString, null); } else { node.InnerText = val.ToString(); } } } } // if it should be added, add it... if (node != null && ((Util.IsNullable(pi.PropertyType) && val != null) || !Util.IsNullable(pi.PropertyType) && val != null && !string.IsNullOrEmpty(val.ToString()))) { root.AppendChild(node); } break; case ReflectorNodeTypes.Value: if (val != null) { root.AppendChild(doc.CreateTextNode(val.ToString())); } break; } } return(root); } catch (Exception ex) { Console.WriteLine(ex.ToString()); throw; } }
/// <summary> /// Initializes a new instance of the <see cref="ReflectorNodeTypeAttribute"/> class. /// </summary> /// <param name="type">The type.</param> public ReflectorNodeTypeAttribute(ReflectorNodeTypes type) { this._type = type; }