Esempio n. 1
0
        private object HandleListDerivative(XElement root, string propName, Type type)
        {
            Type                   type1     = type.IsGenericType ? type.GetGenericArguments()[0] : type.BaseType.GetGenericArguments()[0];
            IList                  list1     = (IList)Activator.CreateInstance(type);
            IList <XElement>       list2     = (IList <XElement>)Enumerable.ToList <XElement>(root.Descendants(XmlExtensions.AsNamespaced(type1.Name, this.Namespace)));
            string                 name      = type1.Name;
            DeserializeAsAttribute attribute = ReflectionExtensions.GetAttribute <DeserializeAsAttribute>(type1);

            if (attribute != null)
            {
                name = attribute.Name;
            }
            if (!Enumerable.Any <XElement>((IEnumerable <XElement>)list2))
            {
                XName name1 = XmlExtensions.AsNamespaced(name.ToLower(), this.Namespace);
                list2 = (IList <XElement>)Enumerable.ToList <XElement>(root.Descendants(name1));
            }
            if (!Enumerable.Any <XElement>((IEnumerable <XElement>)list2))
            {
                XName name1 = XmlExtensions.AsNamespaced(StringExtensions.ToCamelCase(name, this.Culture), this.Namespace);
                list2 = (IList <XElement>)Enumerable.ToList <XElement>(root.Descendants(name1));
            }
            if (!Enumerable.Any <XElement>((IEnumerable <XElement>)list2))
            {
                list2 = (IList <XElement>)Enumerable.ToList <XElement>(Enumerable.Where <XElement>(root.Descendants(), (Func <XElement, bool>)(e => StringExtensions.RemoveUnderscoresAndDashes(e.Name.LocalName) == name)));
            }
            if (!Enumerable.Any <XElement>((IEnumerable <XElement>)list2))
            {
                XName lowerName = XmlExtensions.AsNamespaced(name.ToLower(), this.Namespace);
                list2 = (IList <XElement>)Enumerable.ToList <XElement>(Enumerable.Where <XElement>(root.Descendants(), (Func <XElement, bool>)(e => (XName)StringExtensions.RemoveUnderscoresAndDashes(e.Name.LocalName) == lowerName)));
            }
            this.PopulateListFromElements(type1, (IEnumerable <XElement>)list2, list1);
            if (!type.IsGenericType)
            {
                this.Map((object)list1, root.Element(XmlExtensions.AsNamespaced(propName, this.Namespace)) ?? root);
            }
            return((object)list1);
        }
Esempio n. 2
0
        private object Map(object target, IDictionary <string, object> data)
        {
            Type objType = target.GetType();
            List <PropertyInfo> props = objType.GetProperties()
                                        .Where(p => p.CanWrite)
                                        .ToList();

            foreach (PropertyInfo prop in props)
            {
                string name;
                Type   type = prop.PropertyType;
#if !WINDOWS_UWP
                object[] attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false);

                if (attributes.Length > 0)
#else
                IEnumerable <Attribute> attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false);

                if (attributes.Count() > 0)
