Beispiel #1
0
        private void WriteNode(
            String nodeName, Object value, Boolean asAttribute, XmlItemDefAttributeCollection itemDefAttributes, String comment = null
            )
        {
            if (String.IsNullOrEmpty(nodeName))
            {
                throw new ArgumentNullException();
            }

            if (!asAttribute && comment != null)
            {
                this.XmlWriter.WriteComment(comment);
            }

            Type objectType;

            if (value != null)
            {
                objectType = value.GetType();
                if (!XmlSerializationProvider.IsNativelySerializable(objectType))
                {
                    this.Serializer.GetSubSerializer(value.GetType()).SubSerialize(this.XmlWriter, value, nodeName, asAttribute, itemDefAttributes);
                    return;
                }
            }
            else
            {
                objectType = null;
            }

            this.WriteNativeObject(nodeName, objectType, value, asAttribute, itemDefAttributes);
        }
Beispiel #2
0
        /// <exception cref="XmlSerializationException">
        ///   The type requires to implement <see cref="IXmlCustomSerialized" /> to be serialized as an attribute.
        /// </exception>
        void IXmlSerializerInternal.SubSerialize(
            XmlWriter xmlWriter, Object instance, String rootName, Boolean asAttribute,
            XmlItemDefAttributeCollection itemDefAttributes
            )
        {
            if (xmlWriter == null)
            {
                throw new ArgumentNullException();
            }
            if (instance == null)
            {
                throw new ArgumentNullException();
            }
            if (!this.TargetType.IsAssignableFrom(instance.GetType()))
            {
                throw new ArgumentException();
            }
            if (String.IsNullOrEmpty(rootName))
            {
                throw new ArgumentNullException();
            }
            if (asAttribute && !this.IsCustomSerialized)
            {
                var ex = new XmlSerializationException("The type requires to implement IXmlCustomSerialized to be serialized as an attribute.");
                ex.Data.Add("Type Name", this.TargetType.FullName);
                throw ex;
            }

            this.Serialize(xmlWriter, instance, new XmlSerializationProvider(this, xmlWriter, rootName, asAttribute, itemDefAttributes));
        }
Beispiel #3
0
        /// <exception cref="XmlSerializationException">
        ///   The member contains a derived type which is not explicitly defined by an XmlTypeDefAttribute which is required by the
        ///   current serialization settings.
        /// </exception>
        private void WriteMember(
            XmlSerializableMember member, Object memberValue, Boolean asAttribute,
            IEnumerable <XmlItemDefAttribute> itemAttributeOverrides = null
            )
        {
            XmlItemDefAttributeCollection itemDefAttributes = new XmlItemDefAttributeCollection(member.MemberInfo.ItemDefAttributes);

            if (itemAttributeOverrides != null)
            {
                itemDefAttributes.AddRange(itemAttributeOverrides);
            }

            String nameToWrite;

            if (memberValue != null)
            {
                Type    objectType = memberValue.GetType();
                Boolean typeIsExplicitlyDefined;
                nameToWrite = member.MemberInfo.GetMemberNameByType(objectType, out typeIsExplicitlyDefined);
                if (!typeIsExplicitlyDefined && this.Settings.RequiresExplicitTypeDefinition)
                {
                    var ex = new XmlSerializationException("The member contains a derived type which is not explicitly defined by an XmlTypeDefAttribute which is required by the current serialization settings.");
                    ex.Data.Add("MemberInfo", member.MemberInfo);
                    ex.Data.Add("Derived Type", objectType);
                    throw ex;
                }
            }
            else
            {
                nameToWrite = member.MemberInfo.Name;
            }

            this.WriteNode(nameToWrite, memberValue, asAttribute, itemDefAttributes, member.MemberInfo.Comment);
        }
Beispiel #4
0
        private Object ReadElementContent(Type deserializedType, XmlItemDefAttributeCollection itemDefAttributes = null)
        {
            if (XmlDeserializationProvider.IsNativelyDeserializable(deserializedType))
            {
                return(this.ReadNativeObject(deserializedType, false, itemDefAttributes));
            }

            return(this.Serializer.GetSubSerializer(deserializedType).SubDeserialize(
                       this.XmlReader, this.XmlReader.LocalName, false, itemDefAttributes
                       ));
        }
