title: Form File Upload with other TextBox Inputs + Creating Custom Form Action attribute
body: <p>I am attempting to create a form where a user is able to enter your typical form values textboxes etc, but also upload a file as part of the form submission. This is my View code it can be seen that the File upload is identified by the MCF id:</p>
  
  <pre><code>&lt;% using (Html.BeginForm("Create", "Problem", FormMethod.Post, new { id = "ProblemForm", enctype = "multipart/form-data" }))
     {%&gt;
  
          &lt;p&gt;
              &lt;label for="StudentEmail"&gt;Student Email (*)&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextBox("StudentEmail", Model.Problem.StudentEmail, new { size = "30", maxlength=26 })%&gt;
              &lt;%= Html.ValidationMessage("StudentEmail", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="Type"&gt;Communication Type (*)&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.DropDownList("Type") %&gt;
              &lt;%= Html.ValidationMessage("Type", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="ProblemDateTime"&gt;Problem Date (*)&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextBox("ProblemDateTime", String.Format("{0:d}", Model.Problem.ProblemDateTime), new { maxlength = 10 })%&gt;
              &lt;%= Html.ValidationMessage("ProblemDateTime", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="ProblemCategory"&gt;Problem Category (* OR Problem Outline)&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.DropDownList("ProblemCategory", null, "Please Select...")%&gt;
              &lt;%= Html.ValidationMessage("ProblemCategory", "*")%&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="ProblemOutline"&gt;Problem Outline (* OR Problem Category)&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextArea("ProblemOutline", Model.Problem.ProblemOutline, 6, 75, new { maxlength = 255 })%&gt;
              &lt;%= Html.ValidationMessage("ProblemOutline", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="MCF"&gt;Mitigating Circumstance Form&lt;/label&gt;
              &lt;br /&gt;
              &lt;input id="MCF" type="file" /&gt;
              &lt;%= Html.ValidationMessage("MCF", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="MCL"&gt;Mitigating Circumstance Level&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.DropDownList("MCL") %&gt;
              &lt;%= Html.ValidationMessage("MCL", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="AbsentFrom"&gt;Date Absent From&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextBox("AbsentFrom", String.Format("{0:d}", Model.Problem.AbsentFrom), new { maxlength = 10 })%&gt;
              &lt;%= Html.ValidationMessage("AbsentFrom", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="AbsentUntil"&gt;Date Absent Until&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextBox("AbsentUntil", String.Format("{0:d}", Model.Problem.AbsentUntil), new { maxlength = 10 })%&gt;
              &lt;%= Html.ValidationMessage("AbsentUntil", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="AssessmentID"&gt;Assessment Extension&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.DropDownList("AssessmentID") %&gt;
              &lt;%= Html.ValidationMessage("AssessmentID", "*") %&gt;
  
              &lt;%= Html.TextBox("DateUntil", String.Format("{0:d}", Model.AssessmentExtension.DateUntil), new { maxlength = 16 })%&gt;
              &lt;%= Html.ValidationMessage("DateUntil", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="Details"&gt;Assessment Extension Details&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextArea("Details", Model.AssessmentExtension.Details, 6, 75, new { maxlength = 255 })%&gt;
              &lt;%= Html.ValidationMessage("Details", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="RequestedFollowUp"&gt;Requested Follow Up&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.TextBox("RequestedFollowUp", String.Format("{0:d}", Model.Problem.RequestedFollowUp), new { maxlength = 16 })%&gt;
              &lt;%= Html.ValidationMessage("RequestedFollowUp", "*") %&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;label for="StaffEmail"&gt;Staff&lt;/label&gt;
              &lt;br /&gt;
              &lt;%= Html.ListBox("StaffEmail", Model.StaffEmail, new { @class = "multiselect" })%&gt;
              &lt;%= Html.ValidationMessage("StaffEmail", "*")%&gt;
          &lt;/p&gt;
          &lt;p&gt;
              &lt;input class="button" type="submit" value="Create Problem" /&gt;
          &lt;/p&gt;
  </code></pre>
  
  <p>This is my controller code:</p>
  
  <pre><code>        [AcceptVerbs(HttpVerbs.Post)]
      public ActionResult Create(Problem problem, AssessmentExtension assessmentExtension, Staff staffMember, HttpPostedFileBase file, string[] StaffEmail)
      {
          if (ModelState.IsValid)
          {
              try
              {
  
                  Student student = studentRepository.GetStudent(problem.StudentEmail);
                  Staff currentUserStaffMember = staffRepository.GetStaffWindowsLogon(User.Identity.Name);
  
                  var fileName = Path.Combine(Request.MapPath("~/App_Data"), Path.GetFileName(file.FileName));
                  file.SaveAs(@"C:\Temp\" + fileName);
  
                  if (problem.RequestedFollowUp.HasValue)
                  {
                      String meetingName = student.FirstName + " " + student.LastName + " " + "Mitigating Circumstance Meeting";
                      OutlookAppointment outlookAppointment = new OutlookAppointment(currentUserStaffMember.Email, meetingName, (DateTime)problem.RequestedFollowUp, (DateTime)problem.RequestedFollowUp.Value.AddMinutes(30));
                  }
  
                  problemRepository.Add(problem);
                  problemRepository.Save();
  
                  if (assessmentExtension.DateUntil != null)
                  {
                      assessmentExtension.ProblemID = problem.ProblemID;
                      assessmentExtensionRepository.Add(assessmentExtension);
                      assessmentExtensionRepository.Save();
                  }
  
                  ProblemPrivacy problemPrivacy = new ProblemPrivacy();
                  problemPrivacy.ProblemID = problem.ProblemID;
                  problemPrivacy.StaffEmail = currentUserStaffMember.Email;
                  problemPrivacyRepository.Add(problemPrivacy);
  
                  if (StaffEmail != null)
                  {
                      for (int i = 0; i &lt; StaffEmail.Length; i++)
                      {
                          ProblemPrivacy probPrivacy = new ProblemPrivacy();
                          probPrivacy.ProblemID = problem.ProblemID;
                          probPrivacy.StaffEmail = StaffEmail[i];
                          problemPrivacyRepository.Add(probPrivacy);
                      }
                  }
  
                  problemPrivacyRepository.Save();
  
                  return RedirectToAction("Details", "Student", new { id = student.Email });
  
              }
              catch
              {
                  ModelState.AddRuleViolations(problem.GetRuleViolations());
              }
          }
  
          return View(new ProblemFormViewModel(problem, assessmentExtension, staffMember));
      }
  </code></pre>
  
  <p>This form was working correctly before I had to switch to using a non-AJAX file upload, this was due to an issue with Flash when enabling Windows Authentication which I need to use.</p>
  
  <p>It appears that when I submit the form the file is not sent and I am unsure as to why? I have also been unsuccessful in finding an example online where a file upload is used in conjunction with other input types.</p>
  
  <p>Another query I have is that for Create, and Edit operations I have used a PartialView for my forms to make my application have higher code reuse. The form action is normally generated by just using:</p>
  
  <pre><code>Html.BeginForm()
  </code></pre>
  
  <p>And this populates the action depending on which Url is being used Edit or Create. However when populating HTML attributes you have to provide a action and controller value to pass HTML attributes. </p>
  
  <pre><code>using (Html.BeginForm("Create", "Problem", FormMethod.Post, new { id = "ProblemForm", enctype = "multipart/form-data" }))
  </code></pre>
  
  <p>Is it possible to somehow populate the action and controller value depending on the URL to maintain code reuse? Thinking about it whilst typing this I could set two values in the original controller action request view data and then just populate the value using the viewdata values?</p>
  
  <p>Any help on these two issues would be appreciated, I'm new to asp.net mvc :-)</p>
  
  <p>Thanks,</p>
  
  <p>Jon</p>
  
  <p>ANSWER</p>
  
  <p>Ok guys worked out the issue and its incredibly simple I didn't have the HTML name attribute on the file component of my form:</p>
  
  <pre><code>&lt;input id="MCF" name="MCF" type="file" /&gt;
  </code></pre>
  
  <p>Now this binds to my method signature!</p>