Reputation: 1451
I am trying to download an image from
http://aplweb.soriana.com/foto/fotolib/14/7503003936114/7503003936114-01-01-01.jpg
using WebClient.
When I browse the image in Chrome the image is there:
The url ends in .jpg but the image is in .WEBP format.
using (WebClient wb = new WebClient())
{
wb.DownloadFile("http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg", "image.jpg");
}
I have tried .DownloadData(), asyng methods, HttpClient, WebRequest directly... and I am always getting the same error.
Any idea?
Upvotes: 1
Views: 2871
Reputation: 4824
Your code is fine but this is a server-specific behavior. Adding some request headers fixes the issue.
Here's an example using HttpClient
class Program
{
private static readonly HttpClient client = new HttpClient(new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.All // automatically adds HTTP header "Accept-Encoding: gzip, deflate, br"
});
static async Task Main(string[] args)
{
client.DefaultRequestHeaders.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
try
{
Console.WriteLine("Downloading...");
byte[] data = await client.GetByteArrayAsync("http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg");
Console.WriteLine("Saving...");
File.WriteAllBytes("image.jpg", data);
Console.WriteLine("OK.");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
Console output
Downloading...
Saving...
OK.
Downloaded image
Upvotes: 5
Reputation: 81583
Your problem is to do with headers. But, let's start you on the right track and teach you one of the more modern ways of making Http Requests using DI, Services, and IHttpClientFactory
.
Service
public class MyFunkyService
{
private readonly IHttpClientFactory _clientFactory;
public MyFunkyService(IHttpClientFactory clientFactory)
=> _clientFactory = clientFactory;
public async Task<byte[]> GetSomeFunkyThingAsync()
{
using var client = _clientFactory.CreateClient();
using var request = new HttpRequestMessage(HttpMethod.Get, "http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg");
request.Headers.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
request.Headers.AcceptEncoding.ParseAdd("gzip, deflate");
using var response = await client
.SendAsync(request)
.ConfigureAwait(false);
response.EnsureSuccessStatusCode();
return await response
.Content
.ReadAsByteArrayAsync()
.ConfigureAwait(false);
}
}
Set up
var provider = new ServiceCollection()
.AddHttpClient()
.AddSingleton<MyFunkyService>()
.BuildServiceProvider();
Usage
// this would be injected
var myClient = provider.GetRequiredService<MyFunkyService>();
var result = await myClient.GetSomeFunkyThingAsync();
Note : there are many many more variations on how you could do this. However at least you are not learning the old and busted ways of doing things
Upvotes: 1
Reputation: 28549
It seems that the server is only serving requests that support compression. WebClient
doesn't support compression automatically. You can enable support for compression by inheriting your own class as described in this answer.
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
Then use MyWebClient
instead of WebClient
.
Upvotes: 0