示例#1
0
        /// <summary>
        /// Gets the object from XML element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="memberValue">The member value.</param>
        /// <param name="modelType">Type of the model.</param>
        /// <returns>Object or <c>null</c>.</returns>
        /// <remarks>Note that this method can cause exceptions. The caller will handle them.</remarks>
        private object GetObjectFromXmlElement(ISerializationContext <XmlSerializationContextInfo> context, XElement element, MemberValue memberValue, Type modelType)
        {
            object value   = null;
            string xmlName = element.Name.LocalName;

            var propertyTypeToDeserialize = memberValue.Type;

            var isNullAttribute = element.Attribute("IsNull");
            var isNull          = (isNullAttribute != null) ? StringToObjectHelper.ToBool(isNullAttribute.Value) : false;

            if (isNull)
            {
                return(null);
            }

            var graphRefIdAttribute = element.Attribute(GraphRefId);

            if (graphRefIdAttribute != null)
            {
                var graphId = int.Parse(graphRefIdAttribute.Value);

                var referenceManager = context.ReferenceManager;
                var referenceInfo    = referenceManager.GetInfoById(graphId);
                if (referenceInfo == null)
                {
                    Log.Error("Expected to find graph object with id '{0}' in ReferenceManager, but it was not found. Defaulting value for member '{1}' to null", graphId, element.Name);
                    return(null);
                }

                return(referenceInfo.Instance);
            }

            var typeAttribute  = element.Attribute("type"); // .GetAttribute("type", "http://catel.codeplex.com");
            var attributeValue = (typeAttribute != null) ? typeAttribute.Value : null;

            if (!string.IsNullOrEmpty(attributeValue))
            {
                var typeToDeserialize = TypeCache.GetTypeWithoutAssembly(attributeValue);
                if (typeToDeserialize != null && propertyTypeToDeserialize != typeToDeserialize)
                {
                    Log.Debug("Property type for property '{0}' is '{1}' but found type info that it should be deserialized as '{2}'",
                              memberValue.Name, memberValue.Type.FullName, attributeValue);

                    propertyTypeToDeserialize = typeToDeserialize;
                }
                else
                {
                    Log.Warning("Property type for property '{0}' is '{1}' but found type info that it should be deserialized as '{2}'. Unfortunately the type cannot be found so the deserialization will probably fail.",
                                memberValue.Name, memberValue.Type.FullName, attributeValue);
                }
            }

            var serializer = _dataContractSerializerFactory.GetDataContractSerializer(modelType, propertyTypeToDeserialize, xmlName, null, null);

            using (var xmlReader = element.CreateReader())
            {
                value = serializer.ReadObject(xmlReader, false);
            }

            return(value);
        }
示例#2
0
        /// <summary>
        /// Gets the object from XML element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="memberValue">The member value.</param>
        /// <param name="modelType">Type of the model.</param>
        /// <returns>Object or <c>null</c>.</returns>
        /// <remarks>Note that this method can cause exceptions. The caller will handle them.</remarks>
        private object GetObjectFromXmlElement(ISerializationContext <XmlSerializationContextInfo> context, XElement element, MemberValue memberValue, Type modelType)
        {
            object value   = null;
            var    xmlName = element.Name.LocalName;

            var propertyTypeToDeserialize = memberValue.MemberType;

            var isNullAttribute = element.Attribute("IsNull");
            var isNull          = (isNullAttribute != null) ? StringToObjectHelper.ToBool(isNullAttribute.Value) : false;

            if (isNull)
            {
                return(null);
            }

            var graphRefIdAttribute = element.Attribute(GraphRefId);

            if (graphRefIdAttribute != null)
            {
                var graphId = int.Parse(graphRefIdAttribute.Value);

                var referenceManager = context.ReferenceManager;
                var referenceInfo    = referenceManager.GetInfoById(graphId);
                if (referenceInfo == null)
                {
                    Log.Error("Expected to find graph object with id '{0}' in ReferenceManager, but it was not found. Defaulting value for member '{1}' to null", graphId, element.Name);
                    return(null);
                }

                return(referenceInfo.Instance);
            }

            var typeAttribute  = element.Attribute("type"); // .GetAttribute("type", "http://catel.codeplex.com");
            var attributeValue = (typeAttribute != null) ? typeAttribute.Value : null;

            if (!string.IsNullOrEmpty(attributeValue))
            {
                var typeToDeserialize = TypeCache.GetTypeWithoutAssembly(attributeValue);
                if (typeToDeserialize != null && propertyTypeToDeserialize != typeToDeserialize)
                {
                    Log.Debug("Property type for property '{0}' is '{1}' but found type info that it should be deserialized as '{2}'",
                              memberValue.Name, memberValue.MemberType.FullName, attributeValue);

                    propertyTypeToDeserialize = typeToDeserialize;
                }
                else
                {
                    Log.Warning("Property type for property '{0}' is '{1}' but found type info that it should be deserialized as '{2}'. Unfortunately the type cannot be found so the deserialization will probably fail.",
                                memberValue.Name, memberValue.MemberType.FullName, attributeValue);
                }
            }

            var isDeserialized = false;

            if (propertyTypeToDeserialize == typeof(string) && ShouldSerializeUsingParseAndToString(memberValue, false))
            {
                var tempValue = memberValue.Value;
                memberValue.Value = element.Value;

                var parsedValue = DeserializeUsingObjectParse(context, memberValue);
                if (parsedValue != null)
                {
                    value = parsedValue;

                    isDeserialized = true;
                }
                else
                {
                    memberValue.Value = tempValue;
                }
            }

            if (!isDeserialized && ShouldSerializeModelAsCollection(propertyTypeToDeserialize))
            {
                var collection = value as IList;
                if (collection == null)
                {
                    collection = CreateModelInstance(propertyTypeToDeserialize) as IList;
                }

                if (collection == null)
                {
                    throw Log.ErrorAndCreateException <NotSupportedException>("Cannot deserialize type '{0}', it should implement IList in order to be deserialized", propertyTypeToDeserialize.GetSafeFullName(false));
                }

                var realCollectionType = collection.GetType();
                var childElementType   = realCollectionType.GetCollectionElementType();
                if (childElementType == null)
                {
                    throw Log.ErrorAndCreateException <NotSupportedException>("Cannot deserialize type '{0}', could not determine the element type of the collection", propertyTypeToDeserialize.GetSafeFullName(false));
                }

                var serializer = _dataContractSerializerFactory.GetDataContractSerializer(propertyTypeToDeserialize, childElementType, xmlName, null, null);

                var childElements = element.Elements();
                foreach (var childElement in childElements)
                {
                    using (var xmlReader = childElement.CreateReader())
                    {
                        var childValue = serializer.ReadObject(xmlReader, false);
                        if (childValue != null)
                        {
                            collection.Add(childValue);
                        }
                    }
                }

                value = collection;

                isDeserialized = true;
            }

            if (!isDeserialized)
            {
                var serializer = _dataContractSerializerFactory.GetDataContractSerializer(modelType, propertyTypeToDeserialize, xmlName, null, null);

                using (var xmlReader = element.CreateReader())
                {
                    value = serializer.ReadObject(xmlReader, false);
                }
            }

            // Fix for CTL-555
            var graphIdAttribute = element.Attribute(GraphId);

            if (graphIdAttribute != null)
            {
                var graphId = int.Parse(graphIdAttribute.Value);

                var referenceManager = context.ReferenceManager;
                referenceManager.RegisterManually(graphId, value);
            }

            return(value);
        }