使用未在招摇中公开的 HTTP 内容的 API 文件上传 [英] API File Upload using HTTP content not exposed in swagger

查看:13
本文介绍了使用未在招摇中公开的 HTTP 内容的 API 文件上传的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在现有的 Web API 中实现了一个 swagger 接口.当前的 API 控制器公开了一个异步上传功能,该功能使用 Request.Content 异步传输图像.已使用的代码在 这篇文章.

I am implementing a swagger interface into an existing web API. The current API controller exposes an async upload function which uses the Request.Content to transport an image asynchronously. The code that has been used is explained in this article.

我的 api 控制器:

My 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 公开它时,我有一个无参数函数,使用时会返回错误.

This works dandy, but when i expose this through swagger i have a parameterless function, which returns an error when used.

我的问题是如何提供一个合适的值来测试这个方法?

My question is how can supply a proper value to test this method with?

推荐答案

你需要添加一个自定义的 IOperationFilter 来处理这个问题.

You'll need to add a custom IOperationFilter to handle this.

假设您有这样的控制器:

Given you have a controller like so:

    [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 以向您的函数添加文件上传参数,例如:

You then need to create an Swashbuckle.Swagger.IOperationFilter to add a file upload parameter to your function like:

    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 配置中注册过滤器:

And in your Swagger config you'll need to register the filter:

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

为了补充这一点,我还添加了一个 FilterAttribute 来过滤掉 Multipart 内容:

To top this up, I also added a FilterAttribute to filter out Multipart content:

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)
    {

    }

}

这篇关于使用未在招摇中公开的 HTTP 内容的 API 文件上传的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