public WriterContext(Options options, PropertyInfo property, object value, ValueNode valueNode) { Options = options; Property = property; Value = value; Node = valueNode; }
public ReaderContext(Options options, PropertyInfo property, ValueNode valueNode) { Options = options; Property = property; Node = valueNode; }
private static string GetFriendlyValue(ValueNode node) { return node.Value == null ? "<null>" : "'" + node.Value.TruncateAt(50) + "'"; }
public ValueParseException(PropertyInfo property, ValueNode node, string friendlyMessage, Exception exception) : base("Unable to parse the value {0} in the '{1}' {2} as a {3} into {4}.{5}: {6}".ToFormat( GetFriendlyValue(node), node.Object.GetPath(node.Format), node.NodeType.ToFriendlyNodeType(), property.PropertyType.Name, property.DeclaringType.FullName, property.Name, exception.Message), "Unable to parse the value {0} in the '{1}' {2} as a {3}: {4}".ToFormat( GetFriendlyValue(node), node.Object.GetPath(node.Format), node.NodeType.ToFriendlyNodeType(), property.PropertyType.ToFriendlyType(), friendlyMessage), exception) { Value = node.Value; XPath = node.Object.GetPath(node.Format); Node = node; ParseErrorMessage = friendlyMessage; ClrType = property.PropertyType; FriendlyType = property.PropertyType.ToFriendlyType(); }
public ValueParseException(PropertyInfo property, ValueNode node, ParseException exception) : this(property, node, exception.FriendlyMessage, exception) { }
public UnmatchedNodeException(ValueNode node) : base("The '{0}' {1} does not correspond to a type or property.".ToFormat( node.Object.GetPath(node.Format), node.NodeType.ToFriendlyNodeType()), "Unable to read {0}: The '{1}' {2} is not recognized.".ToFormat(node.Format.ToString().ToLower(), node.Object.GetPath(node.Format), node.NodeType.ToFriendlyNodeType())) { }
private void AddNamespaces(Format format, LinkedNode<object> ancestors, ValueNode valueNode) { if (format == Format.Xml && !ancestors.Any()) _options.XmlNamespaces.ForEach(x => valueNode.XmlElement.Add(new XAttribute(XNamespace.Xmlns + x.Key, x.Value))); }
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; }