#endif
                {
                    DeserializeAsAttribute attribute = (DeserializeAsAttribute)attributes.First();
                    name = attribute.Name;
                }
                else
                {
                    if (prop.GetCustomAttributes(typeof(PagedResultDataAttribute), false).Any())
                    {
                        name = _pagedDataRootName;
                    }
                    else
                    {
                        name = prop.Name;
                    }
                }

                string[] parts = name.Split('.');
                IDictionary <string, object> currentData = data;
                object value = null;

                for (int i = 0; i < parts.Length; ++i)
                {
                    string actualName = parts[i].GetNameVariants(this.Culture)
                                        .FirstOrDefault(currentData.ContainsKey);

                    if (actualName == null)
                    {
                        break;
                    }

                    if (i == parts.Length - 1)
                    {
                        value = currentData[actualName];
                    }
                    else
                    {
                        currentData = (IDictionary <string, object>)currentData[actualName];
                    }
                }

                if (value != null)
                {
                    prop.SetValue(target, this.ConvertValue(type, value), null);
                }
            }

            return(target);
        }
        private object HandleListDerivative(XElement root, string propName, Type type)
        {
//#if !NETSTANDARD1_6
            Type t = type.IsGenericType
                ? type.GetGenericArguments()[0]
                : type.BaseType.GetGenericArguments()[0];
//#else
//          Type t = type.GetTypeInfo().IsGenericType
//           ? type.GenericTypeArguments[0]
//         : type.GetTypeInfo().BaseType.GenericTypeArguments[0];
//#endif
            IList            list     = (IList)Activator.CreateInstance(type);
            IList <XElement> elements = root.Descendants(t.Name.AsNamespaced(this.Namespace))
                                        .ToList();
            string name = t.Name;
            DeserializeAsAttribute attribute = t.GetAttribute <DeserializeAsAttribute>();

            if (attribute != null)
            {
                name = attribute.Name;
            }

            if (!elements.Any())
            {
                XName lowerName = name.ToLower().AsNamespaced(this.Namespace);

                elements = root.Descendants(lowerName).ToList();
            }

            if (!elements.Any())
            {
                XName camelName = name.ToCamelCase(this.Culture).AsNamespaced(this.Namespace);

                elements = root.Descendants(camelName).ToList();
            }

            if (!elements.Any())
            {
                elements = root.Descendants()
                           .Where(e => e.Name.LocalName.RemoveUnderscoresAndDashes() == name)
                           .ToList();
            }

            if (!elements.Any())
            {
                XName lowerName = name.ToLower().AsNamespaced(this.Namespace);

                elements = root.Descendants()
                           .Where(e => e.Name.LocalName.RemoveUnderscoresAndDashes() == lowerName)
                           .ToList();
            }

            this.PopulateListFromElements(t, elements, list);

            // get properties too, not just list items
            // only if this isn't a generic type
//#if !NETSTANDARD1_6
            if (!type.IsGenericType)
//#else
//          if (!type.GetTypeInfo().IsGenericType)
//#endif
            {
                this.Map(list, root.Element(propName.AsNamespaced(this.Namespace)) ?? root);
                // when using RootElement, the heirarchy is different
            }

            return(list);
        }
