1. It's very simple and easy to upload a file without Ajax 
 
 It's easy to upload a file in a synchronous form, where you just post the file and  read a HttpPostedFile variable in the server side: In plain html form, take note  of the form ectype property:
 
 In view write this code:
   @using  (Html.BeginForm("Upload", "Fileupload",  FormMethod.Post, new { enctype = "multipart/form-data" }))
  {
      <input type="file" name="file">
      <input type="submit" value="OK">
  } 
 And after this write this code in the controller 
   public class  FileuploadController : Controller
  {
          //it should show index.cshtml view
          public ActionResult  Index()
          {
              return View();
          }
          [HttpPost]
          public ActionResult  Upload(HttpPostedFile file)
          {
              if (file != null  && file.ContentLength > 0)
               { //now you have a non-empty file
                   //to save in a local directory
                   var fileName =  Path.GetFileName(file.FileName);
                   var path =  Path.Combine(Server.MapPath("~/Uploads"),  fileName);
                   file.SaveAs(path);
          }
          return new EmptyResult();
      }
  }
 2. But when you use the ajax form, it sends a null value in http posted file 
 
 To resolve this issue I use one js file that converts this in the I frame  and easily uploads the file 
 
 That should work, no problem, but what if you have an ajax form, asynchronously,  you will not be able to upload a file together with the other form fields. So,  I've used a 3rd party javascript library to create a hidden iframe that will  contain a file field. 
 
 Js file code is below:
   jQuery.extend({
   createUploadIframe: function (id, uri) {
   //create frame
   var  frameId = 'jUploadFrame' + id;
   
   if (window.ActiveXObject)  {
   var  io = document.createElement('<iframe id="' +  frameId + '" name="' + frameId + '" />');
   if (typeof  uri == 'boolean') {
  io.src = 'javascript:false';
  }
   else if (typeof uri  == 'string') {
  io.src = uri;
  }
  }
   else  {
   var  io = document.createElement('iframe');
  io.id =  frameId;
  io.name =  frameId;
  }
   io.style.position = 'absolute';
  io.style.top  = '-1000px';
   io.style.left = '-1000px';
   document.body.appendChild(io);
   return  io
  },
   createUploadForm: function (id, fileElementId) {
  alert("ajaxfile"  + id)
  alert("ajaxfile"  + fileElementId)
   //create form 
   var  formId = 'jUploadForm' + id;
   var  fileId = 'jUploadFile' + id;
   var  form = $('<form action="" method="POST" name="'  + formId + '" id="' + formId + '" enctype="multipart/form-data"></form>');
   var  oldElement = $('#' + fileElementId);
   var  newElement = $(oldElement).clone();
  $(oldElement).attr('id',  fileId);
  $(oldElement).before(newElement);
  $(oldElement).appendTo(form);
   //set attributes
  $(form).css('position', 'absolute');
  $(form).css('top', '-1200px');
  $(form).css('left', '-1200px');
  $(form).appendTo('body');
   return  form;
  },
   ajaxFileUpload: function (s) {
  alert("file");
   // TODO introduce global settings, allowing the client to modify them for all  requests, not only timeout 
  s =  jQuery.extend({}, jQuery.ajaxSettings, s);
   var  id = new Date().getTime()
   var  form = jQuery.createUploadForm(id, s.fileElementId);
   var  io = jQuery.createUploadIframe(id, s.secureuri);
   var  frameId = 'jUploadFrame' + id;
   var  formId = 'jUploadForm' + id;
   // Watch for a new set of requests
   if (s.global  && !jQuery.active++) {
   jQuery.event.trigger("ajaxStart");
  }
   var  requestDone = false;
   // Create the request object
   var  xml = {}
   if (s.global)
   jQuery.event.trigger("ajaxSend", [xml, s]);
   // Wait for a response to come back
   var  uploadCallback = function (isTimeout) {
   var  io = document.getElementById(frameId);
   try {
   if (io.contentWindow)  {
   xml.responseText = io.contentWindow.document.body ?  io.contentWindow.document.body.innerHTML : null;
   xml.responseXML = io.contentWindow.document.XMLDocument ?  io.contentWindow.document.XMLDocument : io.contentWindow.document;
   
  } else if (io.contentDocument)  {
   xml.responseText = io.contentDocument.document.body ?  io.contentDocument.document.body.innerHTML : null;
   xml.responseXML = io.contentDocument.document.XMLDocument ?  io.contentDocument.document.XMLDocument : io.contentDocument.document;
  }
  } catch (e) {
   jQuery.handleError(s, xml, null, e);
  }
   if  (xml || isTimeout == "timeout") {
  requestDone  = true;
   var  status;
   try {
  status =  isTimeout != "timeout" ? "success" : "error";
   // Make sure that the request was successful or notmodified
   if  (status != "error") {
   // process the data (runs the xml through httpData regardless of callback)
   var  data = jQuery.uploadHttpData(xml, s.dataType);
   // If a local callback was specified, fire it and pass it the data
   if (s.success)
   s.success(data, status);
   
   // Fire the global callback
   if (s.global)
   jQuery.event.trigger("ajaxSuccess", [xml, s]);
  } else
   jQuery.handleError(s, xml, status);
  } catch (e) {
  status = "error";
   jQuery.handleError(s, xml, status, e);
  }
   // The request was completed
   if (s.global)
   jQuery.event.trigger("ajaxComplete", [xml,  s]);
   // Handle the global AJAX counter
   if (s.global  && ! --jQuery.active)
   jQuery.event.trigger("ajaxStop");
   // Process result
   if (s.complete)
   s.complete(xml, status);
   jQuery(io).unbind()
  setTimeout(function  () {
   try {
  $(io).remove();
  $(form).remove();
  } catch (e) {
   jQuery.handleError(s, xml, null, e);
  }
  }, 100)
  xml = null
  }
  }
   // Timeout checker
   if (s.timeout  > 0) {
  setTimeout(function  () {
   // Check to see if the request is still happening
   if (!requestDone)  uploadCallback("timeout");
  }, s.timeout);
  }
   try {
   // var io = $('#' + frameId);
   var  form = $('#' + formId);
  $(form).attr('action',  s.url);
  $(form).attr('method', 'POST');
  $(form).attr('target',  frameId);
   if (form.encoding)  {
   form.encoding = 'multipart/form-data';
  }
   else  {
  form.enctype  = 'multipart/form-data';
  }
  $(form).submit();
  } catch (e) {
   jQuery.handleError(s, xml, null, e);
  }
   if (window.attachEvent)  {
   document.getElementById(frameId).attachEvent('onload',  uploadCallback);
  }
   else  {
   document.getElementById(frameId).addEventListener('load',  uploadCallback, false);
  }
   return  { abort: function () { } };
  },
   uploadHttpData: function (r, type) {
   var  data = !type;
  data = type  == "xml" || data ? r.responseXML :  r.responseText;
   // If the type is "script", eval it in global context
   if  (type == "script")
   jQuery.globalEval(data);
   // Get the JavaScript object, if JSON is used.
   if  (type == "json")
  eval("data  = " + data);
   // evaluate scripts within html
   if  (type == "html")
  jQuery("<div>").html(data).evalScripts();
   //alert($('param', data).each(function(){alert($(this).attr('value'));}));
   return  data;
  }
  })
   //index.cshtml view
  <script src="@Url.Content("~/Scripts/ajaxfileupload.js")" 
  type="text/javascript"></script>
   <script type="text/javascript">
   function  ajaxFileUpload() {
  $.ajaxFileUpload
  (
  {
  url: "@Url.Action("UploadAttachment",  "File")",
  secureuri: false,
   fileElementId: 'FileUpload',
  dataType: 'json',
  data: {
  Name: $('#Name').val(), //you can declare the other form elements here
  },
  success: function (data, status) {
   if (typeof  (data.error) != 'undefined') {
   if (data.error  != '') {
   //alert(data.error);
  } else {
   //alert(data.msg);
  }
  }
  },
  error: function (data, status, e) {
   //alert(e);
  }
  }
  )
   return false;
  }
  @using (Ajax.BeginForm("Upload", "File", new {  }, new AjaxOptions { },  new { enctype = "multipart/form-data"  }))
  {
   </script>
   <table>
      <tr>
          <td class="label">
               @Html.LabelFor(m => m.Name)
          </td>
          <td>
              <div class="field_container">
                   @Html.TextBoxFor(m => m.Name)
              </div>
          </td>
      </tr>
      <tr>
          <td class="label">
               @Html.LabelFor(m => m.PathToAttachment)
          </td>
          <td>
              <div class="field_container">
                   @Html.TextBoxFor(m => m.FileUpload, new { type = "file" })
              </div>
          </td>
      </tr>
   </table>
   <input type="submit" value="OK">
  }  
   public class FileController  : Controller
  {    
       //it should show index.cshtml view
          public ActionResult  Index() { return View(); }
          //do nothing on form submit
          [HttpPost]
          public ActionResult  AddAttachment(AttachmentModel model)
          {
              return Json(new  { success = true });
          }
          //this is where the file gets save in the server
          public ActionResult  UploadAttachment(String Name, HttpPostedFile FileUpload)
          {
              if (FileUpload.ContentLength > 0)
               {
                   var r =  new Random();
                   var uploadPath = Server.MapPath("~/Uploads");
                   var filename = FileName.Replace("_", "");
                   var savedFileName =  Path.Combine(uploadPath, Path.GetFileName(filename));
                   //now you have your file
               }
              return new EmptyResult();
          }
  }