Return message when download file not found using FileStreamResult
Asked Answered
A

1

6

I have a directory "Downloads" where I have static files that our clients can download. I am using the the following ActionLink to call the file:

@Html.ActionLink("Download Example", "Download", new { area = "", controller = "Common", fileName = "SomeFile.xlsx" })

that calls the "Common" controller and returns the file using the code below:

public FileStreamResult Download(string fileName)
        {
            var filePath = Server.MapPath("~/Download/" + fileName);

            var ext = Path.GetExtension(fileName);

            switch (ext)
            {
                case ".xlsx":
                    return new FileStreamResult(new FileStream(filePath, FileMode.Open),
                        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
                case ".xls":
                    return
                        new FileStreamResult(
                            new FileStream(Server.MapPath("~/Download/" + fileName), FileMode.Open),
                            "application/vnd.ms-excel");
                case ".pdf":
                    return
                        new FileStreamResult(
                            new FileStream(Server.MapPath("~/Download/" + fileName), FileMode.Open),
                            "application/pdf");
            }

            return null;
        }
    }

My question is that since I am not returning a view, how can I return a message to the View to show if the file is not there (404)?

I have figured out this much:

 if (!System.IO.File.Exists(filePath))
    {

    }

but I have no idea on what to return to avoid a 404 redirect. I want to return a message "File not found" or something similar within the page rather than the page redirecting to the 404 error page.

Arkose answered 3/4, 2015 at 0:16 Comment(9)
404 isn't a redirect - it's just a "not found" error. Surely that's the most appropriate response if the file you're trying to fetch doesn't exist. It's not really clear what you're asking.Deuno
I want to return a message "File not found" or something similar rather than the page redirecting to the 404 error page.Arkose
It's not really clear to me what you mean. What HTTP response code would you expect to return? If it's anything other than 404, I'd say that's a bad idea.Deuno
What I am after, using the !File.Exists switch is to return a message rather than the page to display "File not found" .Arkose
I don't want to lose the page display when file does not exist - I want to create an alert or a viewbag message that will display rather than the whole page showing 404.Arkose
What "page display" do you mean though? Fundamentally, you've got to respond to the HTTP request with an HTTP response, and I'd expect that HTTP response to be a 404. Now you can potentially give a different error message within that response, but it should still be a 404...Deuno
Now I see the disconnect. If the file exists, it is downloaded and the view remains unchanged. If the file does not exist, the view is lost and replaced with the IIS default 404 view. This is what I am trying to avoid.Arkose
That doesn't tell us what you want to happen, in terms of the HTTP response...Deuno
throw new HttpException(404, "File not found") otherwise you need to change your return type. And anything other than a native HTTP response code is bad practice. besides, you can use filters to handle the "not found" message however you'd like (to the client).Reg
Z
8

I would suggest to make your return type to base ActionResult rather FileStreamResult then you can have flexibility to handle this.

  1. you can redirect to your custom method and then from that you can provide proper message / view.
  2. through exception and and on config file handle 404 with your custom error file. (throw new HttpException(404, "Not found");)

hope this resolve your issue.

Zamudio answered 3/4, 2015 at 1:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.