1

I have recently started working with web api's.

I need to download a file in C# project from a web api, which works fine when I hit the web api using postman's send and download option. Refer to the image, also please check the response in header's tab. This way, I am able to directly download the file to my computer.

Api call using postman

I want to do the same from my C# project, I found following two links which shows how to download a file from web api.

https://code.msdn.microsoft.com/HttpClient-Downloading-to-4cc138fd http://blogs.msdn.com/b/henrikn/archive/2012/02/16/downloading-a-google-map-to-local-file.aspx

I am using the following code in C# project to get the response:

 private static async Task FileDownloadAsync()
    {
        using (var client = new HttpClient())
        {

            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Add("Accept", "text/html");
            try
            {
                // _address is exactly same which I use from postman
                HttpResponseMessage response = await client.GetAsync(_address);
                if (response.IsSuccessStatusCode)
                {
                }
                else
                {
                }
            }
            catch (Exception)
            {
                throw;
            }
        }
    }

However I am not getting the response at all (before I can start to convert the response to a file), please check the error message coming:

Error message

What am I missing here, any help would be appreciated.

Community
  • 1
  • 1
Randeep Singh
  • 1,275
  • 14
  • 29

3 Answers3

1

As the (500s) error says - it's the Server that rejects the request. The only thing I see that could cause an issues is the charset encoding. Yours is the default UTF-8. You could try with other encodings.

ekostadinov
  • 6,880
  • 3
  • 29
  • 47
  • See my updated answer. You use the default encoding, but the Server may require something different...like utf-16. Can you find somedocs for this service? – ekostadinov Feb 27 '16 at 08:10
  • I am pretty much new to web api's , if you know, could you please let me know how can I specify encoding while making an httpClient call – Randeep Singh Feb 27 '16 at 09:13
  • You can specify this in the headers. Here are some [code examples](http://stackoverflow.com/questions/15026953/httpclient-request-like-browser) which are very close to your case. – ekostadinov Feb 27 '16 at 09:20
1

Below method uses:

  1. SSL certificate (comment out code for cert, if you don't use it)
  2. Custom api header for additional layer of security (comment out Custom_Header_If_You_Need code, if you don't need that)
  3. EnsureSuccessStatusCode will throw an error, when response is not 200. This error will be caught in and converted to a human readable string format to show on your screen (if you need to). Again, comment it out if you don't need that.

    private byte[] DownloadMediaMethod(string mediaId)
    {
        var cert = new X509Certificate2("Keystore/p12_keystore.p12", "p12_keystore_password");
        var handler = new WebRequestHandler { ClientCertificates = { cert } };
        using (var client = new HttpClient(handler))
        {
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Add("Custom_Header_If_You_Need", "Value_For_Custom_Header");
            var httpResponse = client.GetAsync(new Uri($"https://my_api.my_company.com/api/v1/my_media_controller/{mediaId}")).Result;
            //Below one line is most relevant to this question, and will address your problem.  Other code in this example if just to show the solution as a whole.
            var result = httpResponse.Content.ReadAsByteArrayAsync().Result;
            try
            {
                httpResponse.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                if (result == null || result.Length == 0) throw;
                using (var ms = new MemoryStream(result))
                {
                    var sr = new StreamReader(ms);
                    throw new Exception(sr.ReadToEnd(), ex);
                }
            }
            return result;
        }
    }
    

Once you have your http response 200, you can use the received bytes[] as under to save them in a file:

using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
    fs.Write(content, 0, content.Length);
}
fluidguid
  • 1,511
  • 14
  • 25
0

Your request header says that you accept HTML responses only. That could be a problem.

Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139