C#中将带连字符的YAML键反序列化为类对象问题求助
解决YAML连字符键反序列化映射问题
核心问题分析
你代码中使用的[JsonProperty]是Newtonsoft.Json专属特性,YamlDotNet并不识别该属性,这是导致带连字符的price-lore无法映射到PriceLore字段的直接原因。另外,UnderscoredNamingConvention仅处理下划线与驼峰的转换,对连字符无效,这也是命名约定未生效的原因。
解决方案
1. 使用YamlDotNet专属特性标记(推荐,精准控制)
替换[JsonProperty]为YamlDotNet的[YamlMember]特性,手动指定YAML键的别名:
using YamlDotNet.Serialization; public class Cosmetic { [YamlMember(Alias = "type")] public string Type { get; set; } [YamlMember(Alias = "price-lore")] public string[] PriceLore { get; set; } }
2. 优化反序列化流程(可选,提升效率)
你当前先将cosmeticsNode序列化为字符串再反序列化的步骤完全冗余,可直接从节点反序列化:
修改LoadFromFile方法中的反序列化逻辑:
// 移除序列化再反序列化的冗余步骤 var deserializer = new DeserializerBuilder() .IgnoreUnmatchedProperties() .Build(); Cosmetics = deserializer.Deserialize<Dictionary<string, Cosmetic>>(cosmeticsNode);
3. 自定义连字符命名约定(批量处理,可选)
如果存在大量带连字符的键,不想逐个添加特性,可以自定义命名约定实现连字符转驼峰:
public class HyphenatedNamingConvention : INamingConvention { public string Apply(string value) { // 将连字符分割的字符串转为驼峰格式,如price-lore → PriceLore return string.Concat(value.Split('-').Select(word => char.ToUpper(word[0]) + word.Substring(1))); } }
构建反序列化器时启用该约定:
var deserializer = new DeserializerBuilder() .WithNamingConvention(new HyphenatedNamingConvention()) .IgnoreUnmatchedProperties() .Build();
这种情况下无需添加[YamlMember]特性,YAML中的price-lore会自动映射到PriceLore,type自动映射到Type。
验证效果
修改后重新运行代码,price-lore对应的列表会正确映射到Cosmetic类的PriceLore数组,其他带连字符的键也能按规则完成映射。
内容的提问来源于stack exchange,提问作者J0r1s
相关产品推荐
相关产品推荐

