예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// It will for every field with string data deserialize this data using <see cref="IXMLDataSerializer"/>.
        ///
        /// For every sub-data field a <see cref="SerializedData"/> object is being written to <see cref="fields"/>.
        /// </summary>
        /// <param name="filename">Only used for error reporting</param>
        public void LoadFieldsFromXML(string filename, List <SerializerError> errors, XMLSerializerParams parameters)
        {
            foreach (var xNode in xElement.Nodes())
            {
                if (!SerializerValidation.NodeIsElement(parameters, xNode, filename, errors))                 // Malformed XML
                {
                    continue;
                }

                var xElement    = xNode as XElement;
                var elementName = xElement.Name.LocalName;

                // Field unknown?
                if (!SerializerValidation.FieldKnown(parameters, xElement, targetType, elementName, filename, errors))
                {
                    continue;
                }

                debug.Add(elementName, xElement);
                var _fieldData = targetType.GetFieldData(elementName);
                var fieldData  = _fieldData.Value;
                var fieldType  = fieldData.serializableTypeCache;

                if (xElement.Value == XMLSerializer.TokenNull)                 // Null special case
                {
                    fields.Add(elementName, null);
                    continue;
                }

                bool isCollection             = SerializedCollectionData.IsCollection(fieldData.fieldInfo.FieldType);
                IXMLDataSerializer serializer = SerializerCache.GetBestSerializerFor(fieldData.fieldInfo.FieldType);

                if (!ReferenceEquals(serializer, null))
                {
                    try
                    {
                        if (!SerializerValidation.SerializerWasFound(parameters, xElement, serializer, elementName, targetType == null ? null : targetType.type, fieldType == null ? null : fieldType.type, filename, errors))
                        {
                            continue;
                        }

                        fields.Add(elementName, serializer.Deserialize(fieldData.fieldInfo.FieldType, xElement, parameters));
                    }
                    catch (Exception ex)
                    {
                        errors.Add(new SerializerError(SerializerErrorSeverity.ERROR, filename, -1, "Serializer threw exception on field " + elementName + " on type " + targetType.type + ":\n\n" + ex.ToString() + "\n\nSkipping field!"));
                    }
                }
                else if (isCollection)
                {
                    var col = new SerializedCollectionData(fieldData.fieldInfo.FieldType, xElement);
                    col.ParseAndLoadData(filename, errors, parameters);
                    fields.Add(elementName, col);

                    // Collection override action?
                    var collectionOverrideAttrib = xElement.Attribute(XMLSerializer.AttributeCollectionOverrideAction);
                    if (!ReferenceEquals(collectionOverrideAttrib, null))
                    {
                        collectionOverrideActions.Set(elementName, (CollectionOverrideAction)Enum.Parse(typeof(CollectionOverrideAction), collectionOverrideAttrib.Value));
                    }
                }
                else
                {
                    // root reference?
                    if (fieldData.isSerializableRoot)
                    {
                        fields.Add(elementName, new SerializedRootObjectReference()
                        {
                            identifier = xElement.Value as string
                        });
                    }
                    else
                    {
                        // Determine which type to serialize
                        var    targetType = fieldData.serializableTypeCache;
                        string typeName   = fieldData.fieldInfo.Name;

                        // Check if element explicitly overwrites the type to support polymorphism
                        // The field type might be some base class type and the xml overwrites this type with a class extending from the base
                        var classAttrib = xElement.Attribute(XMLSerializer.AttributeType);
                        if (!ReferenceEquals(classAttrib, null))
                        {
                            targetType = SerializerCache.GetSerializableTypeCacheFor(classAttrib.Value, parameters.standardNamespace);
                            typeName   = classAttrib.Value;
                        }

                        // Field not serializable?
                        if (!SerializerValidation.DataFieldSerializerValid(parameters, xElement, targetType, typeName, elementName, filename, errors))
                        {
                            continue;
                        }

                        // Resolve field name type
                        var d = new SerializedData(targetType, xElement as XElement);
                        d.LoadFieldsFromXML(filename, errors, parameters);
                        fields.Add(elementName, d);
                    }
                }
            }
        }