如何使用 Swagger 测试文件上传
How to test file Upload with Swagger
我有以下 API 将用户添加到数据库,用户必须有个人资料照片。
我需要能够测试这个 VIA swagger,但不确定如何在 swagger 中执行文件上传部分(如果这有意义的话)
[HttpPost]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
var telemetry = new TelemetryClient();
try
{
var userStore = CosmosStoreHolder.Instance.CosmosStoreUser;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Then we validate the content type
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
if (string.IsNullOrEmpty(user.CustomerId) && string.IsNullOrEmpty(user.PartnerId))
{
return BadRequest("ClientID or PartnerId must be filled in.");
}
var added = await userStore.AddAsync(user);
added.Entity.ProfilePictureUrl = await BlobStorageHelper.Instance.UploadUserProfileImage(Request, added.Entity.Id);
var updated = await userStore.UpdateAsync(user);
return Ok(added);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
用户
public class User : ISharedCosmosEntity
{
[JsonProperty("Id")]
public string Id { get; set; }
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Enabled { get; set; }
public string ProfilePictureUrl { get; set; }
public string Base64Image { get; set; }
public string RoleName { get; set; }
public string CustomerName { get; set; }
public string PartnerName { get; set; }
public string CustomerId{ get; set; }
public string PartnerId { get; set; }
public string RoleId { get; set; }
[CosmosPartitionKey]
public string CosmosEntityName { get; set; }
}
BlobStorageHelper
public async Task<string> UploadUserProfileImage(HttpRequestMessage request, string userid)
{
//Initalize configuration settings
var storageAccount = new CloudStorageAccount(new StorageCredentials(AccountName, Key), true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer imagesContainer = blobClient.GetContainerReference(ProfilePicsContainer);
var provider = new AzureStorageMultipartFormDataStreamProvider(imagesContainer);
// Validate extension and image size
foreach (MultipartFileData file in provider.FileData)
{
var fileName = file.Headers.ContentDisposition.FileName.Trim('\"').Trim();
if (fileName.EndsWith(".png"))
{
var img = Image.FromFile(file.LocalFileName);
if (img.Width != 200 && img.Height != 200)
{
string guid = Guid.NewGuid().ToString();
throw new ArgumentException($"Error Lulo. Unsupported extension, only PNG is valid. Or unsuported image dimensions (200px x 200px)");
}
}
}
await request.Content.ReadAsMultipartAsync(provider);
// Retrieve the filename of the file you have uploaded
var filename = provider.FileData.FirstOrDefault()?.LocalFileName;
//Rename file
CloudBlockBlob blobCopy = imagesContainer.GetBlockBlobReference(userid + ".png");
if (!await blobCopy.ExistsAsync())
{
CloudBlockBlob blob = imagesContainer.GetBlockBlobReference(filename);
if (await blob.ExistsAsync())
{
await blobCopy.StartCopyAsync(blob);
await blob.DeleteIfExistsAsync();
}
}
return blobCopy.Name;
}
我试过post只有相关部分
我知道这不是 swagger,但您可以改用 Postman。
在使用 Postman 时。
您可以模拟对应用程序的 http 调用并将表单数据传递给它。
您可以选择数据类型,如果您选择表单数据,您可以选择文本或文件。
文件让您上传文件并将其传递给您的 api。所以也许您会找到测试它所需的一切。
- 创建自定义属性以接受文件:
[AttributeUsage(AttributeTargets.Method)]
public sealed class SwaggerParameterAttribute : Attribute
{
public SwaggerParameterAttribute(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; private set; }
public string Description { get; private set; }
public string Type { get; set; } = "text";
public bool Required { get; set; } = false;
}
- 添加过滤器来处理新属性:
public class SwaggerParameterOperationFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerParameterAttribute>();
if (requestAttributes.Any())
{
operation.parameters = operation.parameters ?? new List<Parameter>();
foreach (var attr in requestAttributes)
{
operation.parameters.Add(new Parameter
{
name = attr.Name,
description = attr.Description,
@in = attr.Type == "file" ? "formData" : "body",
required = attr.Required,
type = attr.Type
});
}
if (requestAttributes.Any(x => x.Type == "file"))
{
operation.consumes.Add("multipart/form-data");
}
}
}
}
- 更新您的 Swagger 配置以使用过滤器:
config.EnableSwagger(c =>
{
c.OperationFilter<SwaggerParameterOperationFilter>();
// ....
}
- 将属性添加到您的控制器端点:
[HttpPost]
[SwaggerParameter("profilePicture", "A file", Required = true, Type = "file")]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
//...
}
改编自以下 blogpost。
我有以下 API 将用户添加到数据库,用户必须有个人资料照片。
我需要能够测试这个 VIA swagger,但不确定如何在 swagger 中执行文件上传部分(如果这有意义的话)
[HttpPost]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
var telemetry = new TelemetryClient();
try
{
var userStore = CosmosStoreHolder.Instance.CosmosStoreUser;
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
//Then we validate the content type
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
if (string.IsNullOrEmpty(user.CustomerId) && string.IsNullOrEmpty(user.PartnerId))
{
return BadRequest("ClientID or PartnerId must be filled in.");
}
var added = await userStore.AddAsync(user);
added.Entity.ProfilePictureUrl = await BlobStorageHelper.Instance.UploadUserProfileImage(Request, added.Entity.Id);
var updated = await userStore.UpdateAsync(user);
return Ok(added);
}
catch (Exception ex)
{
string guid = Guid.NewGuid().ToString();
var dt = new Dictionary<string, string>
{
{ "Error Lulo: ", guid }
};
telemetry.TrackException(ex, dt);
return BadRequest("Error Lulo: " + guid);
}
}
用户
public class User : ISharedCosmosEntity
{
[JsonProperty("Id")]
public string Id { get; set; }
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool Enabled { get; set; }
public string ProfilePictureUrl { get; set; }
public string Base64Image { get; set; }
public string RoleName { get; set; }
public string CustomerName { get; set; }
public string PartnerName { get; set; }
public string CustomerId{ get; set; }
public string PartnerId { get; set; }
public string RoleId { get; set; }
[CosmosPartitionKey]
public string CosmosEntityName { get; set; }
}
BlobStorageHelper
public async Task<string> UploadUserProfileImage(HttpRequestMessage request, string userid)
{
//Initalize configuration settings
var storageAccount = new CloudStorageAccount(new StorageCredentials(AccountName, Key), true);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer imagesContainer = blobClient.GetContainerReference(ProfilePicsContainer);
var provider = new AzureStorageMultipartFormDataStreamProvider(imagesContainer);
// Validate extension and image size
foreach (MultipartFileData file in provider.FileData)
{
var fileName = file.Headers.ContentDisposition.FileName.Trim('\"').Trim();
if (fileName.EndsWith(".png"))
{
var img = Image.FromFile(file.LocalFileName);
if (img.Width != 200 && img.Height != 200)
{
string guid = Guid.NewGuid().ToString();
throw new ArgumentException($"Error Lulo. Unsupported extension, only PNG is valid. Or unsuported image dimensions (200px x 200px)");
}
}
}
await request.Content.ReadAsMultipartAsync(provider);
// Retrieve the filename of the file you have uploaded
var filename = provider.FileData.FirstOrDefault()?.LocalFileName;
//Rename file
CloudBlockBlob blobCopy = imagesContainer.GetBlockBlobReference(userid + ".png");
if (!await blobCopy.ExistsAsync())
{
CloudBlockBlob blob = imagesContainer.GetBlockBlobReference(filename);
if (await blob.ExistsAsync())
{
await blobCopy.StartCopyAsync(blob);
await blob.DeleteIfExistsAsync();
}
}
return blobCopy.Name;
}
我试过post只有相关部分
我知道这不是 swagger,但您可以改用 Postman。 在使用 Postman 时。 您可以模拟对应用程序的 http 调用并将表单数据传递给它。
您可以选择数据类型,如果您选择表单数据,您可以选择文本或文件。
文件让您上传文件并将其传递给您的 api。所以也许您会找到测试它所需的一切。
- 创建自定义属性以接受文件:
[AttributeUsage(AttributeTargets.Method)]
public sealed class SwaggerParameterAttribute : Attribute
{
public SwaggerParameterAttribute(string name, string description)
{
Name = name;
Description = description;
}
public string Name { get; private set; }
public string Description { get; private set; }
public string Type { get; set; } = "text";
public bool Required { get; set; } = false;
}
- 添加过滤器来处理新属性:
public class SwaggerParameterOperationFilter : IOperationFilter
{
public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
{
var requestAttributes = apiDescription.GetControllerAndActionAttributes<SwaggerParameterAttribute>();
if (requestAttributes.Any())
{
operation.parameters = operation.parameters ?? new List<Parameter>();
foreach (var attr in requestAttributes)
{
operation.parameters.Add(new Parameter
{
name = attr.Name,
description = attr.Description,
@in = attr.Type == "file" ? "formData" : "body",
required = attr.Required,
type = attr.Type
});
}
if (requestAttributes.Any(x => x.Type == "file"))
{
operation.consumes.Add("multipart/form-data");
}
}
}
}
- 更新您的 Swagger 配置以使用过滤器:
config.EnableSwagger(c =>
{
c.OperationFilter<SwaggerParameterOperationFilter>();
// ....
}
- 将属性添加到您的控制器端点:
[HttpPost]
[SwaggerParameter("profilePicture", "A file", Required = true, Type = "file")]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
//...
}
改编自以下 blogpost。