Esempio n. 4
0
        protected virtual object Map(object x, XElement root)
        {
            Type objType = x.GetType();

            PropertyInfo[] props = objType.GetProperties();
            bool           deserializeFromContentAttributeAlreadyUsed = false;

            foreach (var prop in props)
            {
                var type         = prop.PropertyType.GetTypeInfo();
                var typeIsPublic = type.IsPublic || type.IsNestedPublic;

                if (!typeIsPublic || !prop.CanWrite)
                {
                    continue;
                }

                bool  deserializeFromContent   = false;
                bool  isNameDefinedInAttribute = false;
                XName name       = null;
                var   attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false);

                if (attributes.Any())
                {
                    DeserializeAsAttribute attribute = (DeserializeAsAttribute)attributes.First();

                    name = attribute.Name.AsNamespaced(Namespace);
                    isNameDefinedInAttribute = !string.IsNullOrEmpty(name?.LocalName);

                    deserializeFromContent = attribute.Content;

                    if (deserializeFromContentAttributeAlreadyUsed && deserializeFromContent)
                    {
                        throw new ArgumentException("Class cannot have two properties marked with " +
                                                    "SerializeAs(Content = true) attribute.");
                    }

                    deserializeFromContentAttributeAlreadyUsed |= deserializeFromContent;
                }

                if (name == null)
                {
                    name = prop.Name.AsNamespaced(Namespace);
                }

                var value = GetValueFromXml(root, name, prop, isNameDefinedInAttribute);

                if (value == null)
                {
                    // special case for text content node
                    if (deserializeFromContent)
                    {
                        var textNode = root.Nodes().FirstOrDefault(n => n is XText);
                        if (textNode != null)
                        {
                            value = ((XText)textNode).Value;
                            prop.SetValue(x, value, null);
                        }
                        continue;
                    }

                    // special case for inline list items
                    if (type.IsGenericType)
                    {
                        var genericType = type.GetGenericArguments()[0];
                        var first       = GetElementByName(root, genericType.Name);
                        var list        = (IList)Activator.CreateInstance(type.AsType());

                        if (first != null && root != null)
                        {
                            var elements = root.Elements(first.Name);

                            PopulateListFromElements(genericType, elements, list);
                        }

                        prop.SetValue(x, list, null);
                    }
                    continue;
                }

                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    // if the value is empty, set the property to null...
                    if (string.IsNullOrEmpty(value.ToString()))
                    {
                        prop.SetValue(x, null, null);
                        continue;
                    }

                    type = type.GetGenericArguments()[0].GetTypeInfo();
                }

                var asType = type.AsType();
                if (asType == typeof(bool))
                {
                    var toConvert = value.ToString()
                                    .ToLower();

                    prop.SetValue(x, XmlConvert.ToBoolean(toConvert), null);
                }
                else if (type.IsPrimitive)
                {
                    prop.SetValue(x, value.ChangeType(asType, Culture), null);
                }
                else if (type.IsEnum)
                {
                    var converted = type.AsType().FindEnumValue(value.ToString(), Culture);

                    prop.SetValue(x, converted, null);
                }
                else if (asType == typeof(Uri))
                {
                    var uri = new Uri(value.ToString(), UriKind.RelativeOrAbsolute);

                    prop.SetValue(x, uri, null);
                }
                else if (asType == typeof(string))
                {
                    prop.SetValue(x, value, null);
                }
                else if (asType == typeof(DateTime))
                {
                    value = DateFormat.HasValue()
                        ? DateTime.ParseExact(value.ToString(), DateFormat, Culture)
                        : DateTime.Parse(value.ToString(), Culture);

                    prop.SetValue(x, value, null);
                }
                else if (asType == typeof(DateTimeOffset))
                {
                    var toConvert = value.ToString();

                    if (string.IsNullOrEmpty(toConvert))
                    {
                        continue;
                    }

                    DateTimeOffset deserialisedValue;

                    try
                    {
                        deserialisedValue = XmlConvert.ToDateTimeOffset(toConvert);
                        prop.SetValue(x, deserialisedValue, null);
                    }
                    catch (Exception)
                    {
                        if (TryGetFromString(toConvert, out var result, asType))
                        {
                            prop.SetValue(x, result, null);
                        }
                        else
                        {
                            //fallback to parse
                            deserialisedValue = DateTimeOffset.Parse(toConvert);
                            prop.SetValue(x, deserialisedValue, null);
                        }
                    }
                }
        protected virtual object Map(object x, XElement root)
        {
            Type objType = x.GetType();

            PropertyInfo[] props = objType.GetTypeInfo().GetProperties();

            foreach (PropertyInfo prop in props)
            {
                Type type = prop.PropertyType;
//#if !NETSTANDARD1_6
                bool typeIsPublic = type.IsPublic || type.IsNestedPublic;
                //#else
                //                bool typeIsPublic = type.GetTypeInfo().IsPublic || type.GetTypeInfo().IsNestedPublic;
                //#endif

                if (!typeIsPublic || !prop.CanWrite)
                {
                    continue;
                }

                XName name;
//#if !NETSTANDARD1_6
                object[] attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false);

                if (attributes.Length > 0)
//#else
                // IEnumerable<Attribute> attributes = prop.GetCustomAttributes(typeof(DeserializeAsAttribute), false);

                // if (attributes.Count() > 0)
//#endif
                {
                    DeserializeAsAttribute attribute = (DeserializeAsAttribute)attributes.First();

                    name = attribute.Name.AsNamespaced(this.Namespace);
                }
                else
                {
                    name = prop.Name.AsNamespaced(this.Namespace);
                }

                object value = this.GetValueFromXml(root, name, prop);

                if (value == null)
                {
                    // special case for inline list items
//#if !NETSTANDARD1_6
                    if (type.IsGenericType)
//#else
//                  if (type.GetTypeInfo().IsGenericType)
//#endif
                    {
                        Type     genericType = type.GenericTypeArguments[0];
                        XElement first       = this.GetElementByName(root, genericType.Name);
                        IList    list        = (IList)Activator.CreateInstance(type);

                        if (first != null)
                        {
                            IEnumerable <XElement> elements = root.Elements(first.Name);

                            this.PopulateListFromElements(genericType, elements, list);
                        }

                        prop.SetValue(x, list, null);
                    }
                    continue;
                }

                // check for nullable and extract underlying type
//#if !NETSTANDARD1_6
                if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>))
//#else
                //   if (type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
