示例#1
0
        private object Deserialize(Type type, object obj, XElement elm, params string[] properties)
        {
            var mappings = ReflectionCacheManager.Map(type);

            if (properties != null && properties.Length > 0)
            {
                mappings = mappings.Where(m => properties.Any(p => m.AttributeValue.Any(v => v == p))).ToList();
            }

            foreach (var mapping in mappings)
            {
                Logger.Debug($"\nDeserialize property {mapping.PropertyCache.Property.Name}: ");

                try
                {
                    switch (mapping.AttributeType)
                    {
                    case XmlAttributeType.Element:
                        ProcessXmlElement(obj, mapping, elm);
                        break;

                    case XmlAttributeType.Attribute:
                        ProcessXmlAttribute(obj, mapping, elm);
                        break;

                    case XmlAttributeType.Text:
                        ProcessXmlText(obj, mapping, elm);
                        break;

                    default:
                        throw new NotSupportedException();     //todo: add an appropriate failure message
                    }
                }
                catch (Exception)
                {
                    //throw new Exception("An error occurred while trying to deserialize property " + mapping.Property.Name);
                    throw;
                }
            }

            Logger.Debug("\n");

            return(obj);
        }
示例#2
0
        private Expression GetCaseBody(Enum property, Expression rawValue)
        {
            var viaObject = false;

            var typeLookup = property.GetEnumAttribute <TypeLookupAttribute>()?.Class; //ObjectPropertyInternal members don't necessarily have a type lookup

            if (typeLookup == null)
            {
                return(null);
            }

            var mappings   = ReflectionCacheManager.Map(typeLookup).Cache;
            var cache      = ObjectPropertyParser.GetPropertyInfoViaTypeLookup(property);
            var xmlElement = cache.GetAttribute <XmlElementAttribute>(); //todo: what if this objectproperty doesnt point to a member with an xmlelementattribute?

            XmlMapping mapping = null;

            if (xmlElement != null)
            {
                mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == xmlElement.ElementName);
            }
            else
            {
                var mergeAttribute = property.GetEnumAttribute <MergeableAttribute>();

                //If we're a property like LocationName, we don't exist server side - we're only used for constructing requests
                if (mergeAttribute != null)
                {
                    return(null);
                }

                //We have a property like Interval which uses a backing property instead.
                //Get the backing property so that we may extract the real value from the public
                //property
                var rawName     = ObjectPropertyParser.GetObjectPropertyNameViaCache(property, cache);
                var elementName = $"{HtmlParser.DefaultPropertyPrefix}{rawName.TrimEnd('_')}";

                mapping = mappings.FirstOrDefault(m => m.AttributeValue[0] == elementName);

                if (mapping != null)
                {
                    viaObject = true;
                }
            }

            if (mapping != null)
            {
                var deserializer = new ValueDeserializer(mapping, null, rawValue);
                var result       = deserializer.Deserialize();

                if (viaObject)
                {
                    //Construct an expression like return new TableSettings { intervalStr = "60|60 seconds" }.Interval;
                    var settingsObj    = Expression.Variable(typeLookup, "obj");
                    var assignObj      = settingsObj.Assign(Expression.New(typeLookup));
                    var internalProp   = Expression.MakeMemberAccess(settingsObj, mapping.PropertyCache.Property);
                    var assignInternal = internalProp.Assign(result);
                    var externalProp   = Expression.MakeMemberAccess(settingsObj, cache.Property);

                    return(Expression.Block(
                               new[] { settingsObj },
                               assignObj,
                               assignInternal,
                               Expression.Convert(externalProp, typeof(object))
                               ));
                }

                return(result);
            }

            //Property is not deserializable
            return(null);
        }