WebClient 不遵循 .Net Core 3.1 中的重定向

WebClient is not following redirects in .Net Core 3.1

我尝试下载一个 URL 的文件 returns 一个 307 重定向代码。

我尝试使用 WebClient.DownloadFile 方法,但它似乎不遵循所请求站点的重定向。我通过搜索这个问题找到的东西要么说它应该工作(Microsoft 文档)要么没有真正回答我的问题:WebClient Does not automatically redirect

我的第一个问题是为什么它不遵循重定向,即使它使用的 HttpWebRequest AllowAutoRedirect=true?

我的第二个问题是如何最好地实现使用自动重定向下载文件的功能。

我使用的示例 URL 是:https://api.spiget.org/v2/resources/10905/download
但是这个 URL 并不总是重定向,我猜这取决于一些内部 API 状态。

这是一个简单的例子 HttpClient

.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;
                }
            }
        }
    }
}

控制台输出

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.

文件下载成功。

与在浏览器中下载的 byte-by-byte 相比。文件相同。