You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET中序列化List<KeyValuePair<string,string>>至YAML格式异常问题

问题:ASP.NET(C#)修改YAML文件时格式异常

现有YAML文件内容:

pcap:
- interface: eth0
- interface: default

通过C#代码向其中添加新的interface条目,但生成的YAML出现Key和Value字段,格式不符合预期,且无法用Dictionary处理重复键的问题。

错误代码:

var path = "/etc/suricata/suricata_cp.yaml";
var deserializer = new YamlDotNet.Serialization.Deserializer();

try
{
    using var reader = new StreamReader(path);
    var obj = deserializer.Deserialize<Dictionary<object, object>>(reader);
    var doctrine = obj["pcap"];

    List<object> pcap = (List<object>)obj["pcap"];
    List<KeyValuePair<string,string>> addInterfaces = new List<KeyValuePair<string, string>>();

    foreach(var cli in clientReq)
        addInterfaces.Add(new KeyValuePair<string, string>("interface",cli));

    pcap.Add(addInterfaces);

    doctrine = pcap;
    reader.Close();

    using var writer = new StreamWriter(path);
    // Save Changes
    var serializer = new YamlDotNet.Serialization.Serializer();
    serializer.Serialize(writer, obj);
}

错误输出结果:

pcap:
- interface: eth0
- interface: default
- - Key: interface
    Value: eth3

问题原因

  1. 直接将List<KeyValuePair<...>>添加到pcap列表,序列化时会把键值对的结构原样输出成Key和Value字段;
  2. 原YAML中每个interface条目是单键的匿名对象/字典,而非键值对集合。

修复方案

方案1:使用动态类型(简洁灵活)

直接创建包含interface属性的匿名对象添加到列表,匹配原YAML格式:

var path = "/etc/suricata/suricata_cp.yaml";
var deserializer = new YamlDotNet.Serialization.Deserializer();

try
{
    using var reader = new StreamReader(path);
    dynamic obj = deserializer.Deserialize(reader);
    List<dynamic> pcapList = obj.pcap as List<dynamic>;

    foreach(var cli in clientReq)
    {
        // 每个对象对应一条- interface: xxx条目
        pcapList.Add(new { @interface = cli });
    }

    using var writer = new StreamWriter(path);
    var serializer = new YamlDotNet.Serialization.Serializer();
    serializer.Serialize(writer, obj);
}
catch (Exception ex)
{
    // 按需处理异常
}

方案2:自定义类实现类型安全

定义对应YAML结构的类,通过类映射保证序列化格式:

// 定义匹配interface条目的类
public class InterfaceEntry
{
    [YamlMember(Alias = "interface")]
    public string InterfaceName { get; set; }
}

// 修改后的业务代码
var path = "/etc/suricata/suricata_cp.yaml";
var deserializer = new YamlDotNet.Serialization.DeserializerBuilder()
    .WithNamingConvention(CamelCaseNamingConvention.Instance)
    .Build();

try
{
    using var reader = new StreamReader(path);
    var obj = deserializer.Deserialize<Dictionary<string, object>>(reader);
    var pcapList = deserializer.Deserialize<List<InterfaceEntry>>(obj["pcap"].ToString());

    foreach(var cli in clientReq)
    {
        pcapList.Add(new InterfaceEntry { InterfaceName = cli });
    }

    obj["pcap"] = pcapList;

    using var writer = new StreamWriter(path);
    var serializer = new YamlDotNet.Serialization.SerializerBuilder()
        .WithNamingConvention(CamelCaseNamingConvention.Instance)
        .Build();
    serializer.Serialize(writer, obj);
}
catch (Exception ex)
{
    // 按需处理异常
}

关键注意事项

  • 不要批量添加键值对列表,而是逐个添加单键对象,每个对象对应一条- interface: xxx条目;
  • 使用动态类型或自定义类能更好匹配YAML结构,避免强制类型转换的潜在问题。

内容的提问来源于stack exchange,提问作者prog_prog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:20:48