Search code examples
file-uploadasp.net-mvc-5visual-studio-2017

MVC 5 file upload


Can someone help me out here. I've been following tutorials on how to use fileupload using MVC 5, but the file keeps failing to upload.

I have an Uploads folder in my App_Data folder where the files should be getting saved to. In my controller I have this:

using System.IO;
namespace [project_name].Controllers
public class [controller_name]: Controller
    {
        [HttpGet]
        public ActionResult Index()
        {

            return View();
        }

        [HttpPost]
        public ActionResult Index(HttpPostedFileBase file)
        {
            ViewBag.Message = "";
            try
            {
                // Verify that the user selected a file
                if (file.ContentLength > 0)
                {
                    // extract only the filename
                    var fileName = Path.GetFileName(file.FileName);
                    // store the file inside ~/App_Data/uploads folder
                    var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
                    file.SaveAs(path);
                }
                // redirect back to the index action to show the form once again
                ViewBag.Message = "File Upload Successful";
                return RedirectToAction("Index");
            }
            catch(Exception ex)
            {
                ViewBag.Message = ex.Message;
                return View();
            }
        }
    }

In my view I have this:

@{
    ViewBag.Title = "File Upload";
    Layout = "~/Views/Shared/_Layout.cshtml";
}



<div class="row">
    <div class="col-md-4">
        @using (Html.BeginForm("Index", "[controller_name]", FormMethod.Post, new { enctype = "multipart/form-data" }))
        {
            @ViewBag.Message<br />

            @Html.TextBox("file", "", new { type = "file" })
            <input type="submit" value="Upload" />
        }
    </div>
</div>
<br />

So, what am I missing? This project is still in development and I'm using Visual Studio 2017, so this is still using localhost for debugging. When I used breakpoints, it shows file is still null. The error I get form the catch block is "Object reference not set to an instance of an object.".

Anyone have any ideas as to what I've done wrong here?

UPDATE: I tried changing the name of the action to this:

[HttpGet]
public ActionResult Index()
{
    return View();
}


[HttpGet]
public ActionResult UploadFile() { return View(); }

[HttpPost]
public ActionResult UploadFile(HttpPostedFileBase file)
{
    ViewBag.Message = "";
    try
    {
        // Verify that the user selected a file
        if (file.ContentLength > 0)
        {
            // extract only the filename
            var fileName = Path.GetFileName(file.FileName);
            // store the file inside ~/App_Data/uploads folder
            var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName);
            file.SaveAs(path);
        }
        // redirect back to the index action to show the form once again
        ViewBag.Message = "File Upload Successful";
        return RedirectToAction("Index");
    }
    catch(Exception ex)
    {
        ViewBag.Message = ex.Message;
        return View();
    }
}

I added the view, but when I tried again, I had the same problem.


Solution

  • What you're trying to do so should be fairly simple, and I thought you had all the information you needed. Sorry if that wasn't the case :(

    If your question isn't resolved, I encourage you to start a new, "hello world" project, "from scratch", as follows:

    1. Create project:

      MSVS > New project > Name= SimpleUpload > MVC= Y

    2. Add controller:

      Controllers > Add > Add Controller > MVC 5 Controller - Empty > Name= UploadController

      public const string UPLOADS_FOLDER = @"c:\temp";
      public ActionResult Index() { ... }
      [HttpGet] public ActionResult UploadFile() { ... }
      [HttpPost] public ActionResult UploadFile(HttpPostedFileBase file) { ... }
      
    3. Add view:

      Views > Add > Add View > Name= UploadFile, Template= Empty, Use a layout page= Y

    4. Windows Explorer:

      Ensure "uploads folder" exists

    5. MSVS:

      Start app, browse to http://localhost:58021/Upload/UploadFile

    Controllers\UploadController.cs

    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    
    namespace SimpleUpload.Controllers
    {
        public class UploadController : Controller
        {
            public const string UPLOADS_FOLDER = @"c:\temp";
    
            // GET: Upload
            public ActionResult Index()
            {
                return View();
            }
    
            [HttpGet]
            public ActionResult UploadFile()
            {
                return View();
            }
    
            [HttpPost]
            public ActionResult UploadFile(HttpPostedFileBase file)
            {
                try
                {
                    if (file.ContentLength > 0)
                    {
                        string fileName = Path.GetFileName(file.FileName);
                        string path = Path.Combine(UPLOADS_FOLDER, fileName);
                        file.SaveAs(path);
                    }
                    ViewBag.Message = "File Uploaded Successfully!!";
                    return View();
                }
                catch
                {
                    ViewBag.Message = "File upload failed!!";
                    return View();
                }
    
            }
        }
    }
    

    Views\Upload\UploadFile.cshtml

    @{
        ViewBag.Title = "UploadFile"; 
     }
    
    <h2>@ViewBag.Title</h2> 
    @using (Html.BeginForm("UploadFile", "Upload", FormMethod.Post, new { enctype = "multipart/form-data" })) 
    {
        <div>
            @Html.TextBox("file", "", new { type = "file" }) <br />
            <input type="submit" value="Upload" />
            @ViewBag.Message
        </div>
     }