Пример #1
0
        public void Serialize(XmlTextWriter writer, object obj, bool writeElement)
        {
            //Use the IXmlSerializable implementation if needed
            IXmlSerializable serializableObject = obj as IXmlSerializable;

            if (serializableObject != null)
            {
                serializableObject.WriteXml(writer);
                return;
            }

            //If the type can be converted directly to a string then serialize it
            //as an element with text content (int, string, etc)
            TypeConverter conv = TypeDescriptor.GetConverter(obj);

            if (CanSerialize(conv))
            {
                writer.WriteElementString(obj.GetType().Name.ToLowerInvariant(), conv.ConvertToInvariantString(obj));
                return;
            }

            //Serialize the object and its public members
            if (writeElement)
            {
                writer.WriteStartElement(obj.GetType().Name);
            }

            //Get the list of properties with the ones that want to be serialized as attributed listed first
            List <PropertyDescriptor> props = GetSortedProperties(obj);

            //Serialize the Properties
            foreach (PropertyDescriptor prop in props)
            {
                //Get the property value
                object value = prop.GetValue(obj);
                if (value == null)
                {
                    continue;
                }

                if (prop.IsReadOnly)
                {
                    //if the property is read-only and is a list then serialize the content
                    IList list = value as IList;
                    if (list != null && list.Count > 0)
                    {
                        writer.WriteStartElement(prop.Name);

                        string elementName = prop.Name.Substring(0, prop.Name.Length - 1);
                        DefaultListSerializer serializer = new DefaultListSerializer(elementName);
                        serializer.Serialize(writer, list, false);

                        writer.WriteEndElement();
                    }
                }
                else
                {
                    //Get a converter and Serialize it to a string
                    TypeConverter converter = prop.Converter;
                    if (converter == null || !converter.CanConvertTo(typeof(string)) || !converter.CanConvertFrom(typeof(string)))
                    {
                        writer.WriteStartElement(prop.Name);
                        ObjectSerializer.Serialize(writer, value, false);
                        writer.WriteEndElement();
                        continue;
                    }

                    string strValue = converter.ConvertToString(null, InvariantSerializationCulture, value);

                    if (prop.Attributes.Contains(new XmlAttributeAttribute()))
                    {
                        writer.WriteAttributeString(prop.Name, strValue);
                    }
                    else
                    {
                        writer.WriteElementString(prop.Name, strValue);
                    }
                }
            }

            if (writeElement)
            {
                writer.WriteEndElement(); //Object element
            }
        }
Пример #2
0
        public object Deserialize(XmlTextReader reader, Type type, object context)
        {
            //If the object has a type converter then just read the attribute string
            TypeConverter conv = TypeDescriptor.GetConverter(type);

            if (CanSerialize(conv))
            {
                string strValue = reader.ReadElementString();
                object value    = conv.ConvertFromInvariantString(strValue);
                return(value);
            }

            //Create an instance of the type
            Object obj = Activator.CreateInstance(type);

            //Use the IXmlSerializable implementation if needed
            IXmlSerializable serializableObject = obj as IXmlSerializable;

            if (serializableObject != null)
            {
                serializableObject.ReadXml(reader);
                return(obj);
            }

            //parse all the attributes as properties
            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(type);
            bool hasChildren = !reader.IsEmptyElement;

            if (reader.MoveToFirstAttribute())
            {
                do
                {
                    PropertyDescriptor prop = properties[reader.Name];
                    if (prop == null)
                    {
                        throw new InvalidOperationException("the property " + reader.Name + " does not exist on the object " + type.Name);
                    }

                    reader.ReadAttributeValue();
                    TypeConverter converter = prop.Converter;
                    object        value     = converter.ConvertFromInvariantString(reader.Value);
                    prop.SetValue(obj, value);
                }while (reader.MoveToNextAttribute());
            }
            reader.Read();

            if (hasChildren)
            {
                //Parse the children as properties
                while (true)
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        //If the property is read-only and a list then add the children to the list members
                        PropertyDescriptor prop = properties[reader.Name];
                        if (prop == null)
                        {
                            throw new InvalidOperationException("the property " + reader.Name + " does not exist on the object " + type.Name);
                        }

                        if (prop.IsReadOnly)
                        {
                            IList list = prop.GetValue(obj) as IList;
                            if (list != null)
                            {
                                DefaultListSerializer serializer = new DefaultListSerializer();
                                serializer.Deserialize(reader, list.GetType(), list);
                            }
                        }
                        else
                        {
                            //parse the value and set the property
                            object value = ObjectSerializer.Deserialize(reader, prop.PropertyType, null);
                            prop.SetValue(obj, value);
                        }
                    }
                    // If end element then we are done parsing children.
                    else if (reader.NodeType == XmlNodeType.EndElement)
                    {
                        reader.Read(); //end element
                        break;
                    }
                    else if (reader.EOF)
                    {
                        break;  //end of document
                    }
                    // If we don't explicitly handle this kind of node then ignore it.
                    else
                    {
                        reader.Read();
                    }
                }
            }
            return(obj);
        }