title: Partial View file uploads
body: <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>