Exemplo n.º 1
0
 internal static void PutValueConvertedToStringToXml(
     XDocument document,
     string value,
     Type deserializeAs,
     Mapping mapping,
     bool isArrayItem,
     bool emitTypeInfo,
     IXmlNamespaceResolver resolver)
 {
     if (value != null || mapping.IsXmlMandatory || isArrayItem)
     {
         var mappedElement = XmlOperations.GetOrCreateElement(document, mapping.ElementXPath, resolver);
         if (mappedElement == null)
         {
             throw new SerializationException(
                       String.Format("Cannot serialize object. Could not find or create element with mapping XPath '{0}'.", mapping.ElementXPath));
         }
         if (value == null)
         {
             value = String.Empty;
         }
         if (String.IsNullOrWhiteSpace(mapping.AttributeName))
         {
             if (mapping.AsXml)
             {
                 if (!String.IsNullOrWhiteSpace(value))
                 {
                     var wrappingElement = XElement.Parse("<root>" + value + "</root>");
                     mappedElement.Add(wrappingElement.Elements());
                 }
                 if (emitTypeInfo)
                 {
                     if (deserializeAs != null)
                     {
                         if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null)
                         {
                             throw new SerializationException(
                                       String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath));
                         }
                         mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString()));
                     }
                     else
                     {
                         if (mappedElement.Attribute(Constants.NullValueAttributeName) != null)
                         {
                             throw new SerializationException(
                                       String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath));
                         }
                         mappedElement.Add(new XAttribute(Constants.NullValueAttributeName, "true"));
                     }
                 }
             }
             else if (isArrayItem)
             {
                 var arrayItemElement = new XElement(mapping.ArrayItemElementName, value);
                 if (emitTypeInfo)
                 {
                     if (deserializeAs != null)
                     {
                         arrayItemElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString()));
                     }
                     else
                     {
                         arrayItemElement.Add(new XAttribute(Constants.NullValueAttributeName, "true"));
                     }
                 }
                 mappedElement.Add(arrayItemElement);
             }
             else
             {
                 mappedElement.Value = value;
                 if (emitTypeInfo)
                 {
                     if (deserializeAs != null)
                     {
                         if (mappedElement.Attribute(Constants.TypeInfoAttributeName) != null)
                         {
                             throw new SerializationException(
                                       String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath));
                         }
                         mappedElement.Add(new XAttribute(Constants.TypeInfoAttributeName, deserializeAs.AssemblyQualifiedName.ToString()));
                     }
                     else
                     {
                         if (mappedElement.Attribute(Constants.NullValueAttributeName) != null)
                         {
                             throw new SerializationException(
                                       String.Format("Cannot serialize object with type information. Mapping XPath '{0}' is used by more than 1 value.", mapping.ElementXPath));
                         }
                         mappedElement.Add(new XAttribute(Constants.NullValueAttributeName, "true"));
                     }
                 }
             }
         }
         else
         {
             mappedElement.SetAttributeValue(XPathHelper.ConvertToXName(mapping.AttributeName, resolver), value);
         }
     }
 }
Exemplo n.º 2
0
        private static void LoadMembersFromXml(
            XDocument document,
            IXPathSerializable serializable,
            SerializableMemberInfo[] membersToLoad,
            MemberInfo[] useMembers,
            Mapping parentMapping,
            int version,
            IFormatProvider provider,
            XmlNamespaceManager resolver)
        {
            foreach (var member in membersToLoad)
            {
                // Skip non-serializable members
                if (member.GetSingleCustomAttribute <NotForSerializationAttribute>() != null)
                {
                    continue;
                }

                // Check if the member is serializable in the current version
                int serializedFromVersion = 0;
                var versionAttribute      = member.GetSingleCustomAttribute <SerializedFromVersionAttribute>();
                if (versionAttribute != null)
                {
                    serializedFromVersion = versionAttribute.Version;
                }
                if (version < serializedFromVersion)
                {
                    continue;
                }

                var mapping = member.GetMapping(serializable.GetType(), parentMapping);

                var mappedElement = document.Root.XPathSelectElement(mapping.ElementXPath, resolver);

                bool mappedToAttributeWhichIsNotFound =
                    !String.IsNullOrWhiteSpace(mapping.AttributeName) &&
                    (mappedElement == null || mappedElement.Attribute(XPathHelper.ConvertToXName(mapping.AttributeName, resolver)) == null);

                // Ensure mandatory xml elements/attributes are present
                if (mapping.IsXmlMandatory)
                {
                    if (mappedElement == null)
                    {
                        throw new SerializationException(
                                  String.Format(
                                      "Cannot deserialize {0} '{1}', type '{2}'. Could not find the element with path '{3}'",
                                      member.MemeberTypeString,
                                      member.Name,
                                      serializable.GetType(),
                                      mapping.ElementXPath));
                    }
                    else if (mappedToAttributeWhichIsNotFound)
                    {
                        throw new SerializationException(
                                  String.Format(
                                      "Cannot deserialize {0} '{1}', type '{2}'. Could not find the attribute '{3}' of the element with path '{4}'",
                                      member.MemeberTypeString,
                                      member.Name,
                                      serializable.GetType(),
                                      mapping.AttributeName,
                                      mapping.ElementXPath));
                    }
                }

                // Short-circuit for nulls
                if (mappedElement == null || mappedToAttributeWhichIsNotFound)
                {
                    member.SetValue(serializable, null);
                    continue;
                }
                if (string.IsNullOrWhiteSpace(mapping.AttributeName))
                {
                    var isNullAttribute = mappedElement.Attribute(Constants.NullValueAttributeName);
                    if (isNullAttribute != null)
                    {
                        member.SetValue(serializable, null);
                        continue;
                    }
                }

                // Determine the type of the deserialized value
                Type emittedType = null;
                if (mappedElement != null && string.IsNullOrWhiteSpace(mapping.AttributeName))
                {
                    var typeAttribute = mappedElement.Attribute(Constants.TypeInfoAttributeName);
                    if (typeAttribute != null)
                    {
                        emittedType = Type.GetType(typeAttribute.Value);                         // TODO: handle all kind of exceptions
                    }
                }
                Type deserializeAs;
                if (emittedType != null)
                {
                    deserializeAs = emittedType;
                }
                else
                {
                    deserializeAs = member.MemberType;
                }

                var context = new SerializationContext(
                    serializable,
                    member,
                    mapping,
                    useMembers,
                    deserializeAs,
                    version: version,
                    formatProvider: provider,
                    resolver: resolver);

                if (deserializeAs.IsArray && !mapping.AsBase64)
                {
                    LoadArrayMemberFromXml(mappedElement, context);
                }
                else if (typeof(IXPathSerializable).IsAssignableFrom(deserializeAs))
                {
                    LoadXPathSerializableMemberFromXml(document, context);
                }
                else
                {
                    LoadSimpleMemberFromXml(mappedElement, context);
                }
            }
        }