public bool CanHandle(PropertyInfo info)
		{
			return info.HasCustomAttribute<MultiSelectAttribute>();
		}
예제 #2
0
        private XObject Traverse(Format format, object source, LinkedNode<object> ancestors, PropertyInfo sourceProperty = null, Type itemType = null)
        {
            var type = itemType ?? (sourceProperty == null ? source.GetType() : sourceProperty.PropertyType);

            var name = format == Format.Xml ? GetXmlNodeName(type, ancestors, sourceProperty, itemType) :
                GetJsonNodeName(ancestors, sourceProperty, itemType);

            Func<object, XElement> createElement = x => new XElement(_options.DefaultNamespace == null || format == Format.Json ?
                name : _options.DefaultNamespace + name, x, format == Format.Json ? new XAttribute("type", "object") : null);

            Func<string, XObject> createValueNode = x => _options.XmlValueNodeType == XmlValueNodeType.Attribute ||
               (sourceProperty != null && sourceProperty.HasCustomAttribute<XmlAttributeAttribute>()) ?
                new XAttribute(name, x ?? "") : (XObject)createElement(x);

            XObject node;
            ValueNode valueNode = null;

            if (_options.ValueWriters.ContainsKey(type))
            {
                node = createValueNode(null);
                valueNode = new ValueNode(node, format);
                if (format == Format.Json) valueNode.JsonField.DataType = source.ToJsonValueType();
                _options.ValueWriters[type](new WriterContext(_options, sourceProperty, source, valueNode));
            }
            else if (type.IsSimpleType())
            {
                node = source == null ? createValueNode(null) : createValueNode(source.ToString());
                valueNode = new ValueNode(node, format);
                if (format == Format.Json) valueNode.JsonField.DataType = source.ToJsonValueType();
            }
            else if (source == null)
            {
                node = createElement(null);
                valueNode = new ValueNode(node, format);
                if (format == Format.Json) valueNode.JsonField.DataType = JsonDataType.Null;
            }
            else if (type.IsEnumerable())
            {
                var listItemType = type.GetGenericEnumerableType();
                node = createElement(null).WithChildren(source.AsEnumerable().Select(x =>
                    Traverse(format, x, ancestors.Add(source), sourceProperty, listItemType ?? x.GetType())));
                valueNode = new ValueNode(node, format);
                if (format == Format.Json) valueNode.JsonField.DataType = JsonDataType.Array;
            }
            else
            {
                node = createElement(null);
                var properties = type.GetSerializableProperties(_options.ExcludedTypes);

                foreach (var property in properties.Where(x => !x.IsIgnored()))
                {
                    var propertyValue = property.GetValue(source, null);
                    if ((propertyValue == null && _options.ExcludeNullValues) || ancestors.Any(propertyValue)) continue;
                    ((XElement)node).Add(Traverse(format, propertyValue, ancestors.Add(propertyValue), property));
                }
            }

            valueNode = valueNode ?? new ValueNode(node, format);

            AddNamespaces(format, ancestors, valueNode);

            _options.NodeWriters.ForEach(x => x(new WriterContext(_options, sourceProperty, source, valueNode)));

            return valueNode.Object;
        }