For a customer project in ASP.NET MVC 2, we added some functionality to download files. This can easily be done in ASP.NET MVC with the FileStreamResult class. Our original code looked something like this:
1: private ActionResult CreateFileStreamResult(string filepath, string fileResultName, string contentType)
2: {
3: FileStreamResult result = new FileStreamResult(new FileStream(filepath, FileMode.Open), contentType);
4: result.FileDownloadName = fileResultName;
5: return result;
6: }
Not long after deployment in our test enviroment, we discovered that it didn’t work. Instead we got back the following exception:
System.UnauthorizedAccessException: Access to the path is denied
We double-checked the application pool, but the user account we used had the necessary read privileges on the target folder. After opening the FileStream class in Reflector, I noticed the cause of our problem. If you are using the constructor with FilePath and FileMode alone. System.IO.FileStream implementation of this constructor is
1: public FileStream(string path, FileMode mode)
2: : this(path, mode, (mode == FileMode.Append) ? FileAccess.Write : FileAccess.ReadWrite, FileShare.Read, 0×1000, FileOptions.None, Path.GetFileName(path), false)
3: {
4: }
The default constructor asks for ReadWrite access! That’s why a System.UnauthorizedAccessException is thrown in our test environment. The user account under which our application runs has no write access.
As our application needs only Read access to the folder, we change the code and use the following FileStream constructor:
1: using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
It would probably have been better if Read access was the default in System.IO.FileStream rather than ReadWrite.