如何让NSwag生成的Swagger Schema中派生类属性排在基类属性之前
问题原因
NSwag 默认生成 Swagger Schema 时,会优先拼接基类的所有属性,再拼接派生类属性,派生类属性上的[JsonProperty(Order)]注解默认仅在派生类属性集合内部生效,无法覆盖基类属性的默认排序优先级,所以才会出现基类属性全部排在派生类属性前面的情况。
解决方案
方案1:自定义 Schema 处理器(优先推荐,无需修改现有业务代码)
- 实现
ISchemaProcessor接口,全局按照JsonProperty的Order值排序所有属性:
using Namotion.Reflection; using NSwag.Generation.Processors; using NSwag.Generation.Processors.Contexts; using Newtonsoft.Json; using System.Reflection; public class JsonPropertyOrderSchemaProcessor : ISchemaProcessor { public void Process(SchemaProcessorContext context) { // 读取当前类型的所有实例属性(含基类属性) var allProperties = context.Type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Select(prop => new { PropertyInfo = prop, // 读取JsonProperty的Order配置,无配置默认设为int.MaxValue,排在最后 Order = prop.GetCustomAttribute<JsonPropertyAttribute>()?.Order ?? int.MaxValue, // 读取自定义序列化别名,无配置则用属性本身名称 SerializedName = prop.GetCustomAttribute<JsonPropertyAttribute>()?.PropertyName ?? prop.Name }) .OrderBy(p => p.Order) .ToList(); // 按Order排序后重新赋值Schema的属性集合 var orderedProperties = allProperties .Where(p => context.Schema.Properties.ContainsKey(p.SerializedName)) .ToDictionary( p => p.SerializedName, p => context.Schema.Properties[p.SerializedName] ); context.Schema.Properties.Clear(); foreach (var prop in orderedProperties) { context.Schema.Properties.Add(prop.Key, prop.Value); } } }
- 在 NSwag 配置中注册这个处理器,以ASP.NET Core为例:
builder.Services.AddOpenApiDocument(settings => { // 保留你原有其他NSwag配置 settings.SchemaProcessors.Add(new JsonPropertyOrderSchemaProcessor()); });
配置完成后,Dog类的Name属性因为设置了Order = -2,会自动排在所有没有设置Order(默认int.MaxValue)的基类属性前面,符合你预期的输出效果。
方案2:调整基类属性的Order配置(仅适合可以修改基类代码的场景)
如果你可以修改Animal基类的代码,给基类的所有属性显式设置[JsonProperty(Order = 1)]这类大于等于0的Order值,派生类需要前置的属性设置负数的Order值,也可以实现相同效果,无需自定义处理器。
内容的提问来源于stack exchange,提问作者mnc
相关产品推荐
相关产品推荐

