c# - 使用未在 swagger 中公开的 HTTP 内容上传 API 文件

标签 c# api swagger

我正在现有的 Web API 中实现一个 swagger 接口(interface)。当前的 API Controller 公开了一个异步上传函数,该函数使用 Request.Content 异步传输图像。已使用的代码在this中有解释。文章。

我的 API Controller :

    [HttpPost]
    [Route("foo/bar/upload")]
    public async Task<HttpResponseMessage> Upload()
    {
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
        var provider = await Request.Content.ReadAsMultipartAsync(new InMemoryMultipartFormDataStreamProvider());
        NameValueCollection formData = provider.FormData;
        HttpResponseMessage response;
        //access files  
        IList<HttpContent> files = provider.Files;
        if (files.Count > 0)
        {
            HttpContent file1 = files[0];
            using (Stream input = await file1.ReadAsStreamAsync())
            {
                object responseObj = ExternalProcessInputStream(input)
                response = Request.CreateResponse(HttpStatusCode.OK, responseObj);
            }
        }
        else 
        {
            response = Request.CreateResponse(HttpStatusCode.BadRequest);
        }
        return response;
    }

这很有效,但是当我通过 swagger 公开它时,我有一个无参数函数,它在使用时返回错误。

我的问题是如何提供适当的值来测试此方法?

最佳答案

您需要添加自定义 IOperationFilter 来处理此问题。

假设你有一个像这样的 Controller :

    [ValidateMimeMultipartContentFilter]
    [HttpPost, Route("softwarepackage")]
    public Task<SoftwarePackageModel> UploadSingleFile()
    {

        var streamProvider = new MultipartFormDataStreamProvider(ServerUploadFolder);
        var task = Request.Content.ReadAsMultipartAsync(streamProvider).ContinueWith<SoftwarePackageModel>(t =>
        {
            var firstFile = streamProvider.FileData.FirstOrDefault();

            if (firstFile != null)
            {
                // Do something with firstFile.LocalFileName
            }

            return new SoftwarePackageModel
            {

            };
        });

        return task;
    }

然后,您需要创建一个 Swashbuckle.Swagger.IOperationFilter 来将文件上传参数添加到您的函数中,例如:

    public class FileOperationFilter : IOperationFilter
    {
        public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
        {
            if (operation.operationId.ToLower() == "softwarepackage_uploadsinglefile")
            {
                if (operation.parameters == null)
                    operation.parameters = new List<Parameter>(1);
                else
                    operation.parameters.Clear();
                operation.parameters.Add(new Parameter
                {
                    name = "File",
                    @in = "formData",
                    description = "Upload software package",
                    required = true,
                    type = "file"
                });
                operation.consumes.Add("application/form-data");
            }
        }
    }

在您的 Swagger 配置中,您需要注册过滤器:

config.EnableSwagger(c => {... c.OperationFilter<FileOperationFilter>(); ... });

最重要的是,我还添加了一个 FilterAttribute 来过滤多部分内容:

public class ValidateMimeMultipartContentFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!actionContext.Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }
    }

    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {

    }

}

关于c# - 使用未在 swagger 中公开的 HTTP 内容上传 API 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42435635/

相关文章:

c# - try { return x; 中到底发生了什么? } 最后 { x = null; } 陈述?

c# - BFF 到带有 AAD/Entra ID B2C 的内部 API (.NET/ASP.NET Core/Identity.Web)

api - 是否有 Google 照片 API

javascript - Vuex - 调用异步函数

xml - 如何查找 Sabre Soap API 的特定端点?

node.js - Node : How to make swagger show route + endpoint on documentation

java - Swagger:如何在 swagger 文件中引用 Document 对象?

java - 使用 openapi4j 解析包含 jar 内引用的 Swagger

c# - FormClosing() 事件加载了两次

c# - 在 jQuery 中下载并打开文件