public XmlSerializerGenerator(Type delegateType, Type trueType, bool update) { if (trueType == null) { trueType = delegateType; } this.delegateType = delegateType; this.trueType = trueType; this.update = update; Mappings = XmlMapping.GetMappings(trueType).OrderBy(m => m.AttributeValue.FirstOrDefault() == "message").ToList(); if (update) { Mappings = Mappings.Where(m => { var attrib = m.PropertyCache.GetAttribute <PropertyParameterAttribute>(); if (attrib != null && attrib.Property != null) { if (attrib.Property.Equals(Property.Name) || attrib.Property.Equals(Property.Id)) { return(false); } } return(true); }).ToList(); } Target = Expression.Variable(trueType, "obj"); //var obj; DelegateTarget = Expression.Parameter(delegateType, "obj"); }
private bool BuildConditions(XmlMapping mapping, int i, ref int mappingNameIndex, ref List <ConditionalExpression> result) { var type = Mappings[i].PropertyCache.Property.PropertyType; if (type.IsValueType && Nullable.GetUnderlyingType(type) == null) { var flagIndex = Expression.Constant(i); var flag = Expression.ArrayIndex(XmlExpressionConstants.SerializerFlags, flagIndex); //flagArray[0] var nameIndex = Expression.Constant(mappingNameIndex); var name = Expression.ArrayIndex(XmlExpressionConstants.SerializerNames, nameIndex); var assignName = XmlExpressionConstants.Serializer_Name(mapping.AttributeType).Assign(name); var throwNull = XmlExpressionConstants.Fail(null, type).Throw(); //throw Fail(null, null, typeof(int)); var block = Expression.Block( assignName, throwNull ); var condition = flag.Not().IfThen(block); result.Add(condition); } return(false); }
public ValueDeserializer( XmlMapping mapping, XmlSerializerGenerator generator, Expression str) { this.mapping = mapping; this.generator = generator; PropertyType = mapping.PropertyCache.Property.PropertyType; valueConverter = GetValueConverter(); readStr = str; }
private bool BuildTextConditions(XmlMapping mapping, int i, ref int mappingNameIndex, ref List <ConditionalExpression> result) { if (mapping.AttributeType == XmlAttributeType.Text) { var blockBuilder = new LadderCondition(mapping, i, this); var condition = blockBuilder.GetCondition(ref mappingNameIndex); result.Add(condition); return(true); } return(false); }
//todo: profile the performance of my method vs the .net method private void ProcessXmlAttribute(object obj, XmlMapping mapping, XElement elm) { var value = mapping.GetSingleXAttributeAttributeValue(elm); try { value = NullifyMissingValue(value); var finalValue = GetValue(value, mapping.PropertyCache, value?.Value, elm); mapping.PropertyCache.SetValue(obj, finalValue); } catch (Exception ex) when(!(ex is XmlDeserializationException)) { throw new XmlDeserializationException(mapping.PropertyCache.Property.PropertyType.GetUnderlyingType(), XmlAttributeExceptionNode(value), ex); } }
private void ProcessSingleXmlElement(object obj, XmlMapping mapping, XElement elm) { var value = mapping.GetSingleXElementAttributeValue(elm); //priority is priority_raw on the root group, priority everywhere else. we need an alt xmlelement //ok we have one, we now need to treat attributevalue as a list try { ProcessXmlText(obj, mapping, value); } catch (Exception ex) when(!(ex is XmlDeserializationException)) { throw new XmlDeserializationException(mapping.PropertyCache.Property.PropertyType.GetUnderlyingType(), value?.ToString() ?? "null", ex); } }
private void ProcessListEnumerableXmlElement(object obj, XmlMapping mapping, XElement elm) { var type = mapping.PropertyCache.Property.PropertyType; var underlyingType = type.GetGenericArguments().First(); var list = Activator.CreateInstance(type); var elms = mapping.AttributeValue.Select(a => elm.Elements(a)).First(x => x != null).ToList(); foreach (var e in elms) { ((IList)list).Add(Deserialize(underlyingType, e)); } mapping.PropertyCache.Property.SetValue(obj, list); }
private void ProcessXmlText(object obj, XmlMapping mapping, XElement elm) { var type = mapping.PropertyCache.Property.PropertyType; elm = NullifyMissingValue(elm); var finalValue = GetValue(elm, mapping.PropertyCache, elm?.Value, elm); if (type.IsValueType && Nullable.GetUnderlyingType(type) == null && finalValue == null) { if (!deserializeAll) { return; } throw new XmlDeserializationException($"An error occurred while attempting to deserialize XML element '{mapping.AttributeValue.First()}' to property '{mapping.PropertyCache.Property.Name}': cannot assign 'null' to value type '{type.Name}'."); //value types cant be null } mapping.PropertyCache.SetValue(obj, finalValue); }
private void ProcessNonListEnumerableXmlElement(object obj, XmlMapping mapping, XElement elm) { var attribute = mapping.PropertyCache.GetAttribute <SplittableStringAttribute>(); if (attribute != null) { var value = mapping.AttributeValue.Select(a => elm.Element(a)).FirstOrDefault(x => x != null); value = NullifyMissingValue(value); object finalVal = value; if (value != null) { finalVal = value.Value.Trim().Split(new[] { attribute.Character }, StringSplitOptions.RemoveEmptyEntries); } mapping.PropertyCache.Property.SetValue(obj, finalVal); } else { throw new NotSupportedException(); //todo: add an appropriate failure message } }
private void ProcessXmlElement(object obj, XmlMapping mapping, XElement elm) { var type = mapping.PropertyCache.Property.PropertyType; if (typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string)) { ProcessEnumerableXmlElement(obj, mapping, elm); } else { if (mapping.PropertyCache.Property.PropertyType.GetTypeCache().GetAttribute <XmlRootAttribute>() != null) { var elms = mapping.AttributeValue.Select(a => elm.Elements(a)).First(x => x != null).FirstOrDefault(); var result = elms != null?Deserialize(mapping.PropertyCache.Property.PropertyType, elms) : null; mapping.PropertyCache.Property.SetValue(obj, result); } else { ProcessSingleXmlElement(obj, mapping, elm); } } }
private Expression GetTextBlock(XmlMapping mapping) { var body = ForEachMappingValue <ConditionalExpression>(BuildTextConditions).Single().IfTrue; return(body); }
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); }
public ValueDeserializer(XmlMapping mapping, XmlSerializerGenerator generator) : this(mapping, generator, null) { readStr = ReadString(); }