加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-web-api2 – Swashbuckle 5和multipart / form-data Hel

发布时间:2020-12-16 03:24:32 所属栏目:asp.Net 来源:网络整理
导读:我试图让Swashbuckle 5为使用multipart / form-data参数的Post请求的ApiController生成完整的帮助页面.该操作的帮助页面出现在浏览器中,但没有包含有关表单中传递的参数的信息.我已经创建了一个操作过滤器并在SwaggerConfig中启用它,该页面包含URI参数,返回
我试图让Swashbuckle 5为使用multipart / form-data参数的Post请求的ApiController生成完整的帮助页面.该操作的帮助页面出现在浏览器中,但没有包含有关表单中传递的参数的信息.我已经创建了一个操作过滤器并在SwaggerConfig中启用它,该页面包含URI参数,返回类型以及从浏览器帮助页面中显示的 XML注释派生的其他信息;但是,操作过滤器中没有指定任何参数,并且帮助页面不包含有关参数的信息.

我肯定错过了什么.我有什么可能错过的建议吗?

操作过滤代码:

public class AddFormDataUploadParamTypes : IOperationFilter
{
    public void Apply(Operation operation,SchemaRegistry schemaRegistry,ApiDescription apiDescription)         { 
         if (operation.operationId == "Documents_Upload") 
         { 
            operation.consumes.Add("multipart/form-data");
            operation.parameters = new[]
            {
                new Parameter
                 {
                     name = "anotherid",@in  = "formData",description = "Optional identifier associated with the document.",required = false,type = "string",format = "uuid"

                 },new Parameter
                 {
                     name = "documentid",description = "The document identifier of the slot reserved for the document.",format = "uuid"
                 },new Parameter
                 {
                     name = "documenttype",description = "Specifies the kind of document being uploaded. This is not a file name extension.",required = true,type = "string"
                 },new Parameter
                 {
                     name = "emailfrom",description = "A optional email origination address used in association with the document if it is emailed to a receiver.",new Parameter
                 {
                     name = "emailsubject",description = "An optional email subject line used in association with the document if it is emailed to a receiver.",new Parameter 
                 { 
                     name = "file",@in = "formData",description = "File to upload.",type = "file" 
                 }
             }; 
         } 
     } 
}

解决方法

我猜你弄明白你的问题是什么.我能够使用你发布的代码制作一个完美的’swagger ui’界面,其中包含文件[BROWSE …]输入控件.

我只稍微修改了你的代码,所以它在检测到我的首选ValidateMimeMultipartContentFilter属性stolen from Damien Bond时应用.因此,我的类的略微修改版本如下所示:

public class AddFormDataUploadParamTypes<T> : IOperationFilter
{
    public void Apply(Operation operation,ApiDescription apiDescription)
    {
        var actFilters = apiDescription.ActionDescriptor.GetFilterPipeline();
        var supportsDesiredFilter = actFilters.Select(f => f.Instance).OfType<T>().Any();

        if (supportsDesiredFilter)
        {
            operation.consumes.Add("multipart/form-data");
            operation.parameters = new[]
            {
             //other parameters omitted for brevity
             new Parameter
             {
                 name = "file",type = "file"
             }
         };
        }
    }
}

这是我的Swagger UI:

enter image description here

FWIW:

我的NuGets

<package id="Swashbuckle" version="5.5.3" targetFramework="net461" />
<package id="Swashbuckle.Core" version="5.5.3" targetFramework="net461" />

Swagger配置示例

public class SwaggerConfig
{
    public static void Register()
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        GlobalConfiguration.Configuration 
            .EnableSwagger(c =>
                {

                    c.Schemes(new[] { "https" });

                    // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to
                    // hold additional metadata for an API. Version and title are required but you can also provide
                    // additional fields by chaining methods off SingleApiVersion.
                    //
                    c.SingleApiVersion("v1","MyCorp.WebApi.Tsl");


                    c.OperationFilter<MyCorp.Swashbuckle.AddFormDataUploadParamTypes<MyCorp.Attr.ValidateMimeMultipartContentFilter>>();

                })
            .EnableSwaggerUi(c =>
                {

                    // If your API supports ApiKey,you can override the default values.
                    // "apiKeyIn" can either be "query" or "header"                                                
                    //
                    //c.EnableApiKeySupport("apiKey","header");
                });
    }


}

更新2019年3月

我没有快速访问上面的原始项目,但是,这是来自不同项目的示例API控制器…

控制器签名:

[ValidateMimeMultipartContentFilter]
    [SwaggerResponse(HttpStatusCode.OK,Description = "Returns JSON object filled with descriptive data about the image.")]
    [SwaggerResponse(HttpStatusCode.NotFound,Description = "No appropriate equipment record found for this endpoint")]
    [SwaggerResponse(HttpStatusCode.BadRequest,Description = "This request was fulfilled previously")]
    public async Task<IHttpActionResult> PostSignatureImage(Guid key)

您会注意到签名中没有实际参数代表我的文件,您可以在下面看到我只是启动一个MultipartFormDataStreamProvider来取出传入的POST表单数据.

控制器主体:

var signatureImage = await db.SignatureImages.Where(img => img.Id == key).FirstOrDefaultAsync();
        if (signatureImage == null)
        {
            return NotFound();
        }

        if (!signatureImage.IsOpenForCapture)
        {
            ModelState.AddModelError("CaptureDateTime",$"This equipment has already been signed once on {signatureImage.CaptureDateTime}");
        }

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        string fileName = String.Empty;
        string ServerUploadFolder = System.Web.Hosting.HostingEnvironment.MapPath("~/App_Data/");

        DirectoryInfo di = new DirectoryInfo(ServerUploadFolder + key.ToString());

        if (di.Exists == true)
            ModelState.AddModelError("id","It appears an upload for this item is either in progress or has already occurred.");
        else
            di.Create();

        var fullPathToFinalFile = String.Empty;
        var streamProvider = new MultipartFormDataStreamProvider(di.FullName);
        await Request.Content.ReadAsMultipartAsync(streamProvider);


        foreach (MultipartFileData fileData in streamProvider.FileData)
        {
            if (string.IsNullOrEmpty(fileData.Headers.ContentDisposition.FileName))
            {
                return StatusCode(HttpStatusCode.NotAcceptable);
            }
            fileName = cleanFileName(fileData.Headers.ContentDisposition.FileName);

            fullPathToFinalFile = Path.Combine(di.FullName,fileName);

            File.Move(fileData.LocalFileName,fullPathToFinalFile);

            signatureImage.Image = File.ReadAllBytes(fullPathToFinalFile);

            break;
        }

        signatureImage.FileName = streamProvider.FileData.Select(entry => cleanFileName(entry.Headers.ContentDisposition.FileName)).First();
        signatureImage.FileLength = signatureImage.Image.LongLength;
        signatureImage.IsOpenForCapture = false;
        signatureImage.CaptureDateTime = DateTimeOffset.Now;
        signatureImage.MimeType = streamProvider.FileData.Select(entry => entry.Headers.ContentType.MediaType).First();

        db.Entry(signatureImage).State = EntityState.Modified;

        try
        {
            await db.SaveChangesAsync();

            //cleanup...
            File.Delete(fullPathToFinalFile);
            di.Delete();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!SignatureImageExists(key))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        char[] placeHolderImg = paperClipIcon_svg.ToCharArray();
        signatureImage.Image = Convert.FromBase64CharArray(placeHolderImg,placeHolderImg.Length);

        return Ok(signatureImage);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读