0

I am new to MVC, and I have an issue that I can't seem to resolve. I have seen several articles on similar issues, but nothing that I can make fit the bill for what I need to achieve.

I have an MVC4 project, and I need to have multiple multi-file inputs on a page, and I need to be able to distinguish between which files were submitted via which input.

I have seen this SO article that suggested having multiple Post action args, but my code seems to handle them all as a single list.

Here is my controller code :

public ActionResult ProjectDocuments(C4Tbl_UploadedFiles c4tbl_uploadedfiles, IEnumerable<HttpPostedFileBase> File1, IEnumerable<HttpPostedFileBase> File2)
    {
        try
        {
            foreach (var file in File1)
            {
                if (file.ContentLength > 0)
                {
                   //Handle the first file list
                }
            }
            foreach (var file in File2)
            {
                if (file.ContentLength > 0)
                {
                    //Handle the second file list
                }
            }

Here is my View code :

    <table border="0" id="cssTable" class="nobg">
    <tr>
        <th style="width: 100px; min-width: 100px; max-width: 100px">
            <b>Type</b>
        </th>
        <th style="width: 400px; min-width: 400px; max-width: 400px">
            <b>File to Upload</b>
        </th>
        <th style="width: 500px; min-width: 500px; max-width: 500px">
            <b>Status</b>
        </th>
    </tr>
    <tr>
        <td style="width: 100px; min-width: 100px; max-width: 100px">
            <b>Blueprint(s)</b>
        </td>
        <td style="width: 400px; min-width: 400px; max-width: 400px">
            <input type="file" name="File1" id="BP" multiple style="width: 380px"/>
        </td>
        <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
            @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname="group1" }) Uploaded    
            @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname="group1" }) Not Uploaded    
            @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname="group1" }) Not Applicable
        </td>
    </tr>
    <tr>
        <td style="width: 100px; min-width: 100px; max-width: 100px">
            <b>Recovery Guide(s)</b>
        </td>
        <td style="width: 400px; min-width: 400px; max-width: 400px">
            <input type="file" name="File2" id="RG" multiple style="width: 380px"/>
        </td>
        <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
            @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname="group2" }) Uploaded    
            @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname="group2" }) Not Uploaded    
            @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname="group2" }) Not Applicable
        </td>
        <td>
            <input type="submit" value="Submit" name="submit" />
        </td>
    </tr>
</table>

I need to be able to accept any or all of the Inputs having files provided, and I need to know which of my inputs the files were submitted via, so I know which type of file they are so I can create the relevant DB entries in my tables.

Can anyone see a simple solution for this and point me in the right direction?

Community
  • 1
  • 1
Nevski
  • 1
  • 3
  • 1
    The names of your controls are `File1` and `File2` so your parameters need to be `IEnumerable File1, IEnumerable File` (side note - you 2nd set of radio buttons will be ignored because you have given them the same name as the first set) –  May 09 '16 at 12:12
  • Thanks Stephen, I had changed bits of the code for the post which didn't read well. I have edited this to read correctly now. – Nevski May 09 '16 at 12:50
  • The signature of the method in your edit is now correct and you can loop through the files in `File1` and `File2` - `foreach (var file in File1) { ...` –  May 09 '16 at 13:01

3 Answers3

0

Files are uploaded to the server in the Request.Files collection, each one of which is mapped to an HttpPostedFileBase object by the default MVC model binder. Therefore, the controller action that is tasked to process the uploaded files needs a parameter that represents a collection of HttpPostedFileBase objects.

public ActionResult ProjectDocuments()
{ 
   HttpPostedFileBase upPic = Request.Files["File1"];
   if (upPic != null && upPic.ContentLength != 0 && upPic.InputStream != null)
   {
      //Handle the first file list
   }
   upPic = Request.Files["File2"];
   if (upPic != null && upPic.ContentLength != 0 && upPic.InputStream != null)
   {
     //Handle the first file list
   }
   return View();
}

For Multiple File Uploaded.

public ActionResult ProjectDocuments(IEnumerable<HttpPostedFileBase> files)
{
  foreach (HttpPostedFileBase file in files)
  {
     if (file != null && file .ContentLength != 0 && file .InputStream != null)
     {
     //Handle the first file list
     } 
  }
  return View();
}
Fanjo Lama
  • 581
  • 3
  • 15
  • 1
    Thanks for the reply. I thought of using this, but as each input is for multiple files, I didn't think this was a suitable solution? – Nevski May 09 '16 at 12:55
  • "Try this" is not an answer. Please [edit] your answer to explain the principles used in it, and how your changes help the OP. – CodeCaster May 09 '16 at 13:38
0

Thanks for the answers. I have marked this as answered as current edit to the post works although I am sure there are more efficient ways to do this.

This is the working Controller Code :

