Asp.net-Web-Api
我如何告訴 Swashbuckle 需要正文內容?
我有一個 WebAPI 控制器,它接受二進制包並將它們儲存在某個地方。由於這些包可能變得非常大,我不想通過添加字節數組參數將它們載入到記憶體中,而是通過流傳遞。
我在這個答案中找到了一種方法:
[HttpPost] [Route("Store/{projectId}")] public async Task Store(string projectId) { using (var stream = await this.Request.Content.ReadAsStreamAsync()) { await this.packageManager.StorePackageAsync(projectId, stream); } }這行得通,我可以使用 Postman 將文件發送到控制器。但是,我現在想用 Swashbuckle 生成 swagger 文件,當然,這裡沒有提到所需的正文內容。
有沒有辦法獲取請求內容的流,以便 Swashbuckle 知道它?或者是否有一個屬性可以用來告訴它所需的內容?
要實現這一點,您必須做幾件事。
首先,您必須告訴 Swagger 在正文中有一個包含二進制數據的參數。接下來,您必須告訴 Swagger 端點使用二進制數據(例如 application/octet-stream)。
Swashbuckle 不支持此功能。但是您可以創建自定義過濾器來擴展 Swashbuckle 的功能。我通常做的是創建一個自定義屬性來裝飾一個方法,然後創建一個自定義過濾器來對該屬性進行操作。
在您的情況下,這可以解決問題:
自定義屬性
public class BinaryPayloadAttribute : Attribute { public BinaryPayloadAttribute() { ParameterName = "payload"; Required = true; MediaType = "application/octet-stream"; Format = "binary"; } public string Format { get; set; } public string MediaType { get; set; } public bool Required { get; set; } public string ParameterName { get; set; } }自定義過濾器
public class BinaryPayloadFilter : IOperationFilter { public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) { var attribute = apiDescription.GetControllerAndActionAttributes<BinaryPayloadAttribute>().FirstOrDefault(); if (attribute == null) { return; } operation.consumes.Clear(); operation.consumes.Add(attribute.MediaType); operation.parameters.Add(new Parameter { name = attribute.ParameterName, @in = "body", required = attribute.Required, type = "string", format = attribute.Format }); } }將過濾器添加到 Swashbuckle 配置
GlobalConfiguration.Configuration .EnableSwagger(c => { // other configuration setting removed for brevity c.OperationFilter<BinaryPayloadFilter>(); });將屬性應用於您的方法
[HttpPost] [BinaryPayload] [Route("Store/{projectId}")] public async Task Store(string projectId) { ... }在 Swagger UI 中,您將獲得:
又一個更新。這是我最終使用
ASP.NET Core 3.1and的解決方案Swashbuckle.AspNetCore.Swagger 5.0.0:public class BinaryContentAttribute : Attribute { }public class BinaryContentFilter : IOperationFilter { /// <summary> /// Configures operations decorated with the <see cref="BinaryContentAttribute" />. /// </summary> /// <param name="operation">The operation.</param> /// <param name="context">The context.</param> public void Apply(OpenApiOperation operation, OperationFilterContext context) { var attribute = context.MethodInfo.GetCustomAttributes(typeof(BinaryContentAttribute), false).FirstOrDefault(); if (attribute == null) { return; } operation.RequestBody = new OpenApiRequestBody() { Required = true }; operation.RequestBody.Content.Add("application/octet-stream", new OpenApiMediaType() { Schema = new OpenApiSchema() { Type = "string", Format = "binary", }, }); } }
ConfigureServices在Startup.cs:services.AddSwaggerGen(o => { o.OperationFilter<BinaryContentFilter>(); });
