问题描述
我正在尝试从
下载图像http://aplweb.soriana.com/foto/fotolib/14/7503003936114/7503003936114-01-01-01.jpg
使用 WebClient。
网址以 .jpg 结尾,但图片为 .WEBP 格式。
using (WebClient wb = new WebClient())
{
wb.DownloadFile("http://aplweb.soriana.com/foto/fotolib//14/7503003936114/7503003936114-01-01-01.jpg","image.jpg");
}
我已经尝试过 .DownloadData()、asyng 方法、HttpClient、WebRequest 直接。.. 我总是遇到同样的错误。
有什么想法吗?
解决方法
您的代码很好,但这是特定于服务器的行为。添加一些请求标头可解决此问题。
这是一个使用 HttpClient
class Program
{
private static readonly HttpClient client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate });
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");
client.DefaultRequestHeaders.AcceptEncoding.ParseAdd("gzip,deflate");
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);
}
}
}
控制台输出
Downloading...
Saving...
OK.
下载的图片
,您的问题与标题有关。但是,让我们从正确的轨道开始,教您使用 DI、服务 和 IHttpClientFactory
发出 Http 请求的一种更现代的方法。>
服务
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,*/*;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);
}
}
设置
var provider = new ServiceCollection()
.AddHttpClient()
.AddSingleton<MyFunkyService>()
.BuildServiceProvider();
使用
// this would be injected
var myClient = provider.GetRequiredService<MyFunkyService>();
var result = await myClient.GetSomeFunkyThingAsync();
注意:关于如何做到这一点,还有更多变化。然而,至少你没有学习旧的和被破坏的做事方式
,服务器似乎只为支持压缩的请求提供服务。 WebClient
不支持自动压缩。您可以通过继承您自己的类来启用对压缩的支持,如 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;
}
}
然后使用 MyWebClient
而不是 WebClient
。