Beispiel #5
0
        private Object ReadMemberContent(XmlMemberInfo memberInfo, IEnumerable <XmlItemDefAttribute> itemDefAttributeOverrides = null)
        {
            XmlItemDefAttributeCollection itemDefAttributes = new XmlItemDefAttributeCollection(memberInfo.ItemDefAttributes);

            if (itemDefAttributeOverrides != null)
            {
                itemDefAttributes.AddRange(itemDefAttributeOverrides);
            }

            return(this.ReadElementContent(memberInfo.Type, itemDefAttributes));
        }
Beispiel #6
0
        public T ReadElementContent <T>(XmlItemDefAttributeCollection itemDefAttributes = null)
        {
            if (this.XmlReader.ReadState != ReadState.Interactive)
            {
                throw new InvalidOperationException();
            }
            if (this.XmlReader.NodeType != XmlNodeType.Element)
            {
                throw new InvalidOperationException();
            }

            return((T)this.ReadElementContent(typeof(T), itemDefAttributes));
        }
Beispiel #7
0
        /// <exception cref="InvalidOperationException">
        ///   The <see cref="XmlWriter" /> has to be in the write state: <see cref="WriteState.Element" />.
        /// </exception>
        public void WriteAttribute(String name, Object value, XmlItemDefAttributeCollection itemDefAttributes = null)
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException();
            }
            if (this.XmlWriter.WriteState == WriteState.Element)
            {
                throw new InvalidOperationException();
            }

            this.WriteNode(name, value, true, itemDefAttributes);
        }
Beispiel #8
0
        public void WriteElement(
            String name, Object value, XmlItemDefAttributeCollection itemDefAttributes = null, String comment = null
            )
        {
            if (String.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException();
            }
            Contract.Requires <InvalidOperationException>(
                this.XmlWriter.WriteState == WriteState.Content ||
                this.XmlWriter.WriteState == WriteState.Element ||
                this.XmlWriter.WriteState == WriteState.Start
                );

            this.WriteNode(name, value, false, itemDefAttributes, comment);
        }
Beispiel #9
0
        internal XmlSerializationProviderBase(
            IXmlSerializerInternal serializer, String elementName, Boolean asAttribute = false, XmlItemDefAttributeCollection itemDefAttributes = null
            )
        {
            if (serializer == null)
            {
                throw new ArgumentNullException();
            }
            if (String.IsNullOrEmpty(elementName))
            {
                throw new ArgumentNullException();
            }

            this.serializer        = serializer;
            this.elementName       = elementName;
            this.asAttribute       = asAttribute;
            this.itemDefAttributes = itemDefAttributes;
        }
Beispiel #10
0
        /// <exception cref="XmlSerializationException">
        ///   The type requires to implement <see cref="IXmlCustomSerialized" /> to be deserialized as an attribute.
        /// </exception>
        Object IXmlSerializerInternal.SubDeserialize(
            XmlReader xmlReader, String rootName, Boolean asAttribute, XmlItemDefAttributeCollection itemDefAttributes
            )
        {
            if (xmlReader == null)
            {
                throw new ArgumentNullException();
            }
            if (String.IsNullOrEmpty(rootName))
            {
                throw new ArgumentNullException();
            }
            if (asAttribute && !this.IsCustomSerialized)
            {
                var ex = new XmlSerializationException("The type requires to implement IXmlCustomSerialized to be deserialized as an attribute.");
                ex.Data.Add("Type Name", this.TargetType.FullName);
                throw ex;
            }

            return(this.Deserialize(xmlReader, new XmlDeserializationProvider(this, xmlReader, rootName, asAttribute, itemDefAttributes)));
        }
Beispiel #11
0
        internal XmlMemberInfo(
            String name, Type type, Int32 orderIndex, String comment, Boolean isAttribute, Boolean isStatic, Boolean isCollection,
            Type collectionItemType, XmlItemDefAttributeCollection itemDefAttributes, XmlTypeDefAttributeCollection typeDefAttributes
            )
        {
            if (name == null)
            {
                throw new ArgumentNullException();
            }
            if (type == null)
            {
                throw new ArgumentNullException();
            }
            if (itemDefAttributes == null)
            {
                throw new ArgumentNullException();
            }
            if (typeDefAttributes == null)
            {
                throw new ArgumentNullException();
            }
            if (orderIndex < -1)
            {
                throw new ArgumentOutOfRangeException();
            }

            this.name               = name;
            this.type               = type;
            this.orderIndex         = orderIndex;
            this.comment            = comment;
            this.isAttribute        = isAttribute;
            this.isStatic           = isStatic;
            this.isCollection       = isCollection;
            this.collectionItemType = collectionItemType;
            this.itemDefAttributes  = itemDefAttributes;
            this.typeDefAttributes  = typeDefAttributes;
        }
Beispiel #12
0
        internal XmlDeserializationProvider(
            IXmlSerializerInternal serializer, XmlReader reader, String elementName, Boolean asAttribute = false,
            XmlItemDefAttributeCollection itemDefAttributes = null
            ) : base(serializer, elementName, asAttribute, itemDefAttributes)
        {
            if (serializer == null)
            {
                throw new ArgumentNullException();
            }
            if (reader == null)
            {
                throw new ArgumentNullException();
            }
            if (String.IsNullOrEmpty(elementName))
            {
                throw new ArgumentNullException();
            }
            if (reader.ReadState == ReadState.Closed || reader.ReadState == ReadState.Error)
            {
                throw new ArgumentException();
            }

            this.xmlReader = reader;
        }
Beispiel #13
0
        internal XmlSerializationProvider(
            IXmlSerializerInternal serializer, XmlWriter writer, String elementName, Boolean asAttribute = false,
            XmlItemDefAttributeCollection itemDefAttributes = null
            ) : base(serializer, elementName, asAttribute, itemDefAttributes)
        {
            if (serializer == null)
            {
                throw new ArgumentNullException();
            }
            if (writer == null)
            {
                throw new ArgumentNullException();
            }
            if (String.IsNullOrEmpty(elementName))
            {
                throw new ArgumentNullException();
            }
            if (writer.WriteState != WriteState.Closed)
            {
                throw new ArgumentException();
            }

            this.xmlWriter = writer;
        }
Beispiel #14
0
        /// <exception cref="ArgumentException">
        ///   The given <paramref name="type" /> is not natively deserializable.
        /// </exception>
        /// <exception cref="XmlSerializationException">
        ///   A collection can not be deserialized as an attribute.
        /// </exception>
        private Object ReadNativeObject(Type type, Boolean asAttribute, XmlItemDefAttributeCollection itemDefAttributes)
        {
            // Check for null value.
            if (asAttribute)
            {
                if (this.XmlReader.Value == this.Settings.NullAttributeName)
                {
                    return(null);
                }
            }
            else
            {
                if (this.XmlReader.GetAttribute(this.Settings.NullAttributeName) != null)
                {
                    return(null);
                }
            }

            if (typeof(System.Collections.IList).IsAssignableFrom(type) || typeof(System.Collections.IDictionary).IsAssignableFrom(type))
            {
                if (asAttribute)
                {
                    throw new XmlSerializationException("A collection can not be deserialized as an attribute.");
                }

                Contract.Assert(this.XmlReader.NodeType == XmlNodeType.Element);

                Object  collection;
                Boolean isDictionary = typeof(System.Collections.IDictionary).IsAssignableFrom(type);
                if (type.IsClass)
                {
                    ConstructorInfo constructorInfo = type.GetConstructor(new Type[] {});
                    if (constructorInfo == null)
                    {
                        var ex = new XmlSerializationException("An empty constructor is required to deserialize the given IList.");
                        ex.Data.Add("Collection Type", type);
                        throw ex;
                    }

                    try {
                        collection = constructorInfo.Invoke(new Object[] {});
                    } catch (Exception exception) {
                        var ex = new XmlSerializationException("Parameterless constructor of deserializable collection threw exception. See inner exception for more details.", exception);
                        ex.Data.Add("Collection Type", type);
                        throw ex;
                    }
                }
                else
                {
                    // Value type constructor, will never throw exceptions.
                    collection = Activator.CreateInstance(type);
                }

                if (!this.XmlReader.IsEmptyElement)
                {
                    while (this.XmlReader.Read() && this.XmlReader.NodeType != XmlNodeType.EndElement)
                    {
                        if (this.XmlReader.NodeType != XmlNodeType.Element)
                        {
                            continue;
                        }

                        XmlItemDefAttribute attribute;
                        if (!itemDefAttributes.TryGetAttribute(this.XmlReader.LocalName, out attribute))
                        {
                            if (this.Settings.RequiresExplicitCollectionItemDefinition)
                            {
                                var ex = new XmlSerializationException("The collection-node in the XML-Data contains a sub-node with a name which is not explictly defined by an XmlItemDefAttribute which is required by the current serialization settings.");
                                ex.Data.Add("Collection Type", type);
                                ex.Data.Add("Node Name", this.XmlReader.LocalName);
                                throw ex;
                            }
                        }

                        if (!isDictionary)
                        {
                            ((System.Collections.IList)collection).Add(this.ReadElementContent(attribute.Type));
                        }
                        else
                        {
                            Object key   = null;
                            Object value = null;
                            Type[] genericArgumentTypes = type.GetGenericArguments();
                            while (this.XmlReader.Read() && this.XmlReader.NodeType != XmlNodeType.EndElement)
                            {
                                if (this.XmlReader.NodeType != XmlNodeType.Element)
                                {
                                    continue;
                                }

                                if (this.XmlReader.Name == "Key")
                                {
                                    key = this.ReadElementContent(genericArgumentTypes[0]);
                                }
                                else if (this.XmlReader.Name == "Value")
                                {
                                    value = this.ReadElementContent(genericArgumentTypes[1]);
                                }
                            }

                            if (this.XmlReader.NodeType == XmlNodeType.EndElement)
                            {
                                this.XmlReader.ReadEndElement();
                            }

                            try {
                                ((System.Collections.IDictionary)collection).Add(key, value);
                            } catch (Exception exception) {
                                var ex = new XmlSerializationException("Add method of IDictionary implementing collection threw exception. See inner exception for more details.", exception);
                                ex.Data.Add("Collection Type", type);
                                throw ex;
                            }
                        }
                    }

                    if (this.XmlReader.NodeType == XmlNodeType.EndElement)
                    {
                        this.XmlReader.ReadEndElement();
                    }
                }

                return(collection);
            }

            if (type.Name == "KeyValuePair`2" && type.Namespace == "System.Collections.Generic")
            {
                if (asAttribute)
                {
                    throw new XmlSerializationException("The native type KeyValuePair<,> is not deserializable as attribute.");
                }

                Object key   = null;
                Object value = null;
                Type[] genericArgumentTypes = type.GetGenericArguments();
                while (this.XmlReader.Read() && this.XmlReader.NodeType != XmlNodeType.EndElement)
                {
                    if (this.XmlReader.NodeType != XmlNodeType.Element)
                    {
                        continue;
                    }

                    if (this.XmlReader.Name == "Key")
                    {
                        key = this.ReadElementContent(genericArgumentTypes[0]);
                    }
                    else if (this.XmlReader.Name == "Value")
                    {
                        value = this.ReadElementContent(genericArgumentTypes[1]);
                    }
                }

                if (this.XmlReader.NodeType == XmlNodeType.EndElement)
                {
                    this.XmlReader.ReadEndElement();
                }

                return(Activator.CreateInstance(type, key, value));
            }

            String fullTextValue;

            if (!asAttribute)
            {
                fullTextValue = this.XmlReader.ReadElementString();
            }
            else
            {
                fullTextValue = this.XmlReader.Value;
            }

            try {
                if (type.IsEnum)
                {
                    return(Enum.Parse(type, fullTextValue));
                }

                switch (type.FullName)
                {
                case "System.String":
                    return(fullTextValue);

                case "System.Boolean":
                    return(Boolean.Parse(fullTextValue));

                case "System.Byte":
                    return(Byte.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.SByte":
                    return(SByte.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Int16":
                    return(Int16.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Int32":
                    return(Int32.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Int64":
                    return(Int64.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.UInt16":
                    return(UInt16.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.UInt32":
                    return(UInt32.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.UInt64":
                    return(UInt64.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Single":
                    return(Single.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Double":
                    return(Double.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Decimal":
                    return(Decimal.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Char":
                    return(Char.Parse(fullTextValue));

                case "System.DateTime":
                    return(DateTime.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.DBNull":
                    return(DBNull.Value);

                case "System.Version":
                    return(new Version(fullTextValue));

                case "System.DateTimeOffset":
                    return(DateTimeOffset.Parse(fullTextValue, this.Settings.CultureInfo));

                case "System.Guid":
                    return(new Guid(fullTextValue));

                case "System.Drawing.Color":
                    return(System.Drawing.ColorTranslator.FromHtml(fullTextValue));

                case "System.Drawing.Point":
                    String[] pointData = fullTextValue.Split(',');
                    return(new System.Drawing.Point(Int32.Parse(pointData[0]), Int32.Parse(pointData[1])));

                case "System.Drawing.PointF":
                    String[] pointFData = fullTextValue.Split(',');
                    return(new System.Drawing.PointF(Single.Parse(pointFData[0]), Single.Parse(pointFData[1])));

                case "System.Drawing.Rectangle":
                    String[] rectangleData = fullTextValue.Split(',');
                    return(new System.Drawing.Rectangle(
                               Int32.Parse(rectangleData[0]), Int32.Parse(rectangleData[1]),
                               Int32.Parse(rectangleData[2]), Int32.Parse(rectangleData[3])
                               ));

                case "System.Drawing.RectangleF":
                    String[] rectangleFData = fullTextValue.Split(',');
                    return(new System.Drawing.RectangleF(
                               Single.Parse(rectangleFData[0]), Single.Parse(rectangleFData[1]),
                               Single.Parse(rectangleFData[2]), Single.Parse(rectangleFData[3])
                               ));

                /*
                 * case "System.Windows.Point":
                 * return System.Windows.Point.Parse(fullTextValue);
                 * case "System.Windows.Rect":
                 * return System.Windows.Rect.Parse(fullTextValue);
                 * case "System.Windows.Media.Color":
                 * System.Drawing.Color color = System.Drawing.ColorTranslator.FromHtml(fullTextValue);
                 * return System.Windows.Media.Color.FromArgb(color.A, color.R, color.G, color.B);
                 * case "System.Windows.Media.Matrix":
                 * return System.Windows.Media.Matrix.Parse(fullTextValue);
                 * case "System.Windows.Media.Media3D.Matrix3D":
                 * return System.Windows.Media.Media3D.Matrix3D.Parse(fullTextValue);*/

                case "Common.Percentage":
                    return(Percentage.Parse(fullTextValue, this.Settings.CultureInfo));

                case "Common.IO.Path":
                    return(new Path(fullTextValue));
                }
            } catch (Exception exception) {
                var ex = new XmlSerializationException("Parsing of value failed.", exception);
                ex.Data.Add("Type", type);
                ex.Data.Add("Value", fullTextValue);
                throw ex;
            }

            var excep = new ArgumentException("The given type is not natively deserializable.", "type");

            excep.Data.Add("Type", type);
            throw excep;
        }
Beispiel #15
0
        /// <exception cref="ArgumentException">
        ///   The given <paramref name="type" /> is not natively serializable.
        /// </exception>
        /// <exception cref="XmlSerializationException">
        ///   A type which implements <see cref="IEnumerable" /> can not be serialized as an attribute.
        /// </exception>
        private void WriteNativeObject(
            String nodeName, Type type, Object obj, Boolean asAttribute, XmlItemDefAttributeCollection itemDefAttributes
            )
        {
            if (nodeName == null)
            {
                throw new ArgumentNullException();
            }

            if (!asAttribute)
            {
                this.XmlWriter.WriteStartElement(nodeName);
            }
            else
            {
                this.XmlWriter.WriteStartAttribute(nodeName);
            }

            if (obj == null)
            {
                if (asAttribute)
                {
                    this.XmlWriter.WriteValue(this.Settings.NullAttributeName);
                }
                else
                {
                    this.XmlWriter.WriteAttributeString(this.Settings.NullAttributeName, true.ToString(this.Settings.CultureInfo));
                }
            }
            else if (type.FullName != "System.String" && typeof(IEnumerable).IsAssignableFrom(type))
            {
                if (asAttribute)
                {
                    throw new XmlSerializationException("A type which implements IEnumerable can not be serialized as an attribute.");
                }

                foreach (Object item in (IEnumerable)obj)
                {
                    Type   itemType = item.GetType();
                    String itemName;
                    XmlItemDefAttribute itemDefAttribute;

                    if (itemDefAttributes != null && itemDefAttributes.TryGetAttribute(itemType, out itemDefAttribute))
                    {
                        itemName = itemDefAttribute.Name;
                    }
                    else
                    {
                        if (this.Settings.RequiresExplicitCollectionItemDefinition)
                        {
                            var ex = new XmlSerializationException("A collection contains an item which is not explicitly defined by an XmlItemDefAttribute which is required by the current serialization settings.");
                            ex.Data.Add("Collection Type", type);
                            ex.Data.Add("Item Type", itemType);
                            throw ex;
                        }

                        itemName = itemType.FullName;
                        // Mask nested class' full name if required.
                        itemName = itemName.Replace('+', XmlSerializationProviderBase.NestedClassNameMaskCharacter);
                    }

                    this.WriteElement(itemName, item);
                }
            }
            else if (type.Name == "KeyValuePair`2" && type.Namespace == "System.Collections.Generic")
            {
                if (asAttribute)
                {
                    throw new XmlSerializationException("The native type KeyValuePair<,> is not serializable as an attribute.");
                }

                Object key   = type.GetProperty("Key").GetValue(obj, null);
                Object value = type.GetProperty("Value").GetValue(obj, null);
                this.WriteElement("Key", key);
                this.WriteElement("Value", value);
            }
            else if (type.IsEnum)
            {
                this.XmlWriter.WriteString(obj.ToString());
            }
            else
            {
                switch (type.FullName)
                {
                case "System.Drawing.Color":
                    this.XmlWriter.WriteString(System.Drawing.ColorTranslator.ToHtml((System.Drawing.Color)obj));
                    break;

                /*case "System.Windows.Media.Color":
                 * System.Windows.Media.Color mediaColor = (System.Windows.Media.Color)obj;
                 * Color color = Color.FromArgb(mediaColor.A, mediaColor.R, mediaColor.G, mediaColor.B);
                 * this.XmlWriter.WriteString(System.Drawing.ColorTranslator.ToHtml(color));
                 * break;*/

                case "System.Boolean":
                case "System.Byte":
                case "System.SByte":
                case "System.Int16":
                case "System.Int32":
                case "System.Int64":
                case "System.UInt16":
                case "System.UInt32":
                case "System.UInt64":
                case "System.Single":
                case "System.Double":
                case "System.Decimal":
                case "System.Char":
                case "System.String":
                case "System.DateTime":
                case "System.DBNull":
                    this.XmlWriter.WriteString(((IConvertible)obj).ToString(this.Settings.CultureInfo));
                    break;

                case "System.DateTimeOffset":
                    this.XmlWriter.WriteString(((System.DateTimeOffset)obj).ToString(this.Settings.CultureInfo));
                    break;

                /*
                 * case "System.Windows.Point":
                 * this.XmlWriter.WriteString(((System.Windows.Point)obj).ToString(this.Settings.CultureInfo));
                 * break;
                 * case "System.Windows.Rect":
                 * this.XmlWriter.WriteString(((System.Windows.Rect)obj).ToString(this.Settings.CultureInfo));
                 * break;
                 * case "System.Windows.Media.Matrix":
                 * this.XmlWriter.WriteString(((System.Windows.Media.Matrix)obj).ToString(this.Settings.CultureInfo));
                 * break;
                 * case "System.Windows.Media.Media3D.Matrix3D":
                 * this.XmlWriter.WriteString(((System.Windows.Media.Media3D.Matrix3D)obj).ToString(this.Settings.CultureInfo));
                 * break;*/
                case "Common.Percentage":
                    this.XmlWriter.WriteString(((Common.Percentage)obj).ToString(this.Settings.CultureInfo));
                    break;

                case "System.Drawing.Point":
                case "System.Drawing.PointF":
                case "System.Drawing.Rectangle":
                case "System.Drawing.RectangleF":
                case "System.Object":
                case "System.Version":
                case "System.Guid":
                case "Common.IO.Path":
                    this.XmlWriter.WriteString(obj.ToString());
                    break;

                default:
                    throw new ArgumentException("The given type is not natively serializable.", "type");
                }
            }

            if (!asAttribute)
            {
                this.XmlWriter.WriteEndElement();
            }
            else
            {
                this.XmlWriter.WriteEndAttribute();
            }
        }
Beispiel #16
0
        /// <exception cref="ArgumentException">
        ///   The reflected data are invalid.
        /// </exception>
        public static XmlSerializableMember Create(
            MemberInfo memberInfo, ICollection <Type> typesToCache, XmlSerializationSettings settings
            )
        {
            if (memberInfo == null)
            {
                throw new ArgumentNullException();
            }
            if (typesToCache == null)
            {
                throw new ArgumentNullException();
            }

            FieldInfo    fieldInfo    = (memberInfo as FieldInfo);
            PropertyInfo propertyInfo = (memberInfo as PropertyInfo);

            if (fieldInfo == null && propertyInfo == null)
            {
                return(null);
            }

            XmlSerializableMember serializableMember = new XmlSerializableMember(fieldInfo, propertyInfo);
            Type memberType;

            if (fieldInfo != null)
            {
                memberType = fieldInfo.FieldType;
            }
            else
            {
                memberType = propertyInfo.PropertyType;
            }

            // This check includes IList, ICollection, IEnumerable<T>, IList<T>, ICollection<T>.
            Type    collectionItemType = null;
            Boolean isCollection       = (memberType != typeof(String) && typeof(IEnumerable).IsAssignableFrom(memberType));
            Boolean isDictionary       = (typeof(IDictionary).IsAssignableFrom(memberType) || typeof(IDictionary <,>).IsAssignableFrom(memberType));

            if (isCollection)
            {
                if (memberType.IsGenericType)
                {
                    if (!isDictionary)
                    {
                        collectionItemType = memberType.GetGenericArguments()[0];
                    }
                    else
                    {
                        Type[] genericArgumentTypes = memberType.GetGenericArguments();
                        // TODO: There may be a better approach for this.
                        collectionItemType = Type.GetType(String.Format(
                                                              "System.Collections.Generic.KeyValuePair`2[[{0}],[{1}]]",
                                                              genericArgumentTypes[0].AssemblyQualifiedName, genericArgumentTypes[1].AssemblyQualifiedName
                                                              ));
                    }
                }
                else
                {
                    if (!isDictionary)
                    {
                        collectionItemType = typeof(Object);
                    }
                    else
                    {
                        collectionItemType = typeof(KeyValuePair <Object, Object>);
                    }
                }
            }

            Boolean isSerializable = false;
            String  memberName     = null;
            Int32   orderIndex     = 0;
            String  comment        = null;
            Boolean isAttribute    = false;
            XmlItemDefAttributeCollection itemDefAttributes = new XmlItemDefAttributeCollection();
            XmlTypeDefAttributeCollection typeDefAttributes = new XmlTypeDefAttributeCollection();

            if (!settings.RequiresExplicitXmlMetadataAttributes)
            {
                // With this settings, any field or property is serializable by default.
                memberName     = memberInfo.Name;
                isSerializable = true;
            }

            foreach (Attribute attribute in memberInfo.GetCustomAttributes(true))
            {
                if (attribute is XmlNodeAttribute)
                {
                    XmlNodeAttribute nodeAttribute = (XmlNodeAttribute)attribute;

                    if (nodeAttribute.Name == null)
                    {
                        memberName = memberInfo.Name;
                    }
                    else
                    {
                        memberName = nodeAttribute.Name;
                    }

                    if (nodeAttribute.OrderIndex == -1 && settings.RequiresExplicitOrder)
                    {
                        var ex = new ArgumentException("The XmlNodeAttribute on the member does not define an explicit order index as required by the current serialization settings.");
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }
                    comment     = nodeAttribute.Comment;
                    orderIndex  = nodeAttribute.OrderIndex;
                    isAttribute = nodeAttribute.IsAttribute;

                    isSerializable = true;

                    continue;
                }

                if (attribute is XmlNodeTypeDefAttribute)
                {
                    XmlNodeTypeDefAttribute typeDefAttribute = (XmlNodeTypeDefAttribute)attribute;
                    if (memberType == typeDefAttribute.Type)
                    {
                        var ex = new ArgumentException("XmlNodeTypeDefAttribute can not be of the same type as the member.");
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }
                    if (!memberType.IsAssignableFrom(typeDefAttribute.Type))
                    {
                        var ex = new ArgumentException("XmlNodeTypeDefAttribute defined with a type which is not castable to the member's type.");
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }

                    typeDefAttributes.Add(typeDefAttribute);
                }

                if (attribute is XmlItemDefAttribute)
                {
                    if (!isCollection)
                    {
                        var ex = new ArgumentException("XmlItemDefAttribute defined for a member of a type that does not implement the IEnumerable or IEnumerable<T> interface.");
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }

                    XmlItemDefAttribute itemDefAttribute = (XmlItemDefAttribute)attribute;

                    // Check if the type defined by the XmlItemDefAttribute is derived or equal to the collection's item type.
                    if (!collectionItemType.IsAssignableFrom(itemDefAttribute.Type))
                    {
                        var ex = new ArgumentException("The type given by the XmlItemDefAttribute is not assignable to the item type of the collection.");
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }

                    // Check if we have an item attribute for this type already.
                    if (itemDefAttributes.Contains(itemDefAttribute.Type))
                    {
                        var ex = new ArgumentException("Only one XmlItemDefAttribute is allowed for the same item type.");
                        ex.Data.Add("Item Type", itemDefAttribute.Type);
                        ex.Data.Add("Member Info", memberInfo);
                        throw ex;
                    }

                    itemDefAttributes.Add(itemDefAttribute);
                    typesToCache.Add(itemDefAttribute.Type);
                }
            }

            if (!isSerializable)
            {
                return(null);
            }

            if (settings.RequiresExplicitCollectionItemDefinition && isCollection && !itemDefAttributes.ContainsType(collectionItemType))
            {
                var ex = new ArgumentException("The collection member does not define an explicit XmlItemDefAttribute for its type as required by the current serialization settings.");
                ex.Data.Add("Member Info", memberInfo);
                ex.Data.Add("Item Type", collectionItemType);
                throw ex;
            }

            Boolean isStatic;

            if (fieldInfo != null)
            {
                isStatic = fieldInfo.IsStatic;
            }
            else
            {
                // We need at least one accessor to check whether the property is static etc.
                MethodInfo[] accessors = propertyInfo.GetAccessors(true);
                if (accessors.Length == 0)
                {
                    var ex = new ArgumentException("A XML-Serializable property requires at least one accessor.");
                    ex.Data.Add("Property Info", serializableMember.MemberInfo);
                    throw ex;
                }

                MethodInfo accessor = accessors[0];
                if (accessor.IsAbstract)
                {
                    var ex = new ArgumentException("A XML-Serializable property can not be abstract.");
                    ex.Data.Add("Property Info", serializableMember.MemberInfo);
                    throw ex;
                }

                isStatic = accessor.IsStatic;
            }

            // If any field or property should be serializable, we may not include static members.
            if (isStatic && !settings.RequiresExplicitXmlMetadataAttributes)
            {
                return(null);
            }

            serializableMember.memberInfo = new XmlMemberInfo(
                memberName, memberType, orderIndex, comment, isAttribute, isStatic, isCollection, collectionItemType,
                itemDefAttributes, typeDefAttributes
                );

            if (collectionItemType != null)
            {
                typesToCache.Add(collectionItemType);
            }
            typesToCache.Add(memberType);
            return(serializableMember);
        }