[英]WebClient is not following redirects in .Net Core 3.1
I try to download a file with a URL that returns a 307 redirect code.我尝试使用返回 307 重定向代码的 URL 下载文件。
I tried using the WebClient.DownloadFile
method, but it seems to not follow the redirects of the requested site.我尝试使用
WebClient.DownloadFile
方法,但它似乎没有遵循所请求站点的重定向。 The stuff i found by searching for this issue either says it should work (Microsoft docs) or does not really answer my questions: WebClient Does not automatically redirect我通过搜索这个问题找到的东西要么说它应该可以工作(微软文档),要么没有真正回答我的问题: WebClient 不会自动重定向
My first question here is why is it not following the redirect, even if the HttpWebRequest it uses has AllowAutoRedirect=true
?我的第一个问题是为什么它不遵循重定向,即使它使用的 HttpWebRequest 具有
AllowAutoRedirect=true
?
My second question is how to best implement a function which downloads a file with automatic redirects.我的第二个问题是如何最好地实现 function 下载具有自动重定向的文件。
An example URL i'm using would be: https://api.spiget.org/v2/resources/10905/download我正在使用的示例 URL 是: https://api.spiget.org/v2/resources/10905/download
But this URL is not allways redirecting, depending on some internal API states i guess.但是这个 URL 并不总是重定向,这取决于我猜的一些内部 API 状态。
Here's a simple example with HttpClient
这是一个使用
HttpClient
的简单示例
.NET Core 3.1 Console app ( UPD: added progress reporting) .NET Core 3.1控制台应用程序( UPD:添加进度报告)
class Program
{
private static readonly HttpClient client = new HttpClient(new HttpClientHandler() { AllowAutoRedirect = true });
static async Task Main(string[] args)
{
try
{
IProgress<int> progress = new Progress<int>(p =>
{
Console.Write(p + " ");
});
await DownloadAndSaveFileAsync("https://api.spiget.org/v2/resources/10905/download", progress);
Console.WriteLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("Done.");
Console.ReadKey();
}
private static async Task DownloadAndSaveFileAsync(string url, IProgress<int> progress)
{
using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.EnsureSuccessStatusCode(); // throw if not success
string fileName = response.Content.Headers.ContentDisposition?.FileName ?? throw new Exception("Nothing to download");
fileName = fileName.Trim('\"'); // remove quotes
long contentLength = response.Content.Headers.ContentLength ?? 0;
Console.WriteLine("File: {0}", fileName);
Console.WriteLine("Content-Length: {0} bytes", contentLength);
using Stream responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using FileStream fileStream = File.Create(fileName);
int bufferSize = 65536;
byte[] buffer = new byte[bufferSize];
int bytesRead;
long position = 0;
int storedPercentage = -1;
while ((bytesRead = await responseStream.ReadAsync(buffer, 0, bufferSize)) > 0)
{
await fileStream.WriteAsync(buffer, 0, bufferSize);
if (contentLength > 0)
{
position += bytesRead;
int percentage = (int)(position * 100 / contentLength);
if (percentage != storedPercentage)
{
progress?.Report(percentage);
storedPercentage = percentage;
}
}
}
}
}
Console output控制台 output
File: [1.8 TO 1.16] Ultra Cosmetics [OPENSOURCE & FREE!!]#10905.jar
Content-Length: 1692542 bytes
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 73 72 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
Done.
File downloaded successfully.文件下载成功。
Compared byte-by-byte with downloaded in browser.逐字节与在浏览器中下载的比较。 Files are idential.
文件是相同的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.