C# - 从 Swagger API 文档中的抽象 class 订购所需的参数
C# - Ordering required params from abstract class in Swagger API documentation
在问这个问题之前我已经搜索了很多,但我发现的所有内容都与其他主题相关,比如 swagger doc 中的排序路径。
我可以通过这个简单的例子来说明我的问题所在:
abstract class Animal
{
[Required]
public string Name { get; set; }
}
class Dog : Animal
{
[Required]
public bool CanBark { get; set; }
public Color DogColor { get; set; }
}
但在我生成的 Swagger API 文档中,参数按以下顺序出现:
- CanBark(必需)
- 狗狗颜色
- 姓名(必填)
基本上,我想更改它们在生成的文档中出现的顺序。所以,为了做到这一点,我在 SwashBuckleConfig.cs
中创建了一个 class
internal class SortBodyParams : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
var properties = schemaRegistry.Definitions.Values;
foreach (var prop in properties) // Maybe something like this
{
// Order params by Required type and by name
// This code doesn't change anything,
// although I thought it would help to order params by name
prop.properties
.OrderBy(x => x.Key)
.ToList()
.ToDictionary(x => x.Key, y => y.Value);
}
}
}
并从 Register 方法调用 class:
public static void Register(HttpConfiguration config)
{
config
.EnableSwagger(sdc =>
{
...
sdc.DocumentFilter<SortBodyParams>();
...
}
}
有人可以帮我先订购所需的参数,然后再按名称订购吗?
想了很久解决这个问题,终于想到了解决办法:
internal class SortBodyParams : IDocumentFilter
{
private Schema _schema = new Schema();
public void Apply(
SwaggerDocument swaggerDoc,
SchemaRegistry schemaRegistry,
IApiExplorer apiExplorer)
{
foreach (var schema in schemaRegistry.Definitions.Values)
{
_schema = schema;
var allFields = GetAllFieldsInSchema();
var reqFields = GetAllRequiredFieldsInSchema();
_schema.properties.Clear();
AddAllRequiredFieldsInSchema(allFields, reqFields);
AddAllOptionalFieldsInSchema(allFields, reqFields);
}
}
public Dictionary<string, Schema> GetAllFieldsInSchema()
{
return _schema.properties
.OrderBy(x => x.Key)
.ToList()
.ToDictionary(x => x.Key, y => y.Value);
}
public IList<string> GetAllRequiredFieldsInSchema()
{
var requiredFields = _schema.required;
if (ThereAreRequiredFields())
{
return requiredFields
.OrderBy(x => x)
.ToList();
}
return requiredFields;
}
public void AddAllRequiredFieldsInSchema(
Dictionary<string, Schema> allFields,
IList<string> reqFields)
{
if (ThereAreRequiredFields())
{
int index = 0;
int notAllowedIndex = reqFields.Count;
foreach (var field in allFields)
{
if (field.Key == reqFields[index])
{
_schema.properties.Add(field.Key, field.Value);
index++;
if (index == notAllowedIndex) break;
}
}
}
}
public void AddAllOptionalFieldsInSchema(
Dictionary<string, Schema> allFields,
IList<string> reqFields)
{
foreach (var field in allFields)
{
if (ThereAreRequiredFields())
{
if (!reqFields.Contains(field.Key))
{
_schema.properties.Add(field.Key, field.Value);
}
}
else
{
_schema.properties.Add(field.Key, field.Value);
}
}
}
public bool ThereAreRequiredFields()
{
if (_schema.required != null)
{
return true;
}
return false;
}
}
为了解决我的问题,我只需要删除所有字段并按我想要的顺序添加它们。
在问这个问题之前我已经搜索了很多,但我发现的所有内容都与其他主题相关,比如 swagger doc 中的排序路径。
我可以通过这个简单的例子来说明我的问题所在:
abstract class Animal
{
[Required]
public string Name { get; set; }
}
class Dog : Animal
{
[Required]
public bool CanBark { get; set; }
public Color DogColor { get; set; }
}
但在我生成的 Swagger API 文档中,参数按以下顺序出现:
- CanBark(必需)
- 狗狗颜色
- 姓名(必填)
基本上,我想更改它们在生成的文档中出现的顺序。所以,为了做到这一点,我在 SwashBuckleConfig.cs
中创建了一个 class internal class SortBodyParams : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
{
var properties = schemaRegistry.Definitions.Values;
foreach (var prop in properties) // Maybe something like this
{
// Order params by Required type and by name
// This code doesn't change anything,
// although I thought it would help to order params by name
prop.properties
.OrderBy(x => x.Key)
.ToList()
.ToDictionary(x => x.Key, y => y.Value);
}
}
}
并从 Register 方法调用 class:
public static void Register(HttpConfiguration config)
{
config
.EnableSwagger(sdc =>
{
...
sdc.DocumentFilter<SortBodyParams>();
...
}
}
有人可以帮我先订购所需的参数,然后再按名称订购吗?
想了很久解决这个问题,终于想到了解决办法:
internal class SortBodyParams : IDocumentFilter
{
private Schema _schema = new Schema();
public void Apply(
SwaggerDocument swaggerDoc,
SchemaRegistry schemaRegistry,
IApiExplorer apiExplorer)
{
foreach (var schema in schemaRegistry.Definitions.Values)
{
_schema = schema;
var allFields = GetAllFieldsInSchema();
var reqFields = GetAllRequiredFieldsInSchema();
_schema.properties.Clear();
AddAllRequiredFieldsInSchema(allFields, reqFields);
AddAllOptionalFieldsInSchema(allFields, reqFields);
}
}
public Dictionary<string, Schema> GetAllFieldsInSchema()
{
return _schema.properties
.OrderBy(x => x.Key)
.ToList()
.ToDictionary(x => x.Key, y => y.Value);
}
public IList<string> GetAllRequiredFieldsInSchema()
{
var requiredFields = _schema.required;
if (ThereAreRequiredFields())
{
return requiredFields
.OrderBy(x => x)
.ToList();
}
return requiredFields;
}
public void AddAllRequiredFieldsInSchema(
Dictionary<string, Schema> allFields,
IList<string> reqFields)
{
if (ThereAreRequiredFields())
{
int index = 0;
int notAllowedIndex = reqFields.Count;
foreach (var field in allFields)
{
if (field.Key == reqFields[index])
{
_schema.properties.Add(field.Key, field.Value);
index++;
if (index == notAllowedIndex) break;
}
}
}
}
public void AddAllOptionalFieldsInSchema(
Dictionary<string, Schema> allFields,
IList<string> reqFields)
{
foreach (var field in allFields)
{
if (ThereAreRequiredFields())
{
if (!reqFields.Contains(field.Key))
{
_schema.properties.Add(field.Key, field.Value);
}
}
else
{
_schema.properties.Add(field.Key, field.Value);
}
}
}
public bool ThereAreRequiredFields()
{
if (_schema.required != null)
{
return true;
}
return false;
}
}
为了解决我的问题,我只需要删除所有字段并按我想要的顺序添加它们。