refactor
refactor

Reputation: 15054

File download link in ASP.NET MVC application

In my MVC application when user clicks a particular link(a href) , an image will be downloaded.

Below is the action code which downloads the image

public ActionResult Download()
    {
        try
        {
            HttpClient client = new HttpClient();
            byte[] data = client.GetByteArrayAsync("http://public.slidesharecdn.com/b/images/logo/linkdsfsfsfsfedin-ss/SS_Logo_White_Large.png?6d1f7a78a6").Result;
            return File(data, "application/jpg", "testimage.jpg");
        }
        catch (Exception err)
        {
            return new HttpNotFoundResult();
        }
    }

But incase of exception it will display default IIS "HTTP Error 404.0 - Not Found" page, instead I would like to display javascript alert "Image not found".

To implement this requirement , do I need to make an AJAX call, instead of direct HTTP GET?

Upvotes: 0

Views: 1945

Answers (2)

Saleem
Saleem

Reputation: 8978

Yes. By default browser catches http status and render appropriate page. However if you want to modify this behavior and display JavaScript alert, you'll need to implement it in JavaScript (Ajax).

Update:

Here are few great resources about how to download files using Ajax.

Download a file by jQuery.Ajax

and

download file using an ajax request

Upvotes: 0

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

You can implement AJAX call instead of HTTP GET using jQuery.ajax and send proper response after checking file existence in target URL:

<script type="text/javascript">
$.ajax({
    cache: false,
    url: "@Url.Action("Download", "Controller")",
    data: { imageUrl: [your image link here], fileName: [image filename] },
    dataType: 'json',
    success: function (data) {
       // download image to client's browser
    },
    error: function (err) {
       alert(err);
    }
});
</script>

// note that input variable should match with AJAX call data parameter
public ActionResult Download(String imageUrl, String fileName) 
{
    // check if image URL exists by reading response header
    boolean fileExist;
    HttpWebResponse response = null;
    var request = (HttpWebRequest)WebRequest.Create(imageUrl);
    request.Timeout = 10000; // in milliseconds, e.g. 10 sec
    request.Method = "HEAD";

    try
    {
        response = (HttpWebResponse)request.GetResponse(); // get validity response
        fileExist = response.StatusCode == HttpStatusCode.OK;

        if (fileExist)
        {
            HttpClient client = new HttpClient();
            byte[] data = client.GetByteArrayAsync(imageUrl);
            return File(data, "application/jpg", fileName);
        }
        else
        {
            return new HttpStatusCodeResult(404, "Image not found");
        }
    }
    catch (Exception err)
    {
         return new HttpStatusCodeResult(400, "Bad request" + err.Message); // 404 also eligible here, assume it is bad request
    }
    finally
    {
        if (response != null) 
        {
            response.Close();
        }
    }
}

Reference:

(1) can I check if a file exists at a URL?

(2) How to call error function in $.ajax with c# MVC4?

CMIIW.

Upvotes: 1

Related Questions