反序列化对象时,YamlDotNet引发异常

时间:2019-12-19 16:54:18

标签: yamldotnet

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

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:(第2行,Col:5,Idx:8)-(第2行,Col:5,Idx:8):反序列化期间的异常---> System.Runtime.Serialization。 SerializationException:在“ HareDu.Diagnostics.Configuration.InternalDiagnosticScannerConfig”类型上找不到属性“ high-closure-rate-warning-threshold”。    在YamlDotNet.Serialization.TypeInspectors.TypeInspectorSkeleton.GetProperty(类型类型,对象容器,字符串名称,布尔值ignoreUnmatched)    在YamlDotNet.Serialization.NodeDeserializers.ObjectNodeDeserializer.YamlDotNet.Serialization.INodeDeserializer.Deserialize(IParser解析器,类型ExpectedType,Func`3 nestedObjectDeserializer,Object&value)    在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解析器,类型期望类型,SerializerState状态,IValueDeserializer nestedObjectDeserializer)处    在YamlDotNet.Serialization.Deserializer.Deserialize(IParser解析器,类型类型)    在YamlDotNet.Serialization.Deserializer.Deserialize [T](IParser解析器)处    在YamlDotNet.Serialization.Deserializer.Deserialize [T](TextReader输入)    在/Users/albert/Documents/Git/HareDu2/src/HareDu.Diagnostics/Configuration/DiagnosticScannerConfigProvider.cs:line 59

中的HareDu.Diagnostics.Configuration.DiagnosticScannerConfigProvider.TryGet(字符串路径,DiagnosticScannerConfig&config)中

1 个答案:

答案 0 :(得分:0)

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

实际上,可以使用以下方法:

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
...