public void WriteXml(XmlWriter writer, object value, XmlSerializationContext context) { if (context.Member.MappingType != XmlMappingType.Element) { throw new XmlSerializationException($"XML mapping of \"{context.ValueType}\" must be Element."); } var collectionItem = GetCollectionItem(context); if (collectionItem == null) { throw new XmlSerializationException( $"XML contract of \"{context.ValueType}\" must contains collection item"); } Type lastItemType = null; XmlTypeContext typeContext = null; foreach (var item in (IEnumerable)value) { if (item == null) { context.WriteNull(writer, collectionItem.ValueType, collectionItem); } else { var member = (XmlMember)collectionItem; var shouldWriteTypeName = context.TryResolveValueType(item, ref member, out Type itemType); if (itemType != lastItemType) { typeContext = context.Settings.GetTypeContext(itemType); lastItemType = itemType; } writer.WriteStartElement(member.Name); if (shouldWriteTypeName) { context.WriteTypeName(writer, lastItemType); } context.WriteXml(writer, item, member, typeContext); writer.WriteEndElement(); } } }
public void WriteXml(XmlWriter writer, object value, XmlSerializationContext context) { if (context.Member.MappingType != XmlMappingType.Element) { throw new XmlSerializationException(string.Format("XML mapping of \"{0}\" must be Element.", context.ValueType)); } var collectionItem = GetCollectionItem(context); if (collectionItem == null) { throw new XmlSerializationException(string.Format("XML contract of \"{0}\" must contains collection item", context.ValueType)); } Type lastItemType = null; XmlTypeContext typeContext = null; foreach (var listItem in (IEnumerable)value) { object item = listItem; // ignore optional none and unwrap optional because we've already done that in XmlContractResolver.ResolveItem if (listItem is IAnyOptional optional) { if (!optional.HasValue) { if (context.Settings.NoneValueHandling == XmlNoneValueHandling.Ignore) { continue; } // Output default values for inner types var innerType = optional.GetInnerType(); var nullableInnerType = innerType.GetUnderlyingNullableType(); if (nullableInnerType != null) { context.WriteNull(writer, collectionItem.ValueType, collectionItem); continue; } else if (innerType.IsClass) { context.WriteNull(writer, collectionItem.ValueType, collectionItem); continue; } } item = optional.Value; } if (item == null) { context.WriteNull(writer, collectionItem.ValueType, collectionItem); continue; } var member = (XmlMember)collectionItem; var shouldWriteTypeName = context.TryResolveValueType(item, ref member, out Type itemType); if (itemType != lastItemType) { typeContext = context.Settings.GetTypeContext(itemType); lastItemType = itemType; } // start writing element context.WriteElement(writer, item, member, typeContext, itemType, shouldWriteTypeName); } }