Search code examples
asp.net-mvc-5

How can I delete a specific uploaded file in mvc5?


After I upload a file, I would want to be able to delete it. I tried doing so, but I get the error "The resource cannot be found". Also, how can I make edit buttons for every file from the row, in order to upload a better version of that specific file? Could someone help me?

This is my controller:

   public class FileUploadController : Controller
    {
        // GET: FileUpload
        public ActionResult Index()
        {
            var items = GetFiles();
            return View(items);
        }

        // POST: FileUpload
        [HttpPost]
        public ActionResult Index(HttpPostedFileBase file)
        {

            if(file != null && file.ContentLength > 0 )
                try
                {

                    string path = Path.Combine(Server.MapPath("~/Files"),
                        Path.GetFileName(file.FileName));

                    file.SaveAs(path);
                    ViewBag.Message = "File uploaded successfully";

                }
                catch(Exception ex)
                {
                    ViewBag.Message = "ERROR:" + ex.Message.ToString();
                }
            else
            {
                ViewBag.Message = "You have not specified a file.";
            }

            var items = GetFiles();

            return View(items);
            
        }


        public FileResult Download(string downloadedfile)
        {
            var FileVirtualPath = "~/Files/" + downloadedfile;

            return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));

        }
        private List <string> GetFiles()
        {

            var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Files"));
            System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");

            List<string> items = new List<string>();

            foreach (var file in fileNames)
            {
                items.Add(file.Name);
            }

            return items;

        }

        [HttpPost]
        public ActionResult Delete(string file)
        {
            file = Path.Combine(Server.MapPath("~/Files"), file);

            FileInfo fl = new FileInfo(file);

            if (fl != null)
            {
                System.IO.File.Delete(file);
                fl.Delete();

            }

            return View();

        }
  }
}

This is the view, the only problem with it is the Delete section:

<h2> File Upload </h2>

@model List<string>

@using (Html.BeginForm("Index", "FileUpload", FormMethod.Post,
        new { enctype = "multipart/form-data" }))
{


    <label for="file"> Upload </label>
    <input type="file" name="file" id="file" />
    <br /><br />

    <input type="submit" value="Upload" />
    <br /><br />

    @ViewBag.Message

    <br />

    <h2>Documents list</h2>

    <table style="width:100%">
        <tr>
            <th> File Name </th>
            <th> Link  </th>
        </tr>

        @for (var i = 0; i <= (Model.Count) - 1; i++)
        {
        <tr>

            <td>@Model[i].ToString() </td>

            <td>@Html.ActionLink("Download", "Download", new { downloadedfile = Model[i].ToString() }) </td>

            <td>@Html.ActionLink("Delete", "Delete", new { deletedfile = Model[i].ToString() }) </td>
           


        </tr>

        }


    </table>
}

Solution

  • In the form you're posting to the delete method, there is nothing indicating what the path to the file to delete is. You do have a hidden input for the Count property, but if that was a hidden input named "file" and contained the path value for the file to be deleted, then it would be posted.

    Note, for security reasons you likely do NOT want to allow people to just post the path to any file and the server will delete it. That could get you into a lot of trouble. You likely should be storing a database record with the file url and an ID and posting that ID to the server, and reading the URL from the database, then deleting the file.