1

What is wrong in here?
The ajax call is not reaching the action

Server side:

    [HttpPost]
    public ActionResult UploadFile(long someID, HttpPostedFileBase myFile)
    {
        return "hello";
    }

Client side html:

<form id="my-form" method="post" action="" enctype="multipart/form-data">
     <input type="hidden" name="someID" value="156" />
     <input type="file" name="myFile" />
</form>

Client side javascript:

$.ajax({
    async: true,
    type: 'POST',
    url: '/MyController/UploadFile/',
    data: new FormData($('#my-form')),
    success: function (data) {},
    cache: false,
    contentType: false,
    processData: false
});

This kind of upload via ajax should be possible in some browsers.

I'm getting this serverside error: The parameters dictionary contains a null entry for parameter 'someID' of non-nullable type 'System.Int64' (...)

If I change the action to UploadFile(), with no parameters, the ajax call enters the action, but then how do I recover the posted data?

sports
  • 7,851
  • 14
  • 72
  • 129

2 Answers2

4

Well, ended up doing this:

Server side:

[HttpPost]
public ActionResult UploadFile(long someID)
{
    var file = Request.Files[0];
    return "hello";
}

Client side html:

 <form method="post" action="">
     <input type="hidden" id="someID" value="156" />
     <input type="file" id="myFile" />
 </form>

Client side javascript:

var blah = new FormData();
blah.append("file", $("#myFile")[0].files[0]);

$.ajax({
    async: true,
    type: 'POST',
    url: '/MyController/UploadFile/?someID='+ $("#someID").val(),
    data: blah,
    success: function (data) {},
    cache: false,
    contentType: false,
    processData: false
});

As you can see, the html form isn't even necesary, neither the enctype. The someID thing is passed by the URL and the file is catched in Request.Files

sports
  • 7,851
  • 14
  • 72
  • 129
  • 1
    Works well. If one has more input fields in the form which should be included in the post one could use `new FormData($('#someFormId')[0])`. That constructs the FormData from the actual form that should be posted. Then you can modify that form data according to the description in this post. – Erik Öjebo Feb 08 '14 at 20:51
3

In cases where you want to upload a file along with some other parameters, which is the case in your scenario, the HttpPost handler can have only the other parameters. You can then get the file sent to the server from the Request object.

For example:

[HttpPost]
public ActionResult UploadFile(long someID)
{
    string filename = null;
    string fileType = null;
    byte[] fileContents = null;

    if (Request.Files.Count > 0) { //they're uploading the old way
        var file = Request.Files[0];
        fileContents = new byte[file.ContentLength];
        fileType = file.ContentType;
        filename = file.FileName;
    } else if (Request.ContentLength > 0) {
        fileContents = new byte[Request.ContentLength];
        Request.InputStream.Read(fileContents, 0, Request.ContentLength);
        filename = Request.Headers["X-File-Name"];
        fileType = Request.Headers["X-File-Type"];
    }
    //Now you have the file, continue with processing the POST request 
    //...
}

This sample is from this link, which I found really helpful in my first steps in MVC.

Tasos K.
  • 7,979
  • 7
  • 39
  • 63