簡體   English   中英

使用 YamlDotNet 將 yaml 文件反序列化為抽象 class 的屬性時出現異常

[英]Exception when deserializing yaml file to property of abstract class using YamlDotNet

使用 YamlDotNet,我試圖將帶有嵌套 object 圖的 yaml 文件反序列化為一組自定義 .net 類型。 如果我將樹屬性設置為簡單的 PopulationBasicNode,則此方法有效,但是當我使用示例中所示的 PopulationAndNode 時,會引發 YamlException:

沒有節點反序列化器能夠將節點反序列化為 PopulationTreeNode 類型

我認為使用反序列化器構建器的以下擴展方法將使反序列化器能夠解析類型。

WithTagMapping("!and", typeof(PopulationAndNode))

我也嘗試注冊一個 INodeTypeResolver,但我仍然得到相同的 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 _

您忘記將children添加到您的 yaml 文檔中:

# a population
- id: some-id
  tree: !and
    children:
      - !basic
        someProperty: hello
      - !basic
        someProperty: world

順便說一句,您也不需要自定義NodeResolver

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM