Example #1
0
        /// <summary>
        /// Writes the XML element to the xml element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="memberValue">The member value.</param>
        /// <param name="modelType">Type of the model.</param>
        private void WriteXmlElement(ISerializationContext <XmlSerializationContextInfo> context, XElement element, string elementName, MemberValue memberValue, Type modelType)
        {
            var          contextInfo       = context.Context;
            var          namespacePrefix   = GetNamespacePrefix();
            var          stringBuilder     = new StringBuilder();
            var          xmlWriterSettings = new XmlWriterSettings();
            XmlNamespace xmlNamespace      = null;

            xmlWriterSettings.OmitXmlDeclaration = true;
            xmlWriterSettings.CheckCharacters    = false;
            xmlWriterSettings.ConformanceLevel   = ConformanceLevel.Fragment;
            xmlWriterSettings.NamespaceHandling  = NamespaceHandling.OmitDuplicates;

#if XAMARIN
            var defaultNamespace = "http://www.w3.org/2000/xmlns/";
#endif

            using (var xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings))
            {
                if (memberValue.Value == null)
                {
                    xmlWriter.WriteStartElement(elementName);

#if XAMARIN
                    xmlWriter.WriteAttributeString("xmlns", namespacePrefix, defaultNamespace, "http://catel.codeplex.com");
#endif

                    xmlWriter.WriteAttributeString(namespacePrefix, "IsNull", null, "true");
                    xmlWriter.WriteEndElement();
                }
                else
                {
                    var memberTypeToSerialize = memberValue.GetBestMemberType();
                    var serializer            = _dataContractSerializerFactory.GetDataContractSerializer(modelType, memberTypeToSerialize, elementName, null, null);

                    ReferenceInfo referenceInfo    = null;
                    var           serializeElement = true;

                    if (memberValue.MemberGroup != SerializationMemberGroup.Collection)
                    {
                        var isClassType = memberTypeToSerialize.IsClassType();
                        if (isClassType)
                        {
                            var referenceManager = context.ReferenceManager;
                            referenceInfo = referenceManager.GetInfo(memberValue.Value);

                            if (!referenceInfo.IsFirstUsage)
                            {
                                // Note: we don't want to call GetSafeFullName if we don't have to
                                if (LogManager.IsDebugEnabled ?? false)
                                {
                                    Log.Debug("Existing reference detected for element type '{0}' with id '{1}', only storing id", memberTypeToSerialize.GetSafeFullName(false), referenceInfo.Id);
                                }

                                //serializer.WriteStartObject(xmlWriter, memberValue.Value);
                                xmlWriter.WriteStartElement(elementName);

                                xmlWriter.WriteAttributeString(namespacePrefix, GraphRefId, null, referenceInfo.Id.ToString());

                                //serializer.WriteEndObject(xmlWriter);
                                xmlWriter.WriteEndElement();

                                serializeElement = false;
                            }
                        }
                    }

                    if (serializeElement)
                    {
                        //var xmlSerializer = new System.Xml.Serialization.XmlSerializer(memberTypeToSerialize, namespacePrefix);
                        //xmlSerializer.Serialize(xmlWriter, memberValue.Value);

                        xmlWriter.WriteStartElement(elementName);

                        xmlNamespace = _xmlNamespaceManager.GetNamespace(memberTypeToSerialize, namespacePrefix);
                        if (xmlNamespace != null)
                        {
                            xmlWriter.WriteAttributeString("xmlns", xmlNamespace.Prefix, null, xmlNamespace.Uri);
                        }

                        if (referenceInfo != null)
                        {
                            xmlWriter.WriteAttributeString(namespacePrefix, GraphId, null, referenceInfo.Id.ToString());
                        }

                        if (memberTypeToSerialize != memberValue.MemberType)
                        {
                            var memberTypeToSerializerName = TypeHelper.GetTypeName(memberTypeToSerialize.FullName);
                            xmlWriter.WriteAttributeString(namespacePrefix, "type", null, memberTypeToSerializerName);
                        }

                        // In special cases, we need to write our own collection items. One case is where a custom ModelBase
                        // implements IList and gets inside a StackOverflow
                        var serialized = false;
                        if (ShouldSerializeModelAsCollection(memberValue.GetBestMemberType()))
                        {
                            var collection = memberValue.Value as IEnumerable;
                            if (collection != null)
                            {
                                foreach (var item in collection)
                                {
                                    var subItemElementName = GetXmlElementName(item.GetType(), item, null);
                                    xmlWriter.WriteStartElement(subItemElementName);

                                    serializer.WriteObjectContent(xmlWriter, item);

                                    xmlWriter.WriteEndElement();
                                }

                                serialized = true;
                            }
                        }

                        if (!serialized)
                        {
                            serializer.WriteObjectContent(xmlWriter, memberValue.Value);
                        }

                        xmlWriter.WriteEndElement();
                    }
                }
            }

            EnsureNamespaceInXmlDocument(element, xmlNamespace);

            var childContent = stringBuilder.ToString();
            var childElement = XElement.Parse(childContent);
            element.Add(childElement);
        }
