internal void WriteXml(XmlWriter writer, object value, XmlMember member, XmlTypeContext typeContext) { XmlMember lastMember = currentMember; XmlContract lastContract = currentContract; currentMember = member; currentContract = typeContext.Contract; typeContext.WriteXml(writer, value, this); currentMember = lastMember; currentContract = lastContract; }
internal object ReadXml(XmlReader reader, XmlMember member, XmlTypeContext typeContext) { XmlMember lastMember = currentMember; XmlContract lastContract = currentContract; currentMember = member; currentContract = typeContext.Contract; object value = typeContext.ReadXml(reader, this); currentMember = lastMember; currentContract = lastContract; return(value); }
private void SerializeBody(XmlWriter writer, object value, Type memberType, XmlMember member) { if (writer == null) { throw new ArgumentNullException("writer"); } if (value == null) { WriteNull(writer, memberType, member); } else { XmlTypeContext typeContext = settings.GetTypeContext(memberType); WriteXml(writer, value, member ?? typeContext.Contract.Root, typeContext); } }
private object Deserialize(XmlReader reader, Type valueType, XmlMember member) { if (reader == null) { throw new ArgumentNullException("reader"); } if (valueType == null) { throw new ArgumentNullException("valueType"); } if (initialState && reader.NodeType == XmlNodeType.None) { initialState = false; while (reader.NodeType != XmlNodeType.Element) { if (!reader.Read()) { return(null); } } } if (reader.NodeType == XmlNodeType.Element) { if (!ReadValueType(reader, ref valueType)) { reader.Skip(); return(null); } } XmlTypeContext typeInfo = settings.GetTypeContext(valueType); if (member == null) { member = typeInfo.Contract.Root; } return(ReadXml(reader, member, typeInfo)); }
private XmlTypeContext CreateTypeContext(Type valueType, XmlTypeContext context) { IXmlConverter readConverter = null; IXmlConverter writeConverter = null; foreach (var converter in converters.Concat(DefaultConverters)) { if (readConverter == null && converter.CanRead(valueType)) { readConverter = converter; if (writeConverter != null) { break; } } if (writeConverter == null && converter.CanWrite(valueType)) { writeConverter = converter; if (readConverter != null) { break; } } } var contract = contractResolver.ResolveContract(valueType); readConverter = GetConverter(contract, readConverter); writeConverter = GetConverter(contract, writeConverter); context = new XmlTypeContext(contract, readConverter, writeConverter); typeContextCache.TryAdd(valueType, context); return(context); }
internal void WriteElement(XmlWriter writer, object value, XmlMember member, XmlTypeContext context, Type valueType, bool shouldWriteTypeName) { var contractValueType = context.Contract.ValueType; if (!Settings.IsBuildingObjectGraph) { writer.WriteStartElement(member.Name); if (initialState) { initialState = false; WriteNamespaces(writer); } if (shouldWriteTypeName) { WriteTypeName(writer, valueType); } } object referencedValue = value; if (value is IAnyOptional optValue && optValue.HasValue) { contractValueType = optValue.GetInnerType(); referencedValue = optValue.Value; } var isCollection = !contractValueType.Equals(typeof(string)) && contractValueType.IsEnumerable(); var isModel = contractValueType.IsClass && contractValueType != typeof(string); if (context.Contract is XmlObjectContract && isModel && !isCollection) { long id = settings.ReferenceHandlingGenerator.GetId(referencedValue, out bool firstTime); if (Settings.IsBuildingObjectGraph) { if (firstTime) { _xmlReferenceLevelLookup.Add(id, currentLevel); currentLevel++; WriteXml(writer, value, member, context); currentLevel--; } else { if (Settings.ReferenceHandling == XmlReferenceHandling.Throw) { throw new Exception("Found reference loop. Please set ReferenceHandling setting to XmlReferenceHandling.Handle"); } if (currentLevel < _xmlReferenceLevelLookup[id]) { _xmlReferenceLevelLookup[id] = currentLevel; } } // stop processing return; } bool isExpansionElement = Settings.ReferenceExpansion == XmlReferenceExpansion.FirstAccessed ? firstTime : currentLevel == _xmlReferenceLevelLookup[id]; if (isExpansionElement) { if (Settings.ReferenceExpansion == XmlReferenceExpansion.HighestLevel) { // element should only be expanded once - prevents expansion of elements on the same level _xmlReferenceLevelLookup[id] = -1; } if (Settings.ReferenceHandling == XmlReferenceHandling.Handle) { writer.WriteAttributeString(Settings.ReferenceHandlingIdName, id.ToString()); } currentLevel++; WriteXml(writer, value, member, context); currentLevel--; } else { if (Settings.ReferenceHandling == XmlReferenceHandling.Throw) { throw new Exception("Found reference loop. Please set ReferenceHandling setting to XmlReferenceHandling.Handle"); } writer.WriteAttributeString(Settings.ReferenceHandlingReferenceName, id.ToString()); } } else { if (!Settings.IsBuildingObjectGraph || isCollection) { WriteXml(writer, value, member, context); } } if (!Settings.IsBuildingObjectGraph) { writer.WriteEndElement(); } }
private void Serialize(XmlWriter writer, object value, Type memberType, XmlMember member) { if (writer == null) { throw new ArgumentNullException("writer"); } // ignore optional values with none value if (value is IAnyOptional optional) { if (!optional.HasValue) { if (Settings.NoneValueHandling == XmlNoneValueHandling.Ignore) { return; } // Output default values for inner types var innerType = optional.GetInnerType(); var nullableInnerType = innerType.GetUnderlyingNullableType(); if (nullableInnerType != null) { WriteNull(writer, memberType, member); return; } else if (innerType.IsClass) { WriteNull(writer, memberType, member); return; } } else if (optional.Value == null) { WriteNull(writer, memberType, member); return; } } if (value == null) { WriteNull(writer, memberType, member); return; } if (settings.EmptyCollectionHandling == XmlEmptyCollectionHandling.Ignore && value.IsEmpty() == true) { return; } XmlTypeContext context = null; if (member == null) { context = settings.GetTypeContext(memberType); member = context.Contract.Root; } bool shouldWriteTypeName = TryResolveValueType(value, ref member, out Type valueType); if (member.DefaultValue != null) { XmlDefaultValueHandling defaultValueHandling = member.DefaultValueHandling ?? settings.DefaultValueHandling; if (defaultValueHandling == XmlDefaultValueHandling.Ignore && value.Equals(member.DefaultValue)) { return; } } if (context == null || context.Contract.ValueType != member.ValueType) { context = settings.GetTypeContext(valueType); } switch (member.MappingType) { case XmlMappingType.Element: WriteElement(writer, value, member, context, valueType, shouldWriteTypeName); break; case XmlMappingType.Attribute: if (!Settings.IsBuildingObjectGraph) { writer.WriteStartAttribute(member.Name); } WriteXml(writer, value, member, context); if (!Settings.IsBuildingObjectGraph) { writer.WriteEndAttribute(); } break; case XmlMappingType.InnerText: if (!Settings.IsBuildingObjectGraph) { WriteXml(writer, value, member, context); } break; } }