(Preface: this question is about ASP.NET MVC 3.0 which was released in 2011, it is not about ASP.NET Core 3.0 which was released in 2019)
I want to
Often you want to pass a viewmodel also, and not the only one file. In the code below you'll find some other useful features:
It could be done via the following code:
[HttpPost]
public ActionResult Index(MyViewModel viewModel)
{
    // if file's content length is zero or no files submitted
    if (Request.Files.Count != 1 || Request.Files[0].ContentLength == 0)
    {
        ModelState.AddModelError("uploadError", "File's length is zero, or no files found");
        return View(viewModel);
    }
    // check the file size (max 4 Mb)
    if (Request.Files[0].ContentLength > 1024 * 1024 * 4)
    {
        ModelState.AddModelError("uploadError", "File size can't exceed 4 MB");
        return View(viewModel);
    }
    // check the file size (min 100 bytes)
    if (Request.Files[0].ContentLength < 100)
    {
        ModelState.AddModelError("uploadError", "File size is too small");
        return View(viewModel);
    }
    // check file extension
    string extension = Path.GetExtension(Request.Files[0].FileName).ToLower();
    if (extension != ".pdf" && extension != ".doc" && extension != ".docx" && extension != ".rtf" && extension != ".txt")
    {
        ModelState.AddModelError("uploadError", "Supported file extensions: pdf, doc, docx, rtf, txt");
        return View(viewModel);
    }
    // extract only the filename
    var fileName = Path.GetFileName(Request.Files[0].FileName);
    // store the file inside ~/App_Data/uploads folder
    var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
    try
    {
        if (System.IO.File.Exists(path))
            System.IO.File.Delete(path);
        Request.Files[0].SaveAs(path);
    }
    catch (Exception)
    {
        ModelState.AddModelError("uploadError", "Can't save file to disk");
    }
    if(ModelState.IsValid)
    {
        // put your logic here
        return View("Success");
    }
    return View(viewModel);         
}
Make sure you have
@Html.ValidationMessage("uploadError")
in your view for validation errors.
Also keep in mind that default maximum request length is 4MB (maxRequestLength = 4096), to upload larger files you have to change this parameter in web.config:
<system.web>
    <httpRuntime maxRequestLength="40960" executionTimeout="1100" />
(40960 = 40 MB here).
Execution timeout is the whole number of seconds. You may want to change it to allow huge files uploads.
Here is my working example:
[HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Create(Product product, HttpPostedFileBase file)
    {
        if (!ModelState.IsValid)
            return PartialView("Create", product);
        if (file != null)
        {
            var fileName = Path.GetFileName(file.FileName);
            var guid = Guid.NewGuid().ToString();
            var path = Path.Combine(Server.MapPath("~/Content/Uploads/ProductImages"), guid + fileName);
            file.SaveAs(path);
            string fl = path.Substring(path.LastIndexOf("\\"));
            string[] split = fl.Split('\\');
            string newpath = split[1];
            string imagepath = "Content/Uploads/ProductImages/" + newpath;
            using (MemoryStream ms = new MemoryStream())
            {
                file.InputStream.CopyTo(ms);
                byte[] array = ms.GetBuffer();
            }
            var nId = Guid.NewGuid().ToString();
            // Save record to database
            product.Id = nId;
            product.State = 1;
            product.ImagePath = imagepath;
            product.CreatedAt = DateTime.Now;
            db.Products.Add(product);
            await db.SaveChangesAsync();
            TempData["message"] = "ProductCreated";
            //return RedirectToAction("Index", product);
        }
        // after successfully uploading redirect the user
        return Json(new { success = true });
    }
In Controller
 if (MyModal.ImageFile != null)
                    {
                        MyModal.ImageURL = string.Format("{0}.{1}", Guid.NewGuid().ToString(), MyModal.ImageFile.FileName.Split('.').LastOrDefault());
                        if (MyModal.ImageFile != null)
                        {
                            var path = Path.Combine(Server.MapPath("~/Content/uploads/"), MyModal.ImageURL);
                            MyModal.ImageFile.SaveAs(path);
                        }
                    }
In View
<input type="hidden" value="" name="..."><input id="ImageFile" type="file" name="ImageFile" src="@Model.ImageURL">
In Modal Class
 public HttpPostedFileBase ImageFile { get; set; }
Create a folder as uploads in Content folder in project
I have faced this same error while i am doing file uploading concept. I know lot of answer provided by developers for this question.
Even though why i am answering to this question is, have got this error by the below mentioned inattentive mistake.
<input type="file" name="uploadedFile" />
While giving name attribute make sure that your controller parameter are also having the same name value "uploadedFile". Like this :
   [HttpPost]
            public ActionResult FileUpload(HttpPostedFileBase uploadedFile)
            {
            }
otherwise it won't get mapped.
I am giving you the simple and easy method to understand and learn.
First you have to write the following code in your .Cshtml file.
<input name="Image" type="file" class="form-control" id="resume" />
then in your controller put following code:
if (i > 0) {
    HttpPostedFileBase file = Request.Files["Image"];
    if (file != null && file.ContentLength > 0) {
        if (!string.IsNullOrEmpty(file.FileName)) {
            string extension = Path.GetExtension(file.FileName);
            switch ((extension.ToLower())) {
                case ".doc":
                    break;
                case ".docx":
                    break;
                case ".pdf":
                    break;
                default:
                    ViewBag.result = "Please attach file with extension .doc , .docx , .pdf";
                    return View();
            }
            if (!Directory.Exists(Server.MapPath("~") + "\\Resume\\")) {
                System.IO.Directory.CreateDirectory(Server.MapPath("~") + "\\Resume\\");
            }
            string documentpath = Server.MapPath("~") + "\\Resume\\" + i + "_" + file.FileName;
            file.SaveAs(documentpath);
            string filename = i + "_" + file.FileName;
            result = _objbalResume.UpdateResume(filename, i);
            Attachment at = new Attachment(documentpath);
            //ViewBag.result = (ans == true ? "Thanks for contacting us.We will reply as soon as possible" : "There is some problem. Please try again later.");
        }
    } else {
        ...
    }
}
For this you have to make BAL and DAL layer as per your Database.
please pay attention this code for upload image only. I use HTMLHelper for upload image. in cshtml file put this code
@using (Html.BeginForm("UploadImageAction", "Admin", FormMethod.Post, new { enctype = "multipart/form-data", id = "myUploadForm" }))
{
    <div class="controls">
       @Html.UploadFile("UploadImage")
    </div>
     <button class="button">Upload Image</button>
}
then create a HTMLHelper for Upload tag
public static class UploadHelper
{
public static MvcHtmlString UploadFile(this HtmlHelper helper, string name, object htmlAttributes = null)
{
    TagBuilder input = new TagBuilder("input");
    input.Attributes.Add("type", "file");
    input.Attributes.Add("id", helper.ViewData.TemplateInfo.GetFullHtmlFieldId(name));
    input.Attributes.Add("name", helper.ViewData.TemplateInfo.GetFullHtmlFieldName(name));
    if (htmlAttributes != null)
    {
        var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        input.MergeAttributes(attributes);
    }
    return new MvcHtmlString(input.ToString());
   }
}
and finally in Action Upload your file
        [AjaxOnly]
        [HttpPost]
        public ActionResult UploadImageAction(HttpPostedFileBase UploadImage)
        {
           string path = Server.MapPath("~") + "Files\\UploadImages\\" + UploadImage.FileName;
           System.Drawing.Image img = new Bitmap(UploadImage.InputStream);    
           img.Save(path);
           return View();
        }