YamlDotNet 在反序列化对象时抛出异常

YamlDotNet throwing exception when deserializing object

所以,我是 Yaml 和 YamlDotNet 的新手。我编写了以下代码来解析我用于配置客户端的 yaml 文件 API...

public bool TryGet(string path, out DiagnosticScannerConfig config)
{
    var deserializer = new DeserializerBuilder()
        .WithNamingConvention(new HyphenatedNamingConvention())
        .Build();

    try
    {
        using (var reader = File.OpenText(path))
        {
            var deserializedConfig = deserializer.Deserialize<InternalDiagnosticScannerConfig>(reader);

            config = new DiagnosticScannerConfigImpl(deserializedConfig);
            return true;
        }
    }
    catch (Exception e)
    {
        config = DiagnosticAnalyzerConfigCache.Default;
        return true;
    }
}

public interface DiagnosticScannerConfig
{
    DiagnosticAnalyzerConfig Analyzer { get; }
}

public interface DiagnosticAnalyzerConfig
{
    uint HighClosureRateWarningThreshold { get; }
    uint HighCreationRateWarningThreshold { get; }
    uint QueueHighFlowThreshold { get; }
    uint QueueLowFlowThreshold { get; }
    decimal MessageRedeliveryCoefficient { get; }
    decimal SocketUsageCoefficient { get; }
    decimal RuntimeProcessUsageCoefficient { get; }
    decimal FileDescriptorUsageWarningCoefficient { get; }
    decimal ConsumerUtilizationWarningCoefficient { get; }
}

class DiagnosticScannerConfigImpl : DiagnosticScannerConfig
{
    public DiagnosticScannerConfigImpl(InternalDiagnosticScannerConfig config)
    {
        Analyzer = new DiagnosticAnalyzerConfigImpl(config.Analyzer);
    }

    class DiagnosticAnalyzerConfigImpl : DiagnosticAnalyzerConfig
    {
        public DiagnosticAnalyzerConfigImpl(Analyzer config)
        {
            HighClosureRateWarningThreshold = config.HighClosureRateWarningThreshold;
            HighCreationRateWarningThreshold = config.HighCreationRateWarningThreshold;
            QueueHighFlowThreshold = config.QueueHighFlowThreshold;
            QueueLowFlowThreshold = config.QueueLowFlowThreshold;
            MessageRedeliveryCoefficient = config.MessageRedeliveryCoefficient;
            SocketUsageCoefficient = config.SocketUsageCoefficient;
            RuntimeProcessUsageCoefficient = config.RuntimeProcessUsageCoefficient;
            FileDescriptorUsageWarningCoefficient = config.FileDescriptorUsageWarningCoefficient;
            ConsumerUtilizationWarningCoefficient = config.ConsumerUtilizationWarningCoefficient;
        }

        public uint HighClosureRateWarningThreshold { get; }
        public uint HighCreationRateWarningThreshold { get; }
        public uint QueueHighFlowThreshold { get; }
        public uint QueueLowFlowThreshold { get; }
        public decimal MessageRedeliveryCoefficient { get; }
        public decimal SocketUsageCoefficient { get; }
        public decimal RuntimeProcessUsageCoefficient { get; }
        public decimal FileDescriptorUsageWarningCoefficient { get; }
        public decimal ConsumerUtilizationWarningCoefficient { get; }
    }

    public DiagnosticAnalyzerConfig Analyzer { get; }
}


public class Analyzer
{
    [YamlMember(Alias = "high-closure-rate-warning-threshold")]
    public uint HighClosureRateWarningThreshold { get; set; }

    [YamlMember(Alias = "high-creation-rate-warning-threshold")]
    public uint HighCreationRateWarningThreshold { get; set; }

    [YamlMember(Alias = "queue-high-flow-threshold")]
    public uint QueueHighFlowThreshold { get; set; }

    [YamlMember(Alias = "queue-low-flow-threshold")]
    public uint QueueLowFlowThreshold { get; set; }

    [YamlMember(Alias = "message-redelivery-coefficient")]
    public decimal MessageRedeliveryCoefficient { get; set; }

    [YamlMember(Alias = "socket-usage-coefficient")]
    public decimal SocketUsageCoefficient { get; set; }

    [YamlMember(Alias = "runtime-process-usage-coefficient")]
    public decimal RuntimeProcessUsageCoefficient { get; set; }

    [YamlMember(Alias = "file-descriptor-usage-warning-coefficient")]
    public decimal FileDescriptorUsageWarningCoefficient { get; set; }

    [YamlMember(Alias = "consumer-utilization-warning-coefficient")]
    public decimal ConsumerUtilizationWarningCoefficient { get; set; }
}

public class InternalDiagnosticScannerConfig
{
    public Analyzer Analyzer { get; }
}

我正在尝试解析以下 yaml 文件:

---
    high-closure-rate-warning-threshold:  90
    high-creation-rate-warning-threshold: 60
    queue-high-flow-threshold:  90
    queue-low-flow-threshold: 10
    message-redelivery-coefficient: 0.60
    socket-usage-coefficient: 0.60
    runtime-process-usage-coefficient:  0.65
    file-descriptor-usage-warning-coefficient:  0.65
    consumer-utilization-warning-coefficient: 0.65
...

当我执行上面的代码时,出现以下错误:

YamlDotNet.Core.YamlException: (Line: 2, Col: 5, Idx: 8) - (Line: 2, Col: 5, Idx: 8): 反序列化期间异常---> System.Runtime.Serialization.SerializationException:属性 'high-closure-rate-warning-threshold' 在类型 'HareDu.Diagnostics.Configuration.InternalDiagnosticScannerConfig' 上找不到。 在 YamlDotNet.Serialization.TypeInspectors.TypeInspectorSkeleton.GetProperty(类型类型、对象容器、字符串名称、布尔值忽略不匹配) 在 YamlDotNet.Serialization.NodeDeserializers.ObjectNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser 解析器,类型 expectedType,Func`3 nestedObjectDeserializer,对象和值) 在 YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser 解析器,类型 expectedType,SerializerState 状态,IValueDeserializer nestedObjectDeserializer) --- 内部异常堆栈跟踪结束 --- 在 YamlDotNet.Serialization.ValueDeserializers.NodeValueDeserializer.DeserializeValue(IParser 解析器,类型 expectedType,SerializerState 状态,IValueDeserializer nestedObjectDeserializer) 在 YamlDotNet.Serialization.ValueDeserializers.AliasValueDeserializer.DeserializeValue(IParser 解析器,类型 expectedType,SerializerState 状态,IValueDeserializer nestedObjectDeserializer) 在 YamlDotNet.Serialization.Deserializer.Deserialize(IParser 解析器,Type 类型) 在 YamlDotNet.Serialization.Deserializer.Deserialize[T](IParser 解析器) 在 YamlDotNet.Serialization.Deserializer.Deserialize[T](TextReader 输入) 在 HareDu.Diagnostics.Configuration.DiagnosticScannerConfigProvider.TryGet(字符串路径,DiagnosticScannerConfig& 配置)在 /Users/albert/Documents/Git/HareDu2/src/HareDu.Diagnostics/Configuration/DiagnosticScannerConfigProvider.cs:第 59 行

异常消息告诉您问题所在:您的类型 InternalDiagnosticScannerConfig 没有 'high-closure-rate-warning-threshold' 属性。实际上,在您的代码中 属性 是在分析器 class 中定义的。您应该反序列化为该类型,或者更新您的 YAML,使其结构反映您的 classes.

在实践中,要么使用这个:

deserializer.Deserialize<InternalDiagnosticScannerConfig>(reader);

或者这样:

---
analyzer:
    high-closure-rate-warning-threshold:  90
    high-creation-rate-warning-threshold: 60
    queue-high-flow-threshold:  90
    queue-low-flow-threshold: 10
    message-redelivery-coefficient: 0.60
    socket-usage-coefficient: 0.60
    runtime-process-usage-coefficient:  0.65
    file-descriptor-usage-warning-coefficient:  0.65
    consumer-utilization-warning-coefficient: 0.65
...