Download file in MVC - File Missing

Hi:

I'm trying to enable users to download a document in my MVC application by pressing a button on the screen.  

Here's what the code looks like in the controller:

public void DownloadCourseManual(string manualUrl)
        {
            manualUrl="/Resources/Level1_Manual.pdf";
            var path = Server.MapPath(manualUrl);
            var name = Path.GetFileName(path);
            var ext = Path.GetExtension(path);
            string type = "";
            // set known types based on file extension  
            if (ext != null)
            {
                switch (ext.ToLower())
                {
                    case ".htm":
                    case ".html":
                        type = "text/HTML";
                        break;

                    case ".txt":
                        type = "text/plain";
                        break;

                    case ".doc":
                    case ".rtf":
                        type = "Application/msword";
                        break;

                    case ".pdf":
                        type = "Application/pdf";
                        break;

                }
            }
            try
            {

            Response.AppendHeader("content-disposition", "attachment; filename=" + name);

            if (type != "")
                Response.ContentType = type;
            Response.WriteFile(path);
            Response.End();
            }
            catch (Exception rog)
            {

                Utilities.LogError(rog);
            }
        }

Open in new window


When I get down to Response.WriteFile(path), I get the following exception:

rog = {"Could not find file 'C:\\Users\\rbs\\Documents\\Dev\\HDC04-TFS\\HDCO4\\CodeCamper.Web\\Resources\\Level1_Manual.pdf'.":"C:\\Users\\rbs\\Documents\\Dev\\HDC04-TFS\\HDCO4\\CodeCamper.Web\\Resources\\Level1_Manual.pdf"}

I know the file is there and am able to successfully open it.  any help figuring out what I have done wrong greatly appreciated.

RBS
RBSAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
Does the web site have access to the file folder?
0
RBSAuthor Commented:
Yes it does - when - and I have had it working in the past.  When I publish my site - I get the following error - It appears that my code has resulted in the name of the MyWebSite.com getting inserted in the middle of the File Path...

Page location: /Home/DownloadCourseManual?manualUrl=~%2FResources%2FLevel1_Manual.pdf

 Message: Could not find file 'E:\HostingSpaces\RBS\MyWebSite.com\wwwroot\Resources\Level1_Manual.pdf'.

 Source: mscorlib

 Method: Void WinIOError(Int32, System.String)


 Stack Trace:

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share,
0
Bob LearnedCommented:
1) Is this a hosted web site?

2) What is the root folder for the web site on the published web server?
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

RBSAuthor Commented:
Yes, it is a hosted site.  The root form my site is 'E:\HostingSpaces\RBS\MyWebSite.com\wwwroot

Actually, I think this is the correct path.  

I have, however, been able to make some progress.

I created a new stub program and was able to get the code above working in the new simple site.  Also, what appears to be happening now is that in the original site, I am able to download/create the file Level1_Manual.pdf but there is no content in the file.  I tried with a simple text file - in my stub program - test.txt had the "This is a Test" comment in it where as in my production site, I am able to open up the test.txt document but there is no content in it.

The program was working fine - until, I think - I added it to Team Foundation Server Source control - I don't know if that has anything to do with it.  

RBS
0
Bob LearnedCommented:
"I tried with a simple text file - in my stub program - test.txt had the "This is a Test" comment in it where as in my production site, I am able to open up the test.txt document but there is no content in it."

Can you describe the process on how the file gets to the production site?
0
Craig WagnerSoftware ArchitectCommented:
This likely doesn't have anything to do with the problem, but given that this is MVC you really should be using a FileResult rather than writing the file contents to the response stream yourself.

return File( path, type );

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Gary DavisDir Internet SvcsCommented:
If added to SourceControl, perhaps the file is not checked out so it would be ReadOnly. However, I would expect a different exception at the WriteFile() call than not-found.

Gary Davis
0
RBSAuthor Commented:
Thanks for all of your help.  Finally, the solutions was to use FileResult - instead of trying to write the filestream myself.  Craig - if you could briefly explain why - or perhaps send a link to an article why this is so, greatly appreciated.  

Here is my final code which seems to work great:

public FileResult DownloadCourseManual(string manualUrl)
        {
            var pathToFile = Server.MapPath(manualUrl);
            var fileExt = Path.GetExtension(pathToFile);
            var fileName = Path.GetFileName(pathToFile);

            var contentType = "";
            if (fileExt != null)
            {
                switch (fileExt.ToLower())
                {
                    case ".htm":
                    case ".html":
                        contentType = "text/HTML";
                        break;

                    case ".txt":
                        contentType = "text/plain";
                        break;

                    case ".doc":
                    case ".rtf":
                        contentType = "Application/msword";
                        break;

                    case ".pdf":
                        contentType = "Application/pdf";
                        break;
                }
            }


            return File(pathToFile, contentType, fileName);
        }

Open in new window

0
Craig WagnerSoftware ArchitectCommented:
To be honest I'm not sure why you're getting different behavior. I just know that the "correct" way to return a file is to use the FileResult. In my experience writing directly to the response stream and shutting down that stream from within Action methods has never worked out well for me.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.