Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Upload multiple files in one form MVC4

I'm trying to upload multiple images on one form

@using (Html.BeginForm("Create", "AdminRestaurants", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
    <label for="logoFile" class="col-sm-2 control-label">Logo:</label>
    <div class="col-sm-6">
        <input type="file" multiple="" name="logoFile" id="logoFile" />
    </div>
</div>
<div class="form-group">
    <label for="fohFile" class="col-sm-2 control-label">FOH Logo:</label>
    <div class="col-sm-6">
        <input type="file" multiple="" name="fohFile" id="fohFile" />
    </div>
</div>
<div class="form-group">
    <label for="bohFile" class="col-sm-2 control-label">BOH Logo:</label>
    <div class="col-sm-6">
        <input type="file" multiple="" name="bohFile" id="bohFile" />
    </div>
</div>
<div class="form-group">
    <label for="mgmFile" class="col-sm-2 control-label">MGM Logo:</label>
    <div class="col-sm-6">
        <input type="file" multiple="" name="mgmFile" id="mgmFile" />
    </div>
</div>

I'm trying to process the form on the controller with this

public ActionResult Create(IEnumerable<HttpPostedFileBase> files, RestaurantModel collection)
{
    if (ViewData.ModelState.IsValid)
    {
    }
}

Currently nothing shows up in the files signature on the controller. This seems to work great when only working with one file

public ActionResult Create(HttpPostedFileBase file, EventsModel collection)

Can someone point me in the direction to allow multiple files to be uploaded with one submission form?

like image 987
Jon Harding Avatar asked Nov 26 '13 03:11

Jon Harding


2 Answers

Your problem is that you form creates a post request with information that the model binder can bind because the naming convention is not right.

you see, you have 4 file fields each with a different name, for the model binder to bind them correctly your controller action signature should look like this:

public ActionResult Create(HttpPostedFileBase mgmFile, 
                           HttpPostedFileBase logoFile, 
                           HttpPostedFileBase fohFile ,
                           HttpPostedFileBase bohFile)

Following MCV design pattern The best option would be to use a ViewModel that holds an IEnumerable<HttpPostedFileBase> and you would create a custom editor template for an IEnumerable<HttpPostedFileBase>

so that you could use it like that:

Html.EditorFor(m=>Model.filesUploaded)

and your controller action would look like this:

public ActionResult Create(MyViewModel i_InputModel)
{
    i_InputModel.filesUploade; //Use the files here to upload them.
}

Other options are: Use the HTML5 multiple attribute on the file input field like this:

<label for="mgmFile" class="col-sm-2 control-label">Files:</label>
<div class="col-sm-6">
    <input type="file" multiple="multiple" name="files" id="files" />
</div>

and a controller action like this:

public ActionResult Create(HttpPostedFileBase files)

or use multiple file fields but index them in their name:

<input type="file" multiple="multiple" name="files[0]" id="files_1" />
<input type="file" multiple="multiple" name="files[1]" id="files_2" />
<input type="file" multiple="multiple" name="files[2]" id="files_3" />
<input type="file" multiple="multiple" name="files[3]" id="files_4" />

and then you could use a controller action like this:

public ActionResult Create(IEnumerable<HttpPostedFileBase> files)
like image 61
Mortalus Avatar answered Oct 14 '22 15:10

Mortalus


This would only work if your file inputs had indexed names like files[0], files[1], files[2],...

In order to understand how model binding to a list works in asp.net mvc, I recommend that you read this post: Model Binding to a List

You don't even have to use model binding to get the files. Use Request.Files in your Action to get them.

public ActionResult Create(EventsModel collection)
{
    var files = Request.Files;
    // rest of the code...
}
like image 36
ataravati Avatar answered Oct 14 '22 16:10

ataravati