//#endif
                {
                    // if the value is empty, set the property to null...
                    if (string.IsNullOrEmpty(value.ToString()))
                    {
                        prop.SetValue(x, null, null);
                        continue;
                    }

                    type = type.GenericTypeArguments[0];
                }

                if (type == typeof(bool))
                {
                    string toConvert = value.ToString()
                                       .ToLower();

                    prop.SetValue(x, XmlConvert.ToBoolean(toConvert), null);
                }
//#if !NETSTANDARD1_6
                else if (type.IsPrimitive)
//#else
//              else if (type.GetTypeInfo().IsPrimitive)
//#endif
                {
                    prop.SetValue(x, value.ChangeType(type, this.Culture), null);
                }
//#if !NETSTANDARD1_6
                else if (type.IsEnum)
//#else
//              else if (type.GetTypeInfo().IsEnum)
//#endif
                {
                    object converted = type.FindEnumValue(value.ToString(), this.Culture);

                    prop.SetValue(x, converted, null);
                }
                else if (type == typeof(Uri))
                {
                    Uri uri = new Uri(value.ToString(), UriKind.RelativeOrAbsolute);

                    prop.SetValue(x, uri, null);
                }
                else if (type == typeof(string))
                {
                    prop.SetValue(x, value, null);
                }
                else if (type == typeof(DateTime))
                {
                    value = this.DateFormat.HasValue()
                        ? DateTime.ParseExact(value.ToString(), this.DateFormat, this.Culture)
                        : DateTime.Parse(value.ToString(), this.Culture);

                    prop.SetValue(x, value, null);
                }
                else if (type == typeof(DateTimeOffset))
                {
                    string toConvert = value.ToString();

                    if (!string.IsNullOrEmpty(toConvert))
                    {
                        DateTimeOffset deserialisedValue;

                        try
                        {
                            deserialisedValue = XmlConvert.ToDateTimeOffset(toConvert);
                            prop.SetValue(x, deserialisedValue, null);
                        }
                        catch (Exception)
                        {
                            object result;

                            if (TryGetFromString(toConvert, out result, type))
                            {
                                prop.SetValue(x, result, null);
                            }
                            else
                            {
                                //fallback to parse
                                deserialisedValue = DateTimeOffset.Parse(toConvert);
                                prop.SetValue(x, deserialisedValue, null);
                            }
                        }
                    }
                }
                else if (type == typeof(decimal))
                {
                    value = decimal.Parse(value.ToString(), this.Culture);
                    prop.SetValue(x, value, null);
                }
                else if (type == typeof(Guid))
                {
                    string raw = value.ToString();

                    value = string.IsNullOrEmpty(raw)
                        ? Guid.Empty
                        : new Guid(value.ToString());

                    prop.SetValue(x, value, null);
                }
                else if (type == typeof(TimeSpan))
                {
                    TimeSpan timeSpan = XmlConvert.ToTimeSpan(value.ToString());

                    prop.SetValue(x, timeSpan, null);
                }
//#if !NETSTANDARD1_6
                else if (type.IsGenericType)
//#else
//              else if (type.GetTypeInfo(). IsGenericType)
//#endif
                {
                    Type     t         = type.GenericTypeArguments[0];
                    IList    list      = (IList)Activator.CreateInstance(type);
                    XElement container = this.GetElementByName(root, prop.Name.AsNamespaced(this.Namespace));

                    if (container.HasElements)
                    {
                        XElement first = container.Elements().FirstOrDefault();

                        if (first != null)
                        {
                            IEnumerable <XElement> elements = container.Elements(first.Name);

                            this.PopulateListFromElements(t, elements, list);
                        }
                    }

                    prop.SetValue(x, list, null);
                }
                else if (type.IsSubclassOfRawGeneric(typeof(List <>)))
                {
                    // handles classes that derive from List<T>
                    // e.g. a collection that also has attributes
                    object list = this.HandleListDerivative(root, prop.Name, type);

                    prop.SetValue(x, list, null);
                }
                else
                {
                    //fallback to type converters if possible
                    object result;

                    if (TryGetFromString(value.ToString(), out result, type))
                    {
                        prop.SetValue(x, result, null);
                    }
                    else
                    {
                        // nested property classes
                        if (root != null)
                        {
                            XElement element = this.GetElementByName(root, name);

                            if (element != null)
                            {
                                object item = this.CreateAndMap(type, element);

                                prop.SetValue(x, item, null);
                            }
                        }
                    }
                }
            }

            return(x);
        }