如何使用 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。所以也许您会找到测试它所需的一切。

  1. 创建自定义属性以接受文件:
[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;
}
  1. 添加过滤器来处理新属性:
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");
            }
        }
    }
}
  1. 更新您的 Swagger 配置以使用过滤器:
config.EnableSwagger(c =>
{
    c.OperationFilter<SwaggerParameterOperationFilter>();
    // ....
}
  1. 将属性添加到您的控制器端点:
[HttpPost]
[SwaggerParameter("profilePicture", "A file", Required = true, Type = "file")]
public async Task<IHttpActionResult> Adduser([FromBody]User user)
{
//...
}

改编自以下 blogpost