Example #2
0
        /// <summary>
        /// Writes the XML element to the xml element.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="element">The element.</param>
        /// <param name="elementName">Name of the element.</param>
        /// <param name="memberValue">The member value.</param>
        /// <param name="modelType">Type of the model.</param>
        private void WriteXmlElement(ISerializationContext <XmlSerializationContextInfo> context, XElement element, string elementName, MemberValue memberValue, Type modelType)
        {
            var          contextInfo       = context.Context;
            var          namespacePrefix   = GetNamespacePrefix();
            var          stringBuilder     = new StringBuilder();
            var          xmlWriterSettings = new XmlWriterSettings();
            XmlNamespace xmlNamespace      = null;

            xmlWriterSettings.OmitXmlDeclaration = true;
            xmlWriterSettings.CheckCharacters    = false;
            xmlWriterSettings.ConformanceLevel   = ConformanceLevel.Fragment;
            xmlWriterSettings.NamespaceHandling  = NamespaceHandling.OmitDuplicates;

            using (var xmlWriter = XmlWriter.Create(stringBuilder, xmlWriterSettings))
            {
                var memberTypeToSerialize = memberValue.Value != null?memberValue.Value.GetType() : typeof(object);

                var serializer = _dataContractSerializerFactory.GetDataContractSerializer(modelType, memberTypeToSerialize, elementName, null, memberValue.Value);

                if (memberValue.Value == null)
                {
                    xmlWriter.WriteStartElement(elementName);
                    xmlWriter.WriteAttributeString(namespacePrefix, "IsNull", null, "true");
                    xmlWriter.WriteEndElement();
                }
                else
                {
                    ReferenceInfo referenceInfo    = null;
                    bool          serializeElement = true;
                    var           isClassType      = memberTypeToSerialize.IsClassType();
                    if (isClassType)
                    {
                        var referenceManager = context.ReferenceManager;
                        referenceInfo = referenceManager.GetInfo(memberValue.Value);

                        if (!referenceInfo.IsFirstUsage)
                        {
                            Log.Debug("Existing reference detected for element type '{0}' with id '{1}', only storing id", memberTypeToSerialize.GetSafeFullName(), referenceInfo.Id);

                            //serializer.WriteStartObject(xmlWriter, memberValue.Value);
                            xmlWriter.WriteStartElement(elementName);

                            xmlWriter.WriteAttributeString(namespacePrefix, GraphRefId, null, referenceInfo.Id.ToString());

                            //serializer.WriteEndObject(xmlWriter);
                            xmlWriter.WriteEndElement();

                            serializeElement = false;
                        }
                    }

                    if (serializeElement)
                    {
                        //var xmlSerializer = new System.Xml.Serialization.XmlSerializer(memberTypeToSerialize, namespacePrefix);
                        //xmlSerializer.Serialize(xmlWriter, memberValue.Value);

                        xmlWriter.WriteStartElement(elementName);

                        xmlNamespace = _xmlNamespaceManager.GetNamespace(memberTypeToSerialize, namespacePrefix);
                        if (xmlNamespace != null)
                        {
                            xmlWriter.WriteAttributeString("xmlns", xmlNamespace.Prefix, null, xmlNamespace.Uri);
                        }

                        if (referenceInfo != null)
                        {
                            xmlWriter.WriteAttributeString(namespacePrefix, GraphId, null, referenceInfo.Id.ToString());
                        }

                        if (memberTypeToSerialize != memberValue.Type)
                        {
                            var memberTypeToSerializerName = TypeHelper.GetTypeName(memberTypeToSerialize.FullName);
                            xmlWriter.WriteAttributeString(namespacePrefix, "type", null, memberTypeToSerializerName);
                        }

                        serializer.WriteObjectContent(xmlWriter, memberValue.Value);

                        xmlWriter.WriteEndElement();
                    }
                }
            }

            EnsureNamespaceInXmlDocument(element, xmlNamespace);

            var childContent = stringBuilder.ToString();
            var childElement = XElement.Parse(childContent);

            element.Add(childElement);
        }
            private XmlNamespace GetTypeNamespace(Type type, string preferredPrefix)
            {
                var typeNamespace = type.Namespace;
                //if (_xmlNamespacesByDotNetNamespace.ContainsKey(typeNamespace))
                //{
                //    return _xmlNamespacesByDotNetNamespace[typeNamespace];
                //}

                string prefix = preferredPrefix;
                string uri = string.Format("{0}{1}", NamespaceUriPrefix, typeNamespace);

                if (typeof (IEnumerable).IsAssignableFromEx(type))
                {
                    prefix = ArraySchemaName;
                    uri = ArraySchemaUrl;
                }
                else
                {
                    if (!_prefixCounter.ContainsKey(preferredPrefix))
                    {
                        _prefixCounter[preferredPrefix] = 1;
                    }

                    prefix = string.Format("{0}{1}", prefix, _prefixCounter[preferredPrefix]++);
                }

                // TODO: Read xml namespace from attribute

                var xmlNamespace = new XmlNamespace(prefix, uri);

                _xmlNamespaces.Add(type, xmlNamespace);
                //_xmlNamespacesByDotNetNamespace.Add(typeNamespace, xmlNamespace);

                return xmlNamespace;
            }