[英]Adding Query String Params to my Swagger Specs
我在我的 Web API 中使用 Swashbuckle(C# 的 swagger)。我有幾個返回列表的 GET 端點,我允許用戶將每頁和頁面參數添加到 QueryString
示例: http://myapi.com/endpoint/?page=5&perpage=10
我看到 swagger 確實支持“查詢”中的參數,但如何讓 Swashbuckle 執行此操作?
我在其中一條評論中提到,我通過創建一個自定義屬性來解決我的問題,讓我可以做我需要的事情。 以下是我的解決方案的代碼:
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public class SwaggerParameterAttribute : Attribute
{
public SwaggerParameterAttribute(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; private set; }
public Type DataType { get; set; }
public string ParameterType { get; set; }
public string Description { get; private set; }
public bool Required { get; set; } = false;
}
使用 Swagger 配置注冊屬性:
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
c.OperationFilter<SwaggerParametersAttributeHandler>();
});
然后將此屬性添加到您的方法中:
[SwaggerParameter("page", "Page number to display", DataType = typeof(Int32), ParameterType = ParameterType.inQuery)]
[SwaggerParameter("perpage","Items to display per page", DataType = typeof(Int32), ParameterType = ParameterType.inQuery)]
你可以很容易地實現這一目標。 假設你有一個ItemsController
,其動作如下:
[Route("/api/items/{id}")]
public IHttpActionResult Get(int id, int? page = null, int? perpage = null)
{
// some relevant code
return Ok();
}
Swashbuckle將生成此規范(僅顯示相關部分):
"paths":{
"/api/items/{id}":{
"get":{
"parameters":[
{
"name":"id",
"in":"path",
"required":true,
"type":"integer",
"format":"int32"
},
{
"name":"page",
"in":"query",
"required":false,
"type":"integer",
"format":"int32"
},
{
"name":"limit",
"in":"query",
"required":false,
"type":"integer",
"format":"int32"
}
]
}
}
當你想page
和perpage
被要求,才使參數不能為空。
以下是Attribute方法所需步驟(ASP.Net Core 2.1,Swashbuckle.AspNetCore v4.0.1)的摘要。 我需要一個以“$”開頭的參數,所以可選參數不是一個選項!
SwaggerParameterAttribute.cs
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public class SwaggerParameterAttribute : Attribute
{
public SwaggerParameterAttribute(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; private set; }
public string DataType { get; set; }
public string ParameterType { get; set; }
public string Description { get; private set; }
public bool Required { get; set; } = false;
}
SwaggerParameterAttributeFilter.cs
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Linq;
public class SwaggerParameterAttributeFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
var attributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
.Union(context.MethodInfo.GetCustomAttributes(true))
.OfType<SwaggerParameterAttribute>();
foreach (var attribute in attributes)
operation.Parameters.Add(new NonBodyParameter
{
Name = attribute.Name,
Description = attribute.Description,
In = attribute.ParameterType,
Required = attribute.Required,
Type = attribute.DataType
});
}
}
在Startup.ConfigureServices中添加它
using Swashbuckle.AspNetCore.Swagger;
services.AddSwaggerGen(c =>
{
c.OperationFilter<SwaggerParameterAttributeFilter>();
c.SwaggerDoc("v1.0", new Info { Title = "My API", Version = "v1.0" });
});
並使用這樣的:
[SwaggerParameter("$top", "Odata Top parameter", DataType = "integer", ParameterType ="query")]
DataTypes可以是:integer,string,boolean
ParameterTypes:可以是路徑,正文,查詢
這里有一些關於SwaggerParametersAttributeHandler缺失信息的評論。 它是一個操作過濾器,可幫助您確定如何對屬性執行操作。
這是我使用的一個示例處理程序,它允許我使用SwaggerParameterAttribute覆蓋可空參數的必填字段。
public class RequiredParameterOverrideOperationFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
// Get all SwaggerParameterAttributes on the method
var attributes = apiDescription.ActionDescriptor.GetCustomAttributes<SwaggerParameterAttribute>();
if (operation.parameters == null)
{
operation.parameters = new List<Parameter>();
}
// For each attribute found, find the operation parameter (this is where Swagger looks to generate the Swagger doc)
// Override the required fields based on the attribute's required field
foreach (var attribute in attributes)
{
var referencingOperationParameter = operation.parameters.FirstOrDefault(p => p.name == attribute.Name);
if (referencingOperationParameter != null)
{
referencingOperationParameter.required = attribute.Required;
}
}
}
}
我知道這很舊,但我花了一些時間尋找更簡單的方法並找到了它。 所以對於任何也偶然發現這個舊線程的人來說,這里是:
public async Task<IActionResult> Foo([FromQuery]YourDtoType dto)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.