示例#1
0
        /// <summary>
        /// Serialize the object as XML
        ///
        /// </summary>
        /// <param name="obj">Object to serialize</param>
        /// <returns>
        /// XML as string
        /// </returns>
        public string Serialize(object obj)
        {
            XDocument            xdocument  = new XDocument();
            Type                 type1      = obj.GetType();
            string               name1      = type1.Name;
            SerializeAsAttribute attribute1 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>(type1);

            if (attribute1 != null)
            {
                name1 = attribute1.TransformName(attribute1.Name ?? name1);
            }
            XElement xelement1 = new XElement(XmlExtensions.AsNamespaced(name1, this.Namespace));

            if (obj is IList)
            {
                string name2 = "";
                foreach (object obj1 in (IEnumerable)obj)
                {
                    Type type2 = obj1.GetType();
                    SerializeAsAttribute attribute2 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>(type2);
                    if (attribute2 != null)
                    {
                        name2 = attribute2.TransformName(attribute2.Name ?? name1);
                    }
                    if (name2 == "")
                    {
                        name2 = type2.Name;
                    }
                    XElement xelement2 = new XElement(XmlExtensions.AsNamespaced(name2, this.Namespace));
                    this.Map((XContainer)xelement2, obj1);
                    xelement1.Add((object)xelement2);
                }
            }
            else
            {
                this.Map((XContainer)xelement1, obj);
            }
            if (StringExtensions.HasValue(this.RootElement))
            {
                XElement xelement2 = new XElement(XmlExtensions.AsNamespaced(this.RootElement, this.Namespace), (object)xelement1);
                xdocument.Add((object)xelement2);
            }
            else
            {
                xdocument.Add((object)xelement1);
            }
            return(xdocument.ToString());
        }
