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); }
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); }