2

I have this html form which I want to post data and files to C# Web Api. Here is my front-end code

document.getElementById("form1").addEventListener("submit", function (e) {
        e.preventDefault();
        var input = document.getElementById('files');

        var files = input.files;

        var formData = new FormData();

        for (var i = 0; i != files.length; i++) {
            formData.append("files", files[i]);
        }

        var tags = $('#tags').val();

        formData.append("tags", tags);
    
        $.ajax(
            {
                url: "https://localhost:44371/api/file/upload",
                processData: false,
                contentType: false,
                type: "POST",
                data: formData,
                dataType: 'json',
                success: function () {
                    alert("Files Uploaded!");
                }
            }
        );
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form1">
  <div class="form-group">
    <div class="buttons">
      <div class="upload-button">
        <input id="files" name="files" type="file" size="1" />
      </div>
    </div>
  </div>

  <div class="form-group">
    <label for="tags">Tags:</label>
    <input type="text" class="form-control" id="tags">
  </div>
  <div class="form-group">
    <button type="submit" class="btn btn-primary" id="btnSave">Upload and Save</button>
  </div>
</form>

And here is my back-end Web Api C# code:

[HttpPost]
    [Route("upload")]
    public async Task<ActionResult<FileDocument>> PostFileDocument(List<IFormFile> files, string tags)
    {
        return Ok("test");
        
    }

I can reach this method and I can see files has data. But tags is showing null. But I have appended tags at formData.append("tags", tags);. I googled and some said put [FromBody] List<IFormFile> files which I have tried but when I did, it became null.

1 Answer 1

2

I've read, but not tried myself, that it works by creating a class to be used as the parameter of PostFileDocument(). This class would have an array of IFormFile and a string property for the tags as in

class SomeController 
{
    [HttpPost]
    [Route("upload")]
    public async Task<ActionResult<FileDocument>> PostFileDocument([FromForm]Payload payload)
    {
        // some nice code here
    }
}

class Payload 
{
    // You probably have to align the naming of what you `append()`
    // to the `FormData` in JavaScript (e.g. `formData.append("Files", ...)`
    // instead of `formData.append("files", ...)`). 
    public IFormFile[] Files {get;set;}
    public string Tags {get;set;}
}

This is described here: https://thomaslevesque.com/2018/09/04/handling-multipart-requests-with-json-and-file-uploads-in-asp-net-core/

Sign up to request clarification or add additional context in comments.

1 Comment

Any collection type for files is fine - it doesn't have to be an array. The JS just needs to prefix each FormData key with payload. for it to bind (e.g. payload.files). Alternatively, just using [FromForm] string tags will also work.

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.