.NET 5中使用System.Text.Json序列化时如何让Hashtable按键排序?
.NET 5中Hashtable序列化时按键有序输出的实现方案
问题描述
使用以下代码序列化对象时,对象层级中的Hashtable内容无法保证按键有序输出,需要在不修改Hashtable为SortedDictionary(避免破坏现有BinaryFormatter序列化流)的前提下,实现Hashtable内容按字符串键有序输出:
var options = new JsonSerializerOptions { WriteIndented = true, IncludeFields = true}; string jsonString = JsonSerializer.Serialize(obj, options); File.WriteAllText("output.json", jsonString);
解决方案
通过自定义JsonConverter<Hashtable>来控制Hashtable的序列化逻辑,在序列化时对键进行排序后输出:
1. 实现自定义转换器
创建一个针对Hashtable的Json转换器,在序列化阶段将键排序后写入JSON:
using System.Collections; using System.Text.Json; using System.Text.Json.Serialization; public class SortedHashtableConverter : JsonConverter<Hashtable> { // 反序列化保持默认逻辑,不影响原有Hashtable的结构 public override Hashtable Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(ref reader, options); var hashtable = new Hashtable(); foreach (var kvp in dict) { hashtable.Add(kvp.Key, kvp.Value); } return hashtable; } // 序列化时按键排序输出 public override void Write(Utf8JsonWriter writer, Hashtable value, JsonSerializerOptions options) { writer.WriteStartObject(); // 将Hashtable的键转为字符串并按自然顺序排序 var sortedKeys = value.Keys.Cast<string>().OrderBy(key => key); foreach (var key in sortedKeys) { writer.WritePropertyName(key); JsonSerializer.Serialize(writer, value[key], options); } writer.WriteEndObject(); } }
2. 在序列化选项中添加转换器
修改原有序列化代码,将自定义转换器加入JsonSerializerOptions的转换器集合:
var options = new JsonSerializerOptions { WriteIndented = true, IncludeFields = true, Converters = { new SortedHashtableConverter() } }; string jsonString = JsonSerializer.Serialize(obj, options); File.WriteAllText("output.json", jsonString);
注意事项
- 该转换器仅作用于Hashtable类型,不会影响其他类的字段排序,完全符合需求
- 反序列化逻辑保持了Hashtable的原有行为,不会对现有BinaryFormatter的序列化流造成破坏
- 代码中默认按键为字符串处理,若存在非字符串键的场景,可根据实际情况调整
Cast<string>()的转换逻辑
内容的提问来源于stack exchange,提问作者malat
相关产品推荐
相关产品推荐

