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: 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); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- asp.net – 从Repeater中检索TextBox值
- ASP.NET Web窗体DropDownList具有SelectedValue,因为它不存
- asp.net-mvc – 如何使用ASP.NET MVC和表单身份验证创建单页
- asp.net中的Html.ActionLink MVC对象值格式错误
- asp.net – 如何修复“System.Security.Permissions.Securi
- ASP.NET / IIS:404适用于所有文件类型
- 重定向后ASP.NET会话丢失,但仅限于IE
- asp.net-mvc – 如何运行Internet Explorer Selenium测试作
- asp.net核心 – Kestrel托管基础
- Asp.net mvc 知多少(四)
推荐文章
站长推荐
- asp.net-mvc – ErrorAttribute vs OnException与
- 如何实现ASP.NET 2.0,Coldfusion 5和Classic ASP
- 压力测试ASP.Net应用程序
- asp.net – WCF vs ASPX webmethods vs ASMX web
- asp.net-mvc – Knockout.js&复选框列表:发
- asp.net-mvc-3 – 型号型号无法更新mvc
- asp.net-mvc – OwinMiddleware不保留.net 4.6中
- 如何在IIS / ASP.Net中创建长期存在的对象?
- ASP.NET与jQuery弹出对话框:如何回发对话框关闭
- 如何在ASP.NET MVC中具有相同名称的文件夹和控制
热点阅读