使用 SwashBuckle 返回文件流

Zol*_*yak 5 c# stream swagger swashbuckle

我想使用 SwashBuckle 返回文件流

    [System.Web.Http.HttpGet]
    [System.Web.Http.Route("Files/{uid}/file")]
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(Byte[]))]
    public HttpResponseMessage DownloadFile(String uid, String fileName)
    {
        return Safe.Execute(() =>
        {
            var api = new FileApi();
            var stream = api.GetFile(uid, fileName);

            HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
            result.Content = new StreamContent(stream);
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
            result.Content.Headers.ContentDisposition =
                     new ContentDispositionHeaderValue("attachment")
                     {
                         FileName = CalcFileName(fileName)
                     };
            return result;
        });
    }
Run Code Online (Sandbox Code Playgroud)

我看到文件已返回,但是......不知何故......编码。一个 3798 长的文件通过 UI 下载后变成了 5789 字节,文件内容与预期非常相似,但包含了额外的字节,就像它会被解释为字符串并成为 UTF-8 编码版本一样。

当我将其替换为:

    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(Stream))]
Run Code Online (Sandbox Code Playgroud)

Swagger 生成的描述符如下所示:

        "produces": [    
          "application/json",    
          "text/json",    
          "application/xml",    
          "text/xml"    
        ],    
        ...
        "responses": {    
          "200": {    
            "description": "OK",    
            "schema": {    
              "format": "byte",    
              "type": "string"
        }
Run Code Online (Sandbox Code Playgroud)

知道如何实现从控制器方法返回文件流吗?

Hel*_*eda 2

要描述 API 方法,您可以IOperationFilter在 swagger 配置中使用

public class UpdateFileDownloadOperations : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry s, ApiDescription a)
    {
        if (operation.operationId == "DownloadFile_Get")
        {
            operation.produces = new[] { "application/octet-stream" };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您从未使用过过滤器,请查看项目页面: https://github.com/domaindrivendev/Swashbuckle/blob/e0053e1864defa3c4f73ca2a960eb876e257cc9e/Swashbuckle.Dummy.Core/App_Start/SwaggerConfig.cs


在我的评论的示例中,我使用的Swagger-Net非常相似,但我做了一些改进,您可能注意到它使用了最新的 Swagger-UI

  • 谢谢!一想我成功了。我向该方法添加了 [SwaggerResponse(HttpStatusCode.OK, "Download a file.", typeof(FileContentResult))] 属性,然后向 SwaggerConfig.cs 添加了自定义映射: c.MapType<FileContentResult>(() => new模式{type =“字符串”,格式=“二进制”}); (4认同)