0

I'm trying to simply allow a user to upload a file.

I have a simple begin form that contains a file element as shown below:

 @using (Html.BeginForm("LoadData", "Input", FormMethod.Post, new { enctype = "multipart/form-data" }))
        { 
            <div style="width:23%; display:inline-block;">
                <label>Select Type:</label>
                <select name="UploadType">
                    <option value="First">First</option>
                    <option value="Second">Second</option>
                </select>
            </div>
            <div style="width:43%; display:inline-block;">
                <input type="file" name="files1" id="files1" />
            </div>
            <div style="width:33%; display:inline-block;">
                <input type="submit" value="Upload"/>
            </div>
        }

The controller is :

[HttpPost]
    public ActionResult LoadData(string UploadType, HttpPostedFileBase file1)
    {
        if(file1 != null && UploadType != null)
        {
            Console.WriteLine(file1.FileName);
            Console.WriteLine(UploadType);
        }
    }

Everything displays and works on the site but when it posts back the file is null. I've looked at many google results including:

Binding HttpPostedFileBase using Ajax.BeginForm

MVC 4 Razor File Upload

http://www.aurigma.com/upload-suite/developers/aspnet-mvc/how-to-upload-files-in-aspnet-mvc

and more. they all say my stuff is correct. As long as the names match on the file input and the controller param, it should work. But it's not.

I've tried naming it file, files, and now file1 but no mater what I call it, it comes back null.

What am I doing wrong? I even tried checking the Request.Files but that says it has a count of 0.

Community
  • 1
  • 1
Jeremy Styers
  • 497
  • 5
  • 23

3 Answers3

2

I ended up using javascript to handle the files instead. Here's the working code:

Javascript (it allows multiple files now):

 function SendData() {
        var formData = new FormData(document.querySelector('UploadForm'));
        for(var i = 0; i < $('#file')[0].files.length; i++)
        {
            formData.append('files', $('#file')[0].files[i]);
        }

        formData.append('samplevalue', $('#samplevalue').val());

        var url = $('#baseUrl').val() + 'Input/LoadData';
        $.ajax({
            url: url,
            type: 'POST',
            data: formData,
            processData: false,  // tell jQuery not to process the data
            contentType: false,  // tell jQuery not to set contentType
            success: function (data) {
             // your logic....
            },
            error: function(data)
            {
                // logic....
            }
        });
    }

The controller then accepts

public string LoadData(string samplevalue, HttpPostedFileBase[] files)
{
}

Of course the trick is the javascript. I still don't know why the form doesn't work normally but this works perfectly. :)

miken32
  • 42,008
  • 16
  • 111
  • 154
Jeremy Styers
  • 497
  • 5
  • 23
-1

Your file input is named files1, but your action param is file1 (no s).

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • Sorry. Updated and still won't work. As mentioned, no mater the name it never gets the file. – Jeremy Styers May 25 '16 at 17:56
  • 1
    There's really not much to this. Assuming your rendered `form` tag actually contains `enctype="multipart/form-data"` (verify in the document source), and the field name matches *exactly* a param name on your action, then you're golden. – Chris Pratt May 25 '16 at 18:07
  • Is what the page says in it's page source when rendered. – Jeremy Styers May 25 '16 at 18:14
  • 1
    Then as long as you have a param of type `HttpPostedFileBase` whose name *exactly* matches the file input's name attribute, it should work. If it's not, there's something else at play. What exactly, I have no idea, but it's not MVC-related, unless you've done something silly like employed a custom model-binder. – Chris Pratt May 25 '16 at 18:17
  • is the page and public ActionResult LoadData(string UploadType, HttpPostedFileBase file1) is the controller. Both names match and the form has exactly what everyone says to put. Still null returned. I checked the headers and there's a "Form Data" in the body but it doesn't contain the file, only the UploadType. – Jeremy Styers May 25 '16 at 18:18
  • You wouldn't happen to be trying to post via AJAX, would you? – Chris Pratt May 25 '16 at 18:57
  • No. But I am now. I found ajax is working as per this answer : http://stackoverflow.com/questions/2320069/jquery-ajax-file-upload/10811427#10811427 I found ajax is sending the file. So why won't the form without ajax? – Jeremy Styers May 25 '16 at 19:24
  • 1
    If anything AJAX should have more trouble sending the file than a regular form.. as AJAX needs a workaround – krilovich May 25 '16 at 20:06
  • 1
    Yep, and even then, it's only supported in modern browsers, so depending on what you're testing with, it may always be null. – Chris Pratt May 25 '16 at 20:07
-1
    @using (Html.BeginForm("MethodName", "ControllerName", FormMethod.Post, 
new { enctype = "multipart/form-data" }))
{
  @Html.AntiForgeryToken()
  <input type="file" name="ImgUploader" id="ImgUploader" />
  <input type="submit" value="Create" class="btn btn-default" />
}

**Your Controller**`[HttpPost]
public ActionResult Create()
{
 HttpPostedFileBase file = Request.Files["ImgUploader"];
}