/// <summary> /// Serializes the collection obj to <see cref="xElement"/>. /// </summary> /// <param name="targetElement">The element to write the loaded data to.</param> /// <param name="obj">The collection to load and write to <see cref="xElement"/></param> /// <param name="referenceables">Serializable object roots which will possibly be referenced by elements in obj.</param> public void WriteFromObject(object collection, XElement targetElement, List <SerializerError> errors, XMLSerializerParams parameters) { Type elementType = GetElementType(this.collectionType); var elementTypeCache = SerializerCache.GetSerializableTypeCacheFor(elementType); string elementTypeName = elementType.Name; foreach (var obj in (collection as IEnumerable)) { XElement _targetElement = new XElement("li"); targetElement.Add(_targetElement); if (obj == null) { _targetElement.Add(XMLSerializer.TokenNull); continue; } var objType = obj.GetType(); IXMLDataSerializer serializer = SerializerCache.GetBestSerializerFor(objType); if (!ReferenceEquals(serializer, null)) { try { if (!SerializerValidation.SerializerWasFound(parameters, null, serializer, "Collection", null, objType, "SERIALIZE", errors)) { continue; } serializer.Serialize(obj, _targetElement, parameters); } catch (Exception ex) { errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, "SERIALIZE", -1, "Serializer threw exception on collection of type " + objType + ":\n\n" + ex.ToString() + "\n\nSkipping field!")); } } else if (typeof(ISerializableRoot).IsAssignableFrom(elementType)) { // object ref _targetElement.Value = (obj as ISerializableRoot).identifier; } else { // Determine type var serializableTypeCache = elementTypeCache; string typeName = elementTypeName; // Write class attribute _targetElement.SetAttributeValue(XMLSerializer.AttributeType, typeName); // Validity checks // Field not serializable? if (ReferenceEquals(serializableTypeCache, null)) { errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, "SERIALIZER", -1, "Collection element with unknown type " + typeName + " unserializable! Skipping element!")); continue; } // Add element new SerializedData(serializableTypeCache, _targetElement).WriteFromObject(obj, errors, parameters); } } }
public void WriteFromObject(object obj, List <SerializerError> errors, XMLSerializerParams parameters) { targetType.GetAllFields(_fields); foreach (var fieldData in _fields) { if (!fieldData.isSerialized) { continue; } string fieldName = fieldData.fieldInfo.Name; XElement targetElement = new XElement(fieldName); xElement.Add(targetElement); var fieldObj = fieldData.fieldInfo.GetValue(obj); if (fieldObj == null) // Null special case { if (!fieldData.fieldInfo.GetCustomAttributes(true).Any((attrib) => attrib is AlwaysSerializedAttribute)) { return; } targetElement.Value = XMLSerializer.TokenNull; continue; } var fieldObjType = SerializerCache.GetSerializableTypeCacheFor(fieldObj.GetType()); bool isCollection = SerializedCollectionData.IsCollection(fieldData.fieldInfo.FieldType); IXMLDataSerializer serializer = SerializerCache.GetBestSerializerFor(fieldData.fieldInfo.FieldType); if (!ReferenceEquals(serializer, null)) { try { if (!SerializerValidation.SerializerWasFound(parameters, targetElement, serializer, fieldName, fieldObjType == null ? null : fieldObjType.type, fieldObjType == null ? null : fieldObjType.type, "SERIALIZE", errors)) { continue; } serializer.Serialize(fieldObj, targetElement, parameters); } catch (Exception ex) { errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, "SERIALIZE", -1, "Serializer threw exception on field " + fieldName + " on type " + fieldObjType.type + ":\n\n" + ex.ToString() + "\n\nSkipping field!")); } } else if (isCollection) { var col = new SerializedCollectionData(fieldData.fieldInfo.FieldType, targetElement); col.WriteFromObject(fieldObj, targetElement, errors, parameters); } else { // root reference? if (fieldData.isSerializableRoot) { targetElement.Value = (fieldObj as ISerializableRoot).identifier; } else { // Determine which type to serialize string typeName = fieldObjType.type.Name; // Write class attribute if (!ReferenceEquals(fieldData.fieldInfo.FieldType, fieldObjType.type)) { targetElement.SetAttributeValue(XMLSerializer.AttributeType, typeName); } // Field not serializable? if (!SerializerValidation.DataFieldSerializerValid(parameters, targetElement, fieldObjType, typeName, fieldName, "SERIALIZE", errors)) { continue; } // Write field var d = new SerializedData(fieldObjType, targetElement); d.WriteFromObject(fieldObj, errors, parameters); } } } }