示例#2
0
        protected TypeNode(TypeNode parent, MemberInfo memberInfo) : this(parent)
        {
            if (memberInfo == null)
            {
                return;
            }

            Name = memberInfo.Name;

            var propertyInfo = memberInfo as PropertyInfo;
            var fieldInfo    = memberInfo as FieldInfo;

            if (propertyInfo != null)
            {
                _type       = propertyInfo.PropertyType;
                ValueGetter = declaringValue => propertyInfo.GetValue(declaringValue, null);
                ValueSetter = (obj, value) => propertyInfo.SetValue(obj, value, null);
            }
            else if (fieldInfo != null)
            {
                _type       = fieldInfo.FieldType;
                ValueGetter = fieldInfo.GetValue;
                ValueSetter = fieldInfo.SetValue;
            }
            else
            {
                throw new NotSupportedException(string.Format("{0} not supported", memberInfo.GetType().Name));
            }

            _underlyingType = Nullable.GetUnderlyingType(Type);

            object[] attributes = memberInfo.GetCustomAttributes(true);

            IgnoreAttribute = attributes.OfType <IgnoreAttribute>().SingleOrDefault();

            /* Don't go any further if we're ignoring this. */
            if (IgnoreAttribute != null)
            {
                return;
            }

            FieldOrderAttribute fieldOrderAttribute = attributes.OfType <FieldOrderAttribute>().SingleOrDefault();
            if (fieldOrderAttribute != null)
            {
                _order = fieldOrderAttribute.Order;
                if (fieldOrderAttribute.ConverterType != null)
                {
                    var typeConverter       = (IValueConverter)Activator.CreateInstance(fieldOrderAttribute.ConverterType);
                    var originalValueGetter = ValueGetter;
                    var originalValueSetter = ValueSetter;
                    ValueGetter = declaringValue => typeConverter.Convert(originalValueGetter(declaringValue), fieldOrderAttribute.ConverterParameter, null);
                    ValueSetter = (obj, value) => originalValueSetter(obj, typeConverter.ConvertBack(value, fieldOrderAttribute.ConverterParameter, null));
                }
            }


            SerializeAsAttribute serializeAsAttribute = attributes.OfType <SerializeAsAttribute>().SingleOrDefault();
            if (serializeAsAttribute != null)
            {
                _serializedType = serializeAsAttribute.SerializedType;
                Endianness      = serializeAsAttribute.Endianness;

                if (!string.IsNullOrEmpty(serializeAsAttribute.Encoding))
                {
                    Encoding = Encoding.GetEncoding(serializeAsAttribute.Encoding);
                }
            }


            FieldLengthAttribute = attributes.OfType <FieldLengthAttribute>().SingleOrDefault();
            if (FieldLengthAttribute != null)
            {
                FieldLengthBinding = new Binding(FieldLengthAttribute, GetBindingLevel(FieldLengthAttribute.Binding));
            }

            FieldCountAttribute = attributes.OfType <FieldCountAttribute>().SingleOrDefault();
            if (FieldCountAttribute != null)
            {
                FieldCountBinding = new Binding(FieldCountAttribute, FindAncestorLevel(FieldCountAttribute.Binding));
            }

            FieldOffsetAttribute = attributes.OfType <FieldOffsetAttribute>().SingleOrDefault();
            if (FieldOffsetAttribute != null)
            {
                FieldOffsetBinding = new Binding(FieldOffsetAttribute, GetBindingLevel(FieldOffsetAttribute.Binding));
            }

            SerializeWhenAttribute[] serializeWhenAttributes = attributes.OfType <SerializeWhenAttribute>().ToArray();
            SerializeWhenAttributes = new ReadOnlyCollection <SerializeWhenAttribute>(serializeWhenAttributes);

            if (SerializeWhenAttributes.Any())
            {
                SerializeWhenBindings = new ReadOnlyCollection <ConditionalBinding>(
                    serializeWhenAttributes.Select(
                        attribute => new ConditionalBinding(attribute, GetBindingLevel(attribute.Binding))).ToList());
            }

            SubtypeAttribute[] subtypeAttributes = attributes.OfType <SubtypeAttribute>().ToArray();
            SubtypeAttributes = new ReadOnlyCollection <SubtypeAttribute>(subtypeAttributes);

            if (SubtypeAttributes.Count > 0)
            {
                IEnumerable <IGrouping <BindingInfo, SubtypeAttribute> > bindingGroups =
                    SubtypeAttributes.GroupBy(subtypeAttribute => subtypeAttribute.Binding);

                if (bindingGroups.Count() > 1)
                {
                    throw new BindingException("Subtypes must all use the same binding configuration.");
                }

                SubtypeAttribute firstBinding = SubtypeAttributes[0];
                SubtypeBinding = new Binding(firstBinding, GetBindingLevel(firstBinding.Binding));

                var valueGroups = SubtypeAttributes.GroupBy(attribute => attribute.Value);
                if (valueGroups.Count() < SubtypeAttributes.Count)
                {
                    throw new InvalidOperationException("Subtype values must be unique.");
                }

                if (SubtypeBinding.BindingMode == BindingMode.TwoWay)
                {
                    var subTypeGroups = SubtypeAttributes.GroupBy(attribute => attribute.Subtype);
                    if (subTypeGroups.Count() < SubtypeAttributes.Count)
                    {
                        throw new InvalidOperationException("Subtypes must be unique for two-way subtype bindings.  Set BindingMode to OneWay to disable updates to the binding source during serialization.");
                    }
                }
            }


            SerializeUntilAttribute = attributes.OfType <SerializeUntilAttribute>().SingleOrDefault();
            if (SerializeUntilAttribute != null)
            {
                SerializeUntilBinding = new Binding(SerializeUntilAttribute,
                                                    GetBindingLevel(SerializeUntilAttribute.Binding));
            }

            ItemLengthAttribute = attributes.OfType <ItemLengthAttribute>().SingleOrDefault();
            if (ItemLengthAttribute != null)
            {
                ItemLengthBinding = new Binding(ItemLengthAttribute, GetBindingLevel(ItemLengthAttribute.Binding));
            }

            ItemSerializeUntilAttribute = attributes.OfType <ItemSerializeUntilAttribute>().SingleOrDefault();

            if (ItemSerializeUntilAttribute != null)
            {
                ItemSerializeUntilBinding = new Binding(ItemSerializeUntilAttribute,
                                                        GetBindingLevel(ItemSerializeUntilAttribute.Binding));
            }

            BitSizeAttribute = attributes.OfType <BitSizeAttribute>().SingleOrDefault();
        }
