/// <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); }
/// <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; }