0

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?

refactor
  • 13,954
  • 24
  • 68
  • 103

2 Answers2

1

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.

Community
  • 1
  • 1
Tetsuya Yamamoto
  • 24,297
  • 8
  • 39
  • 61
0

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

Community
  • 1
  • 1
Saleem
  • 8,728
  • 2
  • 20
  • 34
  • But image is not getting downloaded , but incase of 404 error , alert is displayed . – refactor Jun 16 '16 at 08:49
  • Well, see http://stackoverflow.com/questions/20830309/download-file-using-an-ajax-request – Saleem Jun 16 '16 at 08:59
  • 1
    Nope. You'll be handling same request differently based on status. If success, hookup download logic, else display alert. – Saleem Jun 16 '16 at 09:02
  • add your comment(the one where you mentioned the link) as your answer , I will accept it as answer , what do you say ? – refactor Jun 16 '16 at 09:05
  • 1
    Here is another link worth looking at. http://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax – Saleem Jun 16 '16 at 09:07