简体   繁体   中英

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();
 }

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();
}

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() {
  }
});

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!

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM