0

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.

NMeneses
  • 152
  • 6
  • 20
  • I assume you're selecting a valid file on your local filesystem, it's not in-use, and you have read permissions. It also sounds like you're successfully calling your POST ActionHandler. Please rename your POST ActionHandler something besides "Index". `UploadFile(HttpPostedFileBase file)` would be good. Please let us know if this makes any difference. See also: https://stackoverflow.com/questions/44127682/ – paulsm4 Sep 08 '20 at 23:22
  • No luck. Same error. – NMeneses Sep 08 '20 at 23:35
  • Q: Did you resolve this yet? I'm guessing "No", and I'm not sure why. So I took the liberty of updating my post with a complete "start from scratch" example. I encourage you to do the same, and post back what you find. – paulsm4 Sep 12 '20 at 19:04

1 Answers1

1

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>
 }
paulsm4
  • 114,292
  • 17
  • 138
  • 190
  • Still no luck. Now I get the following server error: The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly. Requested URL: /HROFileUpload/Index Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.8.4210.0 and URL reads: "https://localhost:44399/HROFileUpload/Index?" – NMeneses Sep 09 '20 at 17:50
  • I will circle around to this later today and will let you know how it goes. I greatly appreciate your patience and willingness to help! – NMeneses Sep 14 '20 at 17:28
  • I created a new project and followed the instructions in the link you provided, and viola it worked perfectly. So now the question is, why isn't it working with the @using Html.BeginForm() in my project. Thank you for the help, I'll dig into this today and see what I come up with. I'll post updates as I find working solutions. – NMeneses Sep 15 '20 at 19:48
  • Glad you got it working! Remember from our earlier discussion, the name "Index", by convention, is "special". Specifically, the `Index()` method in your controller will be invoked by an HTTP "GET" request to `http://myurl/`. Either explicit trailing "/", or implicit `http://myurl`. That may (or may not) be relevant to your troubleshooting... – paulsm4 Sep 15 '20 at 21:03