如何禁用Swagger中Dictionary的自动排序功能?
问题:Swagger自动排序Dictionary键,如何禁用?
我使用Swashbuckle.AspNetCore 6.7版本,定义了包含Dictionary<string, decimal>类型Info属性的DataResponse类,并通过IExamplesProvider提供了特定顺序的示例数据,但Swagger页面会自动对Dictionary的键进行排序,导致示例顺序和定义的不一致。
代码示例
public class DataResponse { public Dictionary<string, decimal> Info { get; set; } } public class DataResponseExample : IExamplesProvider<DataResponse> { public DataResponse GetExamples() => new DataResponse { Info = new Dictionary<string, decimal> { { "100", 842.123123m }, { "40", 842.123123m }, { "10", 842.123123m }, { "1", 842.123123m }, { "0.1", 842.123123m }, { "0.01", 842.123123m }, { "0.05", 842.123123m }, { "0.001", 842.123123m }, } }; }
Swagger页面显示的排序后结果
{ "info": { "1": 842.123123, "10": 842.123123, "40": 842.123123, "100": 842.123123, "0.1": 842.123123, "0.01": 842.123123, "0.05": 842.123123, "0.001": 842.123123 } }
解决方案
方法1:修改Swagger的Json序列化配置(推荐)
Swashbuckle.AspNetCore 6.x默认使用System.Text.Json序列化示例数据,而System.Text.Json默认会对Dictionary的键进行排序。要禁用该行为,只需在Swagger配置中设置JsonSerializerOptions.DictionaryKeyPolicy = null,即可保持字典的插入顺序。
在Program.cs(或Startup.cs)的Swagger配置代码中添加如下设置:
builder.Services.AddSwaggerGen(c => { // 注册示例提供器 c.ExampleFilters(); // 禁用字典键自动排序 c.JsonSerializerOptions.DictionaryKeyPolicy = null; });
方法2:替换Dictionary为OrderedDictionary(需修改模型)
如果不想调整序列化配置,可以将Dictionary<string, decimal>替换为OrderedDictionary,该类型会严格保留插入顺序。修改后的模型和示例代码如下:
public class DataResponse { public OrderedDictionary Info { get; set; } } public class DataResponseExample : IExamplesProvider<DataResponse> { public DataResponse GetExamples() { var orderedDict = new OrderedDictionary(); orderedDict.Add("100", 842.123123m); orderedDict.Add("40", 842.123123m); orderedDict.Add("10", 842.123123m); orderedDict.Add("1", 842.123123m); orderedDict.Add("0.1", 842.123123m); orderedDict.Add("0.01", 842.123123m); orderedDict.Add("0.05", 842.123123m); orderedDict.Add("0.001", 842.123123m); return new DataResponse { Info = orderedDict }; } }
注意:使用OrderedDictionary时,需确保Swagger能正确识别该类型,必要时需添加额外的类型映射配置。
方法3:自定义示例序列化逻辑
若以上方法均不适用,可以直接返回预定义的JSON字符串来绕过自动序列化,确保示例顺序完全符合预期:
public class DataResponseExample : IExamplesProvider<object> { public object GetExamples() { return JsonSerializer.Deserialize<object>(@"{ ""info"": { ""100"": 842.123123, ""40"": 842.123123, ""10"": 842.123123, ""1"": 842.123123, ""0.1"": 842.123123, ""0.01"": 842.123123, ""0.05"": 842.123123, ""0.001"": 842.123123 } }"); } }
这种方法直接控制输出的JSON内容,但后续维护示例数据时需要手动修改字符串,灵活性较差。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