public ActionResult ProjectDocuments(C4Tbl_UploadedFiles c4tbl_uploadedfiles, IEnumerable<HttpPostedFileBase> File1, IEnumerable<HttpPostedFileBase> File2)
{
    try
    {
        foreach (var file in File1)
        {
            if (file.ContentLength > 0)
            {
               //Handle the first file list
            }
        }
        foreach (var file in File2)
        {
            if (file.ContentLength > 0)
            {
                //Handle the second file list
            }
        }

This is the working View Code :

<table border="0" id="cssTable" class="nobg">
<tr>
    <th style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Type</b>
    </th>
    <th style="width: 400px; min-width: 400px; max-width: 400px">
        <b>File to Upload</b>
    </th>
    <th style="width: 500px; min-width: 500px; max-width: 500px">
        <b>Status</b>
    </th>
</tr>
<tr>
    <td style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Blueprint(s)</b>
    </td>
    <td style="width: 400px; min-width: 400px; max-width: 400px">
        <input type="file" name="File1" id="BP" multiple style="width: 380px"/>
    </td>
    <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
        @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname="group1" }) Uploaded    
        @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname="group1" }) Not Uploaded    
        @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname="group1" }) Not Applicable
    </td>
</tr>
<tr>
    <td style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Recovery Guide(s)</b>
    </td>
    <td style="width: 400px; min-width: 400px; max-width: 400px">
        <input type="file" name="File2" id="RG" multiple style="width: 380px"/>
    </td>
    <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
        @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname="group2" }) Uploaded    
        @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname="group2" }) Not Uploaded    
        @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname="group2" }) Not Applicable
    </td>
    <td>
        <input type="submit" value="Submit" name="submit" />
    </td>
</tr>

Thanks for all the help and suggestions

Nevski
  • 1
  • 3
  • Haven't you just used the code from someone elses answer and answered it yourself? IF the other guy took the time to answer you, at least give him the respect to mark his answer as correct. – webnoob May 09 '16 at 14:06
  • I actually used the code from my edited post with an input from @StephenMuecke. The code has hardly changed and there was just 1 error in the args from the original question. I have never used other peoples answers and marked as an answer. – Nevski May 09 '16 at 14:17
  • In that case, no problem :) Some new users don't really know how SO works so it's best to check. – webnoob May 09 '16 at 14:54
-1

View

@using (Html.BeginForm("Multiple", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) {
<table border="0" id="cssTable" class="nobg">
<tr>
    <th style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Type</b>
    </th>
    <th style="width: 400px; min-width: 400px; max-width: 400px">
        <b>File to Upload</b>
    </th>
    <th style="width: 500px; min-width: 500px; max-width: 500px">
        <b>Status</b>
    </th>
</tr>
<tr>
    <td style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Blueprint(s)</b>
    </td>
    <td style="width: 400px; min-width: 400px; max-width: 400px">
        <input type="file" name="File1" id="BP" multiple style="width: 380px" />
    </td>
    <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
        @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname = "group1" }) Uploaded
        @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname = "group1" }) Not Uploaded
        @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname = "group1" }) Not Applicable
    </td>
</tr>
<tr>
    <td style="width: 100px; min-width: 100px; max-width: 100px">
        <b>Recovery Guide(s)</b>
    </td>
    <td style="width: 400px; min-width: 400px; max-width: 400px">
        <input type="file" name="File2" id="RG" multiple style="width: 380px" />
    </td>
    <td style="width: 500px; min-width: 500px; max-width: 500px; text-align: left">
        @Html.RadioButton("Submitted", "Yes", false, new { @style = "width: 25px;", groupname = "group2" }) Uploaded
        @Html.RadioButton("Submitted", "No", false, new { @style = "width: 25px;", groupname = "group2" }) Not Uploaded
        @Html.RadioButton("Submitted", "N/A", false, new { @style = "width: 25px;", groupname = "group2" }) Not Applicable
    </td>
    <td>
        <input type="submit" value="Submit" name="submit" />
    </td>
</tr>

}

Controller

 [HttpPost]
    public ActionResult Multiple(IEnumerable<HttpPostedFileBase> File1, IEnumerable<HttpPostedFileBase> File2)
    {
        try
        {
            foreach (var file in File1)
            {
                if (file.ContentLength > 0)
                {
                    //Handle the first file list
                }
            }
            foreach (var file in File2)
            {
                if (file.ContentLength > 0)
                {
                    //Handle the second file list
                }
            }

        }
        catch (Exception ex)
        {

        }
        return View();
    }

Please see the output, you can get uploaded files on your action. enter image description here

Banwari Yadav
  • 506
  • 1
  • 3
  • 18
  • Thanks for the reply. I don't see how this would allow me to differentiate between files submitted via multiple inputs? Am I missing something obvious? Sorry if it is a stupid question! – Nevski May 09 '16 at 12:19
  • 1
    With this solution, there is no way to know which input submitted the file to the controller. Also, jQuery fileupload is completely unnecessary here. – Dygestor May 09 '16 at 12:28