Partial View file uploads
<p>I'm trying to figure out how to store multiplie files using a partial view. A screenshot of the partial view can be seen
<a href="https://i.stack.imgur.com/gH6r2.png" rel="nofollow noreferrer">here</a>.</p>
<p>The partial view itself works perfectly as long as I use regular form inputs. Storing a file however is a bit more complex. Since I'm using Entity First, I'm just storing a reference to the file instead of the actual file itself.
This works fine for a single file. The byte reference gets stored to my database and I can generate a link to the file in a view which displays all the properties of a certain record.
However, I'm clueless on how I should tackle this if I want multiple uploads. One for each added row.</p>
<p>I'm also not sure how I should target a seperate field of a certain row through jQuery as all rows get generated dynamically, but that's a different issue.</p>
<h2>Relevant code:</h2>
<p><strong>POST action of my controller:</strong></p>
<pre><code>    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult CreateSrv([Bind(Include = &quot;ID,CreationTimestamp,EditTimestamp,requestStatus,Requester,Reponsible,DeliveryDate,Project,CostCenter, MailCounter, ExtendedOrders&quot;)] Request request, HttpPostedFileBase upload)
    {
        
        if (ModelState.IsValid)
        {
            if (upload != null &amp;&amp; upload.ContentLength &gt; 0)
            {
                if (upload.ContentLength &gt; 0)
                {
                    var fileName = Path.GetFileName(upload.FileName);
                    var path = Path.Combine(Server.MapPath(&quot;~/App_Data/uploads&quot;), fileName);
                    upload.SaveAs(path);

                    using (var reader = new System.IO.BinaryReader(upload.InputStream))
                    {
                        request.ExtendedOrders.ToArray()[0].File = reader.ReadBytes(upload.ContentLength);
                    }
                }                    
            }

            request.CreationTimestamp = DateTime.Now;
            request.EditTimestamp = DateTime.Now;
            request.RequestStatus = &quot;Initial&quot;;
            request.RequestType = &quot;Services&quot;;
            db.requests.Add(request);
            db.SaveChanges();

            return RedirectToAction(&quot;Index&quot;);
        }
        return View(request);
    }
    
</code></pre>
<p><strong>Controller method which adds rows to my partial view using AJAX:</strong></p>
<pre><code>    [HttpGet]
    public ActionResult AddOrderRowExtended()
    {
        OrderExtended order = new OrderExtended();
        order.Units = GetSelectListItems(GetUnitsFromDB());
        order.Unit = &quot;PC&quot;;
        order.Currencies = GetSelectListItems(GetCurrenciesFromDB());
        order.Currency = &quot;European Euro&quot;;
        return PartialView(&quot;~/Views/Orders/OrderExtendedCreate.cshtml&quot;, order);
    }       
    
    
</code></pre>
<p><strong>I then call the partial view in my &quot;main&quot; view. The addOrder buttons adds more rows dynamically:</strong></p>
<pre><code>@using (Html.BeginForm(&quot;CreateSrv&quot;, &quot;Requests&quot;, null, FormMethod.Post, new { enctype = &quot;multipart/form-data&quot; }))
{
@Html.AntiForgeryToken()


&lt;div class=&quot;form-horizontal&quot;&gt;
... some fields of my Request model...

            &lt;tbody id=&quot;OrderZone&quot;&gt;
            @foreach (var row in Model.ExtendedOrders)
            {
                Html.RenderPartial(&quot;~/Views/Orders/OrderExtendedCreate.cshtml&quot;, row);
            }
        &lt;/tbody&gt;
    &lt;button class=&quot;btn btn-sm btn-success&quot; type=&quot;button&quot; id=&quot;addOrder&quot;&gt;Add row&lt;/button&gt;
    &lt;br /&gt;
    &lt;div class=&quot;body-content&quot;&gt;
        &lt;div class=&quot;form-group&quot;&gt;
            &lt;div class=&quot;col-md-offset-2 col-md-10&quot;&gt;
                &lt;input type=&quot;submit&quot; value=&quot;Create&quot; class=&quot;btn btn-default&quot; /&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;      
&lt;/div&gt;
</code></pre>
<p><strong>My OrderExtended model:</strong></p>
<pre><code>public class OrderExtended
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }


   ....

    [NotMapped]
    [DataType(DataType.Upload)]
    public HttpPostedFileBase Quotation { get; set; }

    public byte[] File { get; set; }

    //FK
    public int RequestRefId { get; set; }

    [ForeignKey(&quot;RequestRefId&quot;)]
    public virtual Request Request { get; set; }
}
</code></pre>
<p><strong>OrderExtendedCreate.cshtml</strong></p>
<pre><code>@model RFP_MVC.Models.OrderExtended
 


