IFormFile is always null after doing post in javascript

707 views Asked by At

Here is an extract of a larger page that is to upload a file to a c# controller using pure javascript in a .Net Core 6 MVC App.

When it hits the controller, the myFile parameter is always null.

We've tried things like [FromBody] and [FromForm], but cannot seem to get the file into the controller.

Any and all help much appreciated.

Here's the html/js:

<h1>Upload File</h1>

<div>
    <input type="file" id="myFile" name="myFile">
   <button onclick="upload()">Upload</button>
</div>

<script>

    async function upload()
    {
        const fileInput = document.querySelector('#myFile');
        const formData = new FormData();

        formData.append('myFile', fileInput.files[0]);
  
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");

        let requestOptions = {
            method: 'POST',
            headers: myHeaders,
            redirect: 'follow',
            body: formData,           
        };

        const url = `${location.protocol}//${location.host}/Training/demoupload`;
        console.log(url)

        try {
            await fetch(url, requestOptions).then(response => response.json())
                .then(data => {
                    if (data.success == true) {
                        // do stuff
                        alert(data.message);
                    }
                    else {
                        // do other stuff
                        alert(data.message);
                    }

                })

        } catch (error) {
            alert(error)
        }

    }
</script>

And here is the simplified c# where the myFile parm is always null:

public class TrainingController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public JsonResult demoupload(IFormFile myfile)
        {
            BaseResponseModel response = new BaseResponseModel();
            if (myfile == null)
            {
                response.success = false;
                response.message = "no file passed in";
            }
            else
            {
                response.success = true;
                response.message = "file passed in";
            }
            return Json(response);
        }

    }

2

There are 2 answers

3
Qing Guo On

Try to remove "Content-Type", "application/json" from your headers: myHeaders, . Your Content-Type will change according to your upload file. Change the code like below:

let requestOptions = {
            method: 'POST',
           // headers: myHeaders,//try to remove it
            redirect: 'follow',
            body: formData,           
        };

result:

enter image description here

1
Rodney Ellis On

FINALLY got it working (with a couple of hours help of a colleague) ... posting working code here for anyone else:

JS:

<script>
    async function upload() {
        const fileInput = document.querySelector('#myFile');
        const formData = new FormData();

        formData.append('files', fileInput.files[0]);

        var myHeaders = new Headers();
        
        let requestOptions = {
            method: 'POST',
            headers: myHeaders,
            redirect: 'follow',
            body: formData,

        };

        const url = `${location.protocol}//${location.host}/Training/demoupload`;
        console.log(url)

        try {
            await fetch(url, requestOptions).then(response => response.json())
                .then(data => {
                    if (data.success == true) {
                        console.log(data.message);
                    }
                    else {
                        console.log(data.message);
                    }

                })

        } catch (error) {
            alert(error)
        }

    }
</script>

and par of the C#:

    [HttpPost]
    public async Task<IActionResult> demoupload(IList<IFormFile> files)
    {
        foreach (IFormFile source in files)
        {
            string filename = ContentDispositionHeaderValue.Parse(source.ContentDisposition).FileName.Trim('"');
            // do more from here .... 
        }



    }