private static Type GetWrittenType(XmlReader reader, string elementName, Type objType) { var writtenTypeName = reader.GetAttribute("type"); if (writtenTypeName == null) return GetSerializedType(objType); Type writtenType; if (!g_typeNameToType.TryGetValue(writtenTypeName, out writtenType)) { writtenType = Type.GetType(writtenTypeName) ?? AppDomain.CurrentDomain.GetAssemblies() .Select(assembly => assembly.GetType(writtenTypeName)) .Where(type => type != null) .FirstOrDefault(); if (writtenType == null) throw new XmlException("XML suggests unknown type " + writtenTypeName, null, reader.LineNumber(), reader.LinePosition()); g_typeNameToType.Add(writtenTypeName, writtenType); } if (!IsAssignableFrom(objType, writtenType)) throw new XmlException("XML suggests type " + writtenTypeName + " that is not assignable to expected type " + objType.Name, null, reader.LineNumber(), reader.LinePosition()); return writtenType; }
/// <summary> /// Reads in fields and properties of an object from an XML reader. /// </summary> /// <remarks> /// <para> /// You can limit the deserialisation to members that have the specified limitation attribute. /// This limitation is applied only to instances of classes that have /// LimitedSerializationAttribute. ///</para> ///<para> /// The XML reader is assumed to be positioned on the first child element of /// the root element of the serialised 'obj' to be read. At successful return, /// the XML reader will be positioned at the end element of the serialised 'obj'. /// A log message is produced if an unknown serialised member is encountered. /// It is guaranteed that all fields and properties (marked with <paramref name="limitationAttribute"/> /// get a value exactly once, lest an exception is thrown. /// </para> /// </remarks> /// <param name="reader">Where to read the serialised values.</param> /// <param name="obj">The object whose members to deserialise.</param> /// <param name="limitationAttribute">Limit the deserialisation to members with this attribute, /// or deserialise all members if limitationAttribute is a null reference.</param> /// <seealso cref="AW2.Helpers.LimitedSerializationAttribute"/> private static void DeserializeFieldsAndPropertiesXml(XmlReader reader, object obj, Type limitationAttribute, bool tolerant) { try { var type = obj.GetType(); var finder = new FieldAndPropertyFinder(obj.GetType(), limitationAttribute, tolerant); // NOTE: There is no guarantee about the order of the members. while (reader.IsStartElement()) { var member = finder.Find(reader.Name); if (member == null) { reader.Skip(); continue; } var memberLimitationAttribute = GetLimitationAttribute(member, limitationAttribute); var value = DeserializeXml(reader, reader.Name, member.ValueType, memberLimitationAttribute, tolerant); member.SetValue(obj, value); } finder.CheckForMissing(); } catch (MemberSerializationException e) { e.LineNumber = reader.LineNumber(); throw; } }