&lt;tr class=&quot;editorRow&quot;&gt;
    @using (Html.BeginCollectionItem(&quot;ExtendedOrders&quot;))
    {
        &lt;td class=&quot;col-md-2&quot;&gt;@Html.EditorFor(model =&gt; model.Material, new { htmlAttributes = new { @class = &quot;input-sm form-control&quot; } })&lt;/td&gt;
        &lt;td class=&quot;col-md-1&quot;&gt;@Html.EditorFor(model =&gt; model.Quantity, new { htmlAttributes = new { @class = &quot;input-sm form-control&quot; } })&lt;/td&gt;
        &lt;td class=&quot;col-md-2&quot;&gt;@Html.DropDownListFor(model =&gt; model.Unit, Model.Units, new { id = &quot;Unit&quot;, @class = &quot;input-sm form-control select2&quot; })&lt;/td&gt;
        &lt;td class=&quot;col-md-2&quot;&gt;@Html.DropDownListFor(model =&gt; model.PurchGroup, Model.PurchGroupList, &quot;Select...&quot;, new { @class = &quot;input-sm form-control&quot; })&lt;/td&gt;
        &lt;td class=&quot;col-md-2&quot;&gt;
            &lt;div class=&quot;input-group&quot;&gt;
                &lt;span class=&quot;input-group-btn&quot;&gt;
                    &lt;button class=&quot;btn btn-sm btn-default&quot; type=&quot;button&quot; data-toggle=&quot;modal&quot; data-target=&quot;#myModal&quot;&gt;&lt;span class=&quot;glyphicon glyphicon-search&quot;&gt;&lt;/span&gt;&lt;/button&gt;
                &lt;/span&gt;
                @Html.EditorFor(model =&gt; model.Vendor, new { htmlAttributes = new { id = &quot;Vendor&quot; , @class = &quot;input-sm form-control&quot; } })
            &lt;/div&gt;
        &lt;/td&gt;
        &lt;td class=&quot;col-md-1&quot;&gt;@Html.EditorFor(model =&gt; model.OrderingCode, new { htmlAttributes = new { @class = &quot;input-sm form-control&quot; } })&lt;/td&gt;
        &lt;td class=&quot;col-md-1&quot;&gt;@Html.EditorFor(model =&gt; model.Price, new { htmlAttributes = new { @class = &quot;input-sm form-control&quot; } })&lt;/td&gt;
        &lt;td class=&quot;col-md-1&quot;&gt;@Html.DropDownListFor(model =&gt; model.Currency, Model.Currencies, new { id = &quot;Currency&quot;, @class = &quot;input-sm form-control select2&quot; })&lt;/td&gt;
        &lt;td class=&quot;col-md-2&quot;&gt;
            &lt;span class=&quot;btn btn-sm btn-default btn-file glyphicon glyphicon-folder-open&quot;&gt;&lt;input type=&quot;file&quot; name=&quot;upload&quot;&gt;&lt;/span&gt;
        &lt;/td&gt;
    }
&lt;/tr&gt;
</code></pre>
<p>Thanks in advance</p>
<h2>Updated with solution:</h2>
<p><strong>Changed my POST method</strong></p>
<ol>
<li><p>Changed the parameter to an IEnumerable (as suggested by  ramiramilu):</p>
<p>IEnumerable  files</p>
</li>
<li><p>Loop through all the files and process them:</p>
</li>
</ol>
<pre class="lang-cs prettyprint-override"><code>int fileIndex = 0;
foreach (HttpPostedFileBase upload in files)
{
    if (upload != null &amp;&amp; upload.ContentLength &gt; 0)
    {   
        var fileName = Path.GetFileName(upload.FileName);
        var path = Path.Combine(Server.MapPath(&quot;~/uploads&quot;), fileName);
        upload.SaveAs(path);

        using (var reader = new System.IO.BinaryReader(upload.InputStream))
        {
            request.ExtendedOrders.ToArray()[fileIndex].File = reader.ReadBytes(upload.ContentLength);
        }

        fileIndex++;
    }
}
</code></pre>