1

I have a document service API written in ASP.NET Core Web API 2.1. This API currently accepts a ViewModel containing information for 1 file and then saves that file and information to the server. I want to add the ability to add multiple files, but I cannot get the IFormFile file to bind when uploaded as part of a collection.

/// The ViewModel being uploaded.
public class FileUploadDto
{
    public Guid Id { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
    public IFormFile File { get; set; }
}

/// Works perfect. All properties are bound to the fileUploadRequest object.
[HttpPost]
public async Task<IActionResult> Add(FileUploadDto fileUploadRequest)
{
    /// Process

    return Ok();
}

/// All properties are bound to the objects in the collection, except for the File property.
[HttpPost]
public async Task<IActionResult> AddRange([FromForm] IEnumerable<FileUploadDto> fileUploadRequests)
{
    foreach (FileUploadDto fileUploadRequest in fileUploadRequests)
    {
        //fileUploadRequest.File is null
    }

    return Ok();
}

I am testing this by using Postman, and uploading the content in the body, using form-data, as:

[0][Description]:Test (Type: Text)
[0][Name]:Test (Type: Text)
[0][File]:sample.txt (Type: File)

multipart/form-data is set in the content-type header.

UPDATE:
I've found a workaround by doing the following, but obviously this is not the best thing to do. I recognize the problem is that the files are not being bound to my ViewModels, but are being stored in the Request.Form.Files collection. I'm not sure how to work around that, though.

[HttpPost]
public async Task<IActionResult> AddRange([FromForm] IEnumerable<FileUploadDto> fileUploadRequests)
{
    var index = 0;
    foreach (FileUploadDto fileUploadRequest in fileUploadRequests)
    {
        //fileUploadRequest.File is null
        fileUploadRequest.File = Request.Form.Files[index];
        index += 1;
    }

    return Ok();
}

1 Answer 1

1

I ended up passing an additional property to specify the file index to use in the Request Form.

/// The ViewModel being uploaded.
public class FileUploadDto
{
    public Guid Id { get; set; }
    public string Description { get; set; }
    public string Name { get; set; }
    public int? FileIndex { get; set; }
    public IFormFile File { get; set; }
}

/// Works perfect. All properties are bound to the fileUploadRequest object.
[HttpPost]
public async Task<IActionResult> Add(FileUploadDto fileUploadRequest)
{
    /// Process

    return Ok();
}

/// All properties are bound to the objects in the collection, except for the File property.
[HttpPost]
public async Task<IActionResult> AddRange([FromForm] IEnumerable<FileUploadDto> fileUploadRequests)
{
    foreach (FileUploadDto fileUploadRequest in fileUploadRequests)
    {
        fileUploadRequest.File = Request.Form.Files[fileUploadRequest.FileIndex ?? -1];
    }

    return Ok();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.