views:

89

answers:

1

My app needs to download a file after the file has been cached and then download the file. I have one jQuery.post() cache the file and then call the following after the file is successfully cached:

<script type="text/javascript">
    function startViewingFiles(fileNames) {
        $.get(
            '<%= Url.Action(MvcTemplates.Document.DisplayDownload()) %>',
            { fileName: fileNames[0] },
            function() {
                $('<div class="status fill"><p>Download complete</p></div>')
                    .appendTo('#ViewerContainer')
                    .fadeIn('slow'); 
            }
        );
    }
</script>

This communicates with the following action, as I have observed the calls actually make it to the server in VS 2008 and the FilePathResult exits the method successfully:

[HttpGet]
public virtual ActionResult DisplayDownload(string fileName)
{
    var path = _CacheService.GetCachedPath(fileName);
    return new FilePathResult(path, _MimeDictionary.LookupMimeType(fileName));
}

Using Firebug, I see the response contains a "500 Internal Server Error" that complains of a System.UnauthorizedAccessException: Access to the path 'C:\websites\WebSubscriptionPortal\CacheLocation' is denied. I configured both the VS development server and the web app in IIS 7.5 to run as my user with full access to the directory, but I always get this error. When I have the view output WindowsIdentity.GetCurrent().Name, it outputs my user name regardless of which server I use.

  1. Why am I getting the UnauthorizedAccessException?
  2. Apparently, I cannot use jQuery to download a file using FilePathResult. Is this true?
  3. Do I need to change the method used on the client or the ActionResult on the server to start the download via a Javascript method?

Update: The UnauthorizedAccessException exception is due the fact that the fileNames parameter is null, as no route was setup to map to a method with a parameter named "fileNames". So the path parameter to the FilePathResult constructor is simply the directory name as shown in the exception message.

+2  A: 

No. You cannot use jQuery to return a file via download. You can, however, set location.href to the action that delivers the file and it will download it without changing the current page. This assumes that the FileResult is an attachment, which it typically is. You should change the method on the client to use location.href instead of jQuery get. I'm not sure why you are getting the access exception. It could be that while you have access to the particular directory, your account doesn't have access to one of the intervening directories in the path.

tvanfosson
I learned the UnauthorizedAccessException is a routing issue due to the fact that the jQuery params never make it to the server. So the fileName is just a directory.`location.get` does download the file, but it does not show the download dialog. How can I rewrite the action to show the download dialog?
flipdoubt
@flipdoubt - Try using `return File( path, _MimeDictionary.LookupMimeType(fileName), fileName );`. Using the controller method and supplying the fileName parameter should trigger the response to have an attachment content disposition.
tvanfosson