コード例 #1
0
        /// <summary>
        ///   Deserializes an <see cref="object"/> from the given <see cref="Stream"/> for the given <see cref="Type"/>.
        /// </summary>
        /// <param name="serializationStream">The stream to read the object from.</param>
        /// <param name="objectType">The type of object to create.</param>
        /// <returns>The deserialized object.</returns>
        private object Deserialize([NotNull] Stream serializationStream, Type objectType)
        {
            object deserialized;

            // create xml reader from stream
            using (XmlTextReader reader = new XmlTextReader(serializationStream))
            {
                DeserializationCallBackList.Clear();
                deserialized = InitializeObject(reader, new FormatterConverter(), objectType);
            }

            foreach (IDeserializationCallback callBack in DeserializationCallBackList)
            {
                callBack.OnDeserialization(null);
            }

            return(deserialized);
        }
コード例 #2
0
        /// <summary>
        ///   Reads an <see cref="object"/> from the XML and initializes it.
        /// </summary>
        /// <param name="reader">The XMLTextReader to read from.</param>
        /// <param name="converter">
        ///   The <see cref="System.Runtime.Serialization.FormatterConverter">converter</see> used to parse the values from the XML.
        /// </param>
        /// <param name="objectType">The type of the object to create.</param>
        /// <returns>The recreated object.</returns>
        /// <exception cref="SerializationException">
        ///   <para>The stream contained an element not found in <paramref name="objectType"/>.</para>
        ///   <para>-or</para>
        ///   <para>A List member in the object is a <see langword="null"/>.</para>
        ///   <para>-or-</para>
        ///   <para>More than one member was found for an XML tag.</para>
        /// </exception>
        private object InitializeObject(
            [NotNull] XmlTextReader reader,
            [NotNull] FormatterConverter converter,
            Type objectType)
        {
            Type actualType;
            ISurrogateSelector      selector1;
            ISerializationSurrogate serializationSurrogate;
            SerializationInfo       info;
            object initializedObject = null;

            // check if a type attribute is present
            if (reader.HasAttributes)
            {
                // if so, get the type
                string actualTypeName = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
                Debug.Assert(actualTypeName != null);
                actualType = Binder.BindToType("", actualTypeName);
                Debug.Assert(actualType != null);
            }
            else
            {
                if (objectType == null)
                {
                    throw new ArgumentNullException("objectType");
                }
                // passed type is actual type.
                actualType = objectType;
            }

            // check whether a surrogate should be used, ISerializable is implemented or reflection is needed.
            if ((SurrogateSelector != null) &&
                ((serializationSurrogate = SurrogateSelector.GetSurrogate(actualType, Context, out selector1)) != null))
            {
                // use surrogate
                info = new SerializationInfo(actualType, converter);

                if (!actualType.IsPrimitive)
                {
                    // create a instance of the type.
                    initializedObject = FormatterServices.GetUninitializedObject(actualType);

                    // read the first element
                    reader.ReadStartElement();

                    while (reader.IsStartElement())
                    {
                        // determine type
                        string typeName = reader.GetAttribute("type", "http://www.w3.org/2001/XMLSchema-instance");
                        Debug.Assert(typeName != null);
                        Type type = Binder.BindToType("", typeName);

                        Debug.Assert(type != null);
                        Debug.Assert(reader.Name != null);

                        // using ISerializable
                        info.AddValue(reader.Name, DetermineValue(reader, converter, type));
                        reader.ReadEndElement();
                    }
                    // use the surrogate to populate the instance
                    initializedObject = serializationSurrogate.SetObjectData(
                        initializedObject,
                        info,
                        Context,
                        SurrogateSelector);
                }
            }
            else if (typeof(ISerializable).IsAssignableFrom(actualType))
            {
                // The item implements ISerializable. Create a SerializationInfo object
                info = new SerializationInfo(actualType, converter);

                // Populate the collection
                PopulateSerializationInfo(reader, converter, info);

                // Get the specialized Serialization Constructor
                ConstructorInfo ctor =
                    actualType.GetConstructor(new[] { typeof(SerializationInfo), typeof(StreamingContext) });
                if (ctor == null)
                {
                    throw new SerializationException("ISerializable type does not support deserialization");
                }

                // Create the object
                initializedObject = ctor.Invoke(new object[] { info, Context });
            }
            else
            {
                // The item does not implement ISerializable. Use reflection to get public
                // fields and properties.
                initializedObject = FormatterServices.GetUninitializedObject(actualType);
                Debug.Assert(initializedObject != null);

                List <MemberInfo> memberList = new List <MemberInfo>();
                List <object>     valuesList = new List <object>();
                // read the first element.
                reader.ReadStartElement();

                while (reader.IsStartElement())
                {
                    // Get public fields and members of this type.
                    MemberInfo[] possibleMembers = actualType.GetMember(
                        reader.Name,
                        MemberTypes.Property | MemberTypes.Field,
                        BindingFlags.Public | BindingFlags.DeclaredOnly |
                        BindingFlags.Instance);

                    if (possibleMembers.Length < 1)
                    {
                        throw new SerializationException(
                                  // ReSharper disable once AssignNullToNotNullAttribute
                                  string.Format(Resources.XmlFormatter_InitializeObject_ElementNotFound, reader.Name));
                    }

                    if (possibleMembers.Length > 1)
                    {
                        throw new SerializationException(
                                  string.Format(
                                      // ReSharper disable once AssignNullToNotNullAttribute
                                      Resources.XmlFormatter_InitializeObject_MoreThanOneMemberFound,
                                      reader.Name));
                    }

                    // ReSharper disable once PossibleNullReferenceException
                    if (typeof(IList).IsAssignableFrom(possibleMembers[0].ReflectedType))
                    {
                        // the type is a list, get the list from the initialized object.
                        IList list = GetMemberValue(initializedObject, possibleMembers[0]) as IList;

                        // ReSharper disable PossibleNullReferenceException
                        if (list == null)
                        {
                            throw new SerializationException(
                                      string.Format(
                                          // ReSharper disable once AssignNullToNotNullAttribute
                                          Resources.XmlFormatter_InitializeObject_MemberListIsNull,
                                          possibleMembers[0].DeclaringType.FullName,
                                          possibleMembers[0].Name));
                        }
                        // ReSharper restore PossibleNullReferenceException

                        // read the next element
                        reader.ReadStartElement();

                        while (reader.IsStartElement())
                        {
                            if (!reader.IsEmptyElement)
                            {
                                // Initialize the object (recursive call)
                                // ReSharper disable PossibleNullReferenceException
                                object listItem = InitializeObject(
                                    reader,
                                    converter,
                                    possibleMembers[0].ReflectedType.GetElementType());
                                // ReSharper restore PossibleNullReferenceException
                                list.Add(listItem);
                                reader.ReadEndElement();
                            }
                            else
                            {
                                reader.ReadStartElement();
                            }
                        }
                    }
                    else
                    {
                        // determine the value.
                        // ReSharper disable once AssignNullToNotNullAttribute
                        object value = DetermineValue(reader, converter, possibleMembers[0].ReflectedType);
                        memberList.Add(possibleMembers[0]);
                        valuesList.Add(value);
                    }
                }
                if (memberList.Count > 0)
                {
                    initializedObject = FormatterServices.PopulateObjectMembers(
                        initializedObject,
                        memberList.ToArray(),
                        valuesList.ToArray());
                    Debug.Assert(initializedObject != null);
                }
                reader.ReadEndElement();
            }

            if ((initializedObject as IDeserializationCallback) != null)
            {
                DeserializationCallBackList.Add(initializedObject);
            }
            return(initializedObject);
        }