How to upload file from AJAX to asp.net core controller

I can't give a file to my action. Action get null. I use ASP.NET Core.

HTML

<form enctype="multipart/form-data" method="POST" id="QuestionImgUpload" action="/api/TestQuestions/PostQuestionIMG">
    <input id="QuestionImg" type="file" name="file">
</form>

JS:

var formData = new FormData();
var file = document.getElementById("QuestionImg").files[0];
formData.append("QuestionImg", file);
$.ajax({
  url: "/api/TestQuestions/PostQuestionIMG",
  type: "POST",
  data: formData,
  contentType: false,
  processData: false,
  success: function() {
  }
});

Action:

 [Route("PostQuestionIMG")]
 [HttpPost]
 public IActionResult PostQuestionIMG(IFormFile file)
 {    
     return Ok();
 }

Upvotes: 3

Views: 7593

Answers (5)

Ramil Aliyev 007
Ramil Aliyev 007

Reputation: 5460

This is similar to my problem.

Problem is formData's name is not corresponding ASP.NET action's parameter's name.

FormData's append function's first parametr is name. In your JavaScript code it is 'QuestionImg'.

Your ASP.NET code:

 [Route("PostQuestionIMG")]
 [HttpPost]
 public IActionResult PostQuestionIMG(IFormFile file)
 {    
     return Ok();
 }

If your ASP.NET action's parameter name is 'file', you must set formData's field name to 'file'.

I refactored your JavaScript code as following below:

var formData = new FormData();
var file = document.getElementById("QuestionImg").files[0];
formData.append("file", file);
$.ajax({
  url: "/api/TestQuestions/PostQuestionIMG",
  type: "POST",
  data: formData,
  contentType: false,
  processData: false,
  success: function() {
  }
});

Upvotes: 3

Patrick Knott
Patrick Knott

Reputation: 1837

This is similar to my problem, in that the ICollection was not registering my javascript call, but the Request with the files still arrives in my controller.

In the controller, try:

    [HttpPost]
    [Route("ImportDataFromExcelFile")]
    public async Task<IActionResult> ImportDataFromExcelFile(ICollection<IFormFile> files)
    {
        var myfiles = HttpContext.Request.Form.Files; //THIS IS THE ACTUAL FILE LIST!
        long size = files.Sum(f => f.Length); //this is 0... the ICollection 
               //doesn't register the files that are in the request.

        return Ok(new { stuff = 1, size});
    }

I imagine that your request is probably working the same way. Just to be clear, my call was this:

    const formData = new FormData(); 
    for (var i = 0; i < files.length; i++) {
        var file = files.item(i);
        formData.append(file.name, file);
    }
    var xhr = new XMLHttpRequest;
    xhr.open('POST', data.endpoint, true);
    xhr.onload = function() {
        if (xhr.status === 200) {
            //file uploaded
            console.log("success");
        } else {
            console.log("error");
        }
    }

Again, I realize this is not the way you did your ajax call, but my point is that the data may still be in the Request, just not being assigned. Perhaps this helps until you, I, or someone else figures out a great answer.

Good Luck!

Upvotes: 1

Daniel Beckmann
Daniel Beckmann

Reputation: 286

First ensure your route is setup correctly. I assume your Controller is annotated with: [Route("api/TestQuestions")]

You then can access the posted file like this:

[Route("PostQuestionIMG")]
[HttpPost]
public IActionResult PostQuestionIMG()
{
    var file = HttpContext.Request.Form.Files[0];
    return Ok();
}

Upvotes: 3

Brian Mains
Brian Mains

Reputation: 50728

There is a way using the HTML FileReader object outlined on this post.

$("#FileUpload").on('change', function (e) {
var $self = this;
var file = $self.files[0];

var fileReader = new FileReader();
fileReader.addEventListener('load', function () {
   var result = fileReader.result;
   $hidden.val(result);
});
fileReader.readAsDataURL(file);

$self.val('');
});

Basically read the file, grab the data, then you can AJAX that up to the server as an alternative. My example stores it in a hidden field, instead of AJAXing it up, but it's simple to replace that function.

Upvotes: 0

flyingfox
flyingfox

Reputation: 13506

It's difficult to upload file via ajax directly,however you can use iframe to achieve your goal.

Change your code as below:

<form enctype="multipart/form-data" method="POST" id="QuestionImgUpload" action="/api/TestQuestions/PostQuestionIMG" target="upload_post">
    <input id="QuestionImg" type="file" name="file">
</form>
<iframe id="upload_target" name="upload_target" src="#" style="width:0;height:0;border:0px solid #fff;"></iframe> 

With the help of iframe we can submit our form like this:

$("#QuestionImgUpload").submit();

More details can be found at AJAX file upload tutorial or jQuery Ajax File Upload

Upvotes: 0

Related Questions