开发者

Deleting an uploaded file from the server in ASP.NET MVC3

I am trying to upload files to a folder from the admin side like a CMS. The front-end will display links to download the file. On the admin end, I would like to not only delete the reference to but also remove the actual file from the server.

Here is the part of my controller that saves the uploaded file:

[HttpPost]
public ActionResult Upload(HttpPostedFileBase file)
{
  开发者_如何学Python  if (file != null && file.ContentLength > 0)
    {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
        file.SaveAs(path);

        ViewBag.fileName = fileName.ToString();

        return RedirectToAction("Create", new {fileName = fileName });
    }

    return RedirectToAction("Index");
}

In the Create view, the admin is then allowed to enter other details about the document and that is stored on a table along with the fileName.

Now I need to be able to link to that document name like document.pdf. Am I even able to link to an uploads folder under App_Data folder?

Also, how do I remove the file and not just the table row on doing delete?


Create a separate controller to handle the downloading of the file. It also prevents your users to hotlink directly to the files.

public ActionResult GetDocument(String pathName)
{
    try
    {
        Byte[] buffer = DownloadMyFileFromSomeWhere(pathName);
        FileContentResult result = new FileContentResult(buffer, "PDF"); // or whatever file ext
        // these next two lines are optional
        String[] folders = pathName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);            
        result.FileDownloadName = folders[folders.Length - 1];

        return result;
    }
    catch (Exception ex)
    {
        // log the error or something
    }
    return new HttpNotFoundResult();
}

Where DownloadMyFileFromSomeWhere(string) should be able to retrieve the byte-array file from some storage like a blob or even the local server. It can look something like:

private Byte[] DownloadMyFileFromSomeWhere(string pathname)
{
    Byte[] file = System.IO.File.ReadAllBytes(Server.MapPath(pathname));
    return file;
}

For the Admin side, you can do the same approach: Write a separate controller to delete the file and its entry in the database.


Some notes:

  • If you have rights to save a file somewhere, you should also have the rights to delete it. You can use normal file operations to do this.
  • IIS should block you from linking to a file under App_Data. You have a couple of options:
    • Create an action that reads the file from that location and streams it back to the browser
    • Store in a different location - somewhere that the user will actually have access to.

The benefit of the first option is that you can easily add authentication, etc. to your action to secure access to the files, whereas the second option would require you to add a web.config in the folder with the appropriate roles and access rights. However, on the other hand, you'll have to supply appropriate headers in your action method so the browser knows what to do with the file, rather than letting IIS figure it out for you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