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中具有相同名称的文件夹和控制
热点阅读

