0

Okay, we have a PHP script that creates an download link from a file and we want to download that file via C#. This works fine with progress etc but when the PHP page gives an error the program downloads the error page and saves it as the requested file. Here is the code we have atm:

PHP Code:

<?php
$path = 'upload/test.rar';

    if (file_exists($path)) {
        $mm_type="application/octet-stream";
        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Type: " . $mm_type);
        header("Content-Length: " .(string)(filesize($path)) );
        header('Content-Disposition: attachment; filename="'.basename($path).'"');
        header("Content-Transfer-Encoding: binary\n");
        readfile($path); 
        exit();
    } 
    else {
    print 'Sorry, we could not find requested download file.';
    }
?>

C# Code:

private void btnDownload_Click(object sender, EventArgs e)
    {
        string url = "http://***.com/download.php";
        WebClient client = new WebClient();
        client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
        client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);
        client.DownloadFileAsync(new Uri(url), @"c:\temp\test.rar");
    }

    private void ProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        progressBar.Value = e.ProgressPercentage;
    }

    void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
    {
            MessageBox.Show(print);
    }
Yuki Kutsuya
  • 3,968
  • 11
  • 46
  • 63

2 Answers2

1

Instead of printing an error message, you should use the Header function in PHP documented here.

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404); 

Due to the nature of your Async call, no WebException is thrown. On your DownloadFileCompleted callback, you can check

if(e.Error != null)

Your e.Error will contain a line similar to "The remote server returned an error: (404) Not Found.".

emartel
  • 7,712
  • 1
  • 30
  • 58
  • Is there no way to get like, get the custom print message instead of showing the default exception header? Because there can be more custom exceptions that we will implant. – Yuki Kutsuya Nov 14 '12 at 23:18
  • You risk of having a collision between your status messages and the data that you're trying to transfer. Passing through the header should guarantee the `WebException` and then you could probably have a second `header` call to set the message? – emartel Nov 14 '12 at 23:23
  • Umm, could you give me an example? I never did that before :(. – Yuki Kutsuya Nov 14 '12 at 23:25
  • Me neither, unfortunately, but according to the doc your `WebException` will have a `StatusCode` and a `StatusDescription`, you could probably try changing the part avec 404 and see if you can trap that as a Description. Otherwise, since it's your own tools, you're not restricted to the standard error codes a Browser has to support for HTTP, you can probably use your own (though `404` is pretty well known for `file not found`) – emartel Nov 14 '12 at 23:27
  • After some local tests, I edited my answer, hopefully this is more useful to you – emartel Nov 15 '12 at 01:54
1

You need to inform the webclient that an error as occurred by setting headers just like you have when a successful download is happening. I'm not very familiar with PHP, but found a 401 example

header('HTTP/1.0 401 Unauthorized', true, 401);

from here

Community
  • 1
  • 1
Darren Reid
  • 2,322
  • 20
  • 25