示例#3
0
        private void Map(XContainer root, object obj)
        {
            Type type1 = obj.GetType();
            IEnumerable <PropertyInfo> enumerable = Enumerable.Select(Enumerable.OrderBy(Enumerable.Where(Enumerable.Select((IEnumerable <PropertyInfo>)type1.GetProperties(), p => new
            {
                p = p,
                indexAttribute = ReflectionExtensions.GetAttribute <SerializeAsAttribute>((MemberInfo)p)
            }), param0 =>
            {
                if (param0.p.CanRead)
                {
                    return(param0.p.CanWrite);
                }
                return(false);
            }), param0 =>
            {
                if (param0.indexAttribute != null)
                {
                    return(param0.indexAttribute.Index);
                }
                return(int.MaxValue);
            }), param0 => param0.p);
            SerializeAsAttribute attribute1 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>(type1);

            foreach (PropertyInfo propertyInfo in enumerable)
            {
                string str  = propertyInfo.Name;
                object obj1 = propertyInfo.GetValue(obj, (object[])null);
                if (obj1 != null)
                {
                    string serializedValue          = this.GetSerializedValue(obj1);
                    Type   propertyType             = propertyInfo.PropertyType;
                    bool   flag                     = false;
                    SerializeAsAttribute attribute2 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>((MemberInfo)propertyInfo);
                    if (attribute2 != null)
                    {
                        str  = StringExtensions.HasValue(attribute2.Name) ? attribute2.Name : str;
                        flag = attribute2.Attribute;
                    }
                    SerializeAsAttribute attribute3 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>((MemberInfo)propertyInfo);
                    if (attribute3 != null)
                    {
                        str = attribute3.TransformName(str);
                    }
                    else if (attribute1 != null)
                    {
                        str = attribute1.TransformName(str);
                    }
                    XElement xelement1 = new XElement(XmlExtensions.AsNamespaced(str, this.Namespace));
                    if (propertyType.IsPrimitive || propertyType.IsValueType || propertyType == typeof(string))
                    {
                        if (flag)
                        {
                            root.Add((object)new XAttribute((XName)str, (object)serializedValue));
                            continue;
                        }
                        xelement1.Value = serializedValue;
                    }
                    else if (obj1 is IList)
                    {
                        string name = "";
                        foreach (object obj2 in (IEnumerable)obj1)
                        {
                            if (name == "")
                            {
                                Type type2 = obj2.GetType();
                                SerializeAsAttribute attribute4 = ReflectionExtensions.GetAttribute <SerializeAsAttribute>(type2);
                                name = attribute4 == null || !StringExtensions.HasValue(attribute4.Name) ? type2.Name : attribute4.Name;
                            }
                            XElement xelement2 = new XElement(XmlExtensions.AsNamespaced(name, this.Namespace));
                            this.Map((XContainer)xelement2, obj2);
                            xelement1.Add((object)xelement2);
                        }
                    }
                    else
                    {
                        this.Map((XContainer)xelement1, obj1);
                    }
                    root.Add((object)xelement1);
                }
            }
        }
示例#4
0
        private void Map(XContainer root, object obj)
        {
            Type objType = obj.GetType();
            var  props   = from p in objType.GetProperties()
                           let indexAttribute = p.GetAttribute <SerializeAsAttribute>()
                                                where p.CanRead && p.CanWrite
                                                orderby indexAttribute?.Index ?? int.MaxValue
                                                select p;
            SerializeAsAttribute globalOptions   = objType.GetAttribute <SerializeAsAttribute>();
            bool textContentAttributeAlreadyUsed = false;

            foreach (var prop in props)
            {
                var name     = prop.Name;
                var rawValue = prop.GetValue(obj, null);

                if (rawValue == null)
                {
                    continue;
                }

                string value                 = this.GetSerializedValue(rawValue);
                Type   propType              = prop.PropertyType;
                bool   useAttribute          = false;
                bool   setTextContent        = false;
                SerializeAsAttribute options = prop.GetAttribute <SerializeAsAttribute>();

                if (options != null)
                {
                    name = options.Name.HasValue()
                        ? options.Name
                        : name;

                    name = options.TransformName(name);

                    useAttribute = options.Attribute;

                    setTextContent = options.Content;

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

                    textContentAttributeAlreadyUsed |= setTextContent;
                }
                else if (globalOptions != null)
                {
                    name = globalOptions.TransformName(name);
                }

                var nsName  = name.AsNamespaced(Namespace);
                var element = new XElement(nsName);
                if (propType.GetTypeInfo().IsPrimitive || propType.GetTypeInfo().IsValueType ||
                    propType == typeof(string))
                {
                    if (useAttribute)
                    {
                        root.Add(new XAttribute(name, value));
                        continue;
                    }
                    else if (setTextContent)
                    {
                        root.Add(new XText(value));
                        continue;
                    }

                    element.Value = value;
                }
                else if (rawValue is IList)
                {
                    var itemTypeName = "";

                    foreach (var item in (IList)rawValue)
                    {
                        if (itemTypeName == "")
                        {
                            var type    = item.GetType();
                            var setting = type.GetAttribute <SerializeAsAttribute>();

                            itemTypeName = setting != null && setting.Name.HasValue()
                                ? setting.Name
                                : type.Name;
                        }

                        var instance = new XElement(itemTypeName.AsNamespaced(Namespace));

                        Map(instance, item);
                        element.Add(instance);
                    }
                }
                else
                {
                    Map(element, rawValue);
                }

                root.Add(element);
            }
        }