Using YamlDotNet, I'm trying to deserialize a yaml file with a nested object graph into a set of custom .net types. This works if I set the tree property to a simple PopulationBasicNode, but when I use the PopulationAndNode as shown in the example, a YamlException is thrown:
No node deserializer was able to deserialize the node into type PopulationTreeNode
I thought that using the following extension method of the deserializer builder would make the deserializer being able to resolve the type.
WithTagMapping("!and", typeof(PopulationAndNode))
I also tried registering a INodeTypeResolver, but I still get the same expeption.
WithNodeTypeResolver(new PopulationNodeResolver())
public class PopulationNodeResolver : INodeTypeResolver
{
public bool Resolve(NodeEvent nodeEvent, ref Type currentType)
{
if (nodeEvent.Tag == "!and")
{
currentType = typeof(PopulationAndNode);
return true;
}
return false;
}
}
# a population
- id: some-id
tree:
!and
- !basic
someProperty: hello
- !basic
someProperty: world
public class Population
{
public string Id { get; set; }
public PopulationTreeNode Tree { get; set; }
}
public abstract class PopulationTreeNode
{
public string Id { get; set; }
}
public class PopulationAndNode : PopulationTreeNode
{
public IEnumerable<PopulationTreeNode> Children { get; set; }
}
public class PopulationBasicNode : PopulationTreeNode
{
public string SomeProperty { get; set; }
}
var resourcePath = assembly.GetManifestResourceNames().Single(str => str.EndsWith(fileName));
using Stream stream = assembly.GetManifestResourceStream(resourcePath);
using StreamReader streamReader = new StreamReader(stream);
var fileContent = streamReader.ReadToEnd();
var deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.WithTagMapping("!and", typeof(PopulationAndNode))
.WithTagMapping("!basic", typeof(PopulationBasicNode))
.Build();
var populations = deserializer.Deserialize<List<Population>>(fileContent);
YamlDotNet.Core.YamlException
HResult=0x80131500
Message=(Line: 34, Col: 9, Idx: 1055) - (Line: 35, Col: 7, Idx: 1066): No node deserializer was able to deserialize the node into type _.PopulationTreeNode, _, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Source=YamlDotNet
StackTrace:
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.<>c__DisplayClass3_0.<DeserializeValue>b__0(IParser r, Type t)
at YamlDotNet.Serialization.NodeDeserializers.ObjectNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value)
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.<>c__DisplayClass3_0.<DeserializeValue>b__0(IParser r, Type t)
at YamlDotNet.Serialization.NodeDeserializers.CollectionNodeDeserializer.DeserializeHelper(Type tItem, IParser parser, Func`3 nestedObjectDeserializer, IList result, Boolean canUpdate)
at YamlDotNet.Serialization.NodeDeserializers.CollectionNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser parser, Type expectedType, Func`3 nestedObjectDeserializer, Object& value)
at YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser parser, Type expectedType, SerializerState state, IValueDeserializer nestedObjectDeserializer)
at YamlDotNet.Serialization.Deserializer.Deserialize(IParser parser, Type type)
at YamlDotNet.Serialization.Deserializer.Deserialize[T](IParser parser)
at YamlDotNet.Serialization.Deserializer.Deserialize[T](TextReader input)
at YamlDotNet.Serialization.Deserializer.Deserialize[T](String input)
at _() in _
You forgot to add children
to your yaml doc:
# a population
- id: some-id
tree: !and
children:
- !basic
someProperty: hello
- !basic
someProperty: world
You don't need the custom NodeResolver
either, btw.
User contributions licensed under CC BY-SA 3.0