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
...
所以,我是 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
...