C# 使用HttpWebRequest下载html页面会将ContentLength返回为-1

C# 使用HttpWebRequest下载html页面会将ContentLength返回为-1,c#,httpwebrequest,httpwebresponse,C#,Httpwebrequest,Httpwebresponse,我正试图从互联网上下载一些HTML文件,并使用HttpWebRequest来完成 但是当我使用 WebRequest.Create(“”); WebRequest.GetResponse() HttpWebResponse.ContentLength始终为-1。我必须显示这些页面下载的进度,在我们现有的VB6版本中,我们正在使用inet控件,它很好地报告了下载进度 我的代码与此非常相似: (即“下载”方法) 我不确定我做错了什么,也不确定这是否正常——web服务器没有发送内容长度的头。在这种情

我正试图从互联网上下载一些HTML文件,并使用HttpWebRequest来完成

但是当我使用

WebRequest.Create(“”); WebRequest.GetResponse()

HttpWebResponse.ContentLength始终为-1。我必须显示这些页面下载的进度,在我们现有的VB6版本中,我们正在使用inet控件,它很好地报告了下载进度

我的代码与此非常相似:

(即“下载”方法)

我不确定我做错了什么,也不确定这是否正常——web服务器没有发送内容长度的头。在这种情况下,我们如何计算进度

谢谢,

链接文章中Download()方法中的代码依赖于类中的私有成员,因此

WebRequest.Create("http://www.stackoverflow.com"); WebRequest.Create(“http://www.stackoverflow.com"); 可能会编译,它实际上是在类WebRequest上调用一个方法,然后丢弃结果,这是请求实际存储的地方。到排队的时候

WebRequest.GetResponse(); WebRequest.GetResponse(); 调用时,代码已经忘记了Create()的所有响应。(C#区分大小写,因此WebRequest和WebRequest不是一回事;将WebRequest命名为WebRequest类的实例是非常传统的做法。)

所以试着把这些线

private HttpWebRequest webRequest; private HttpWebResponse webResponse; 私有HttpWebRequest-webRequest; 私有HttpWebResponse-webResponse;
在类顶部的方法之外,作为WebRequest和WebResponse对象的实例。

如果web服务器不发送内容长度,则无法知道还有多少数据,因此基本上不可能知道您已经完成了多少

见鬼,服务器可能正在动态生成数据,但仍然不知道(当您获得数据的第一部分时)还要发送多少数据

任何声称显示进度(占完整下载大小的比例)的东西要么是在撒谎,要么是以不同的方式下载数据,这确实给了他们完整的大小。当然,如果你正在下载多个文件,你总是可以说出你已经下载了多少文件,还有多少文件需要下载(尽管即使在这种情况下,如果你正在使用爬虫式应用程序,后一个数字可能不知道)

请注意,一种常见的方法是显示一个进度条,该进度条指示“我正在取得进展”,但不尝试猜测还有多少内容需要下载。

以下是一个示例,您可以尝试:

class Program
{
    static void Main(string[] args)
    {
        var client = new WebClient();
        client.DownloadProgressChanged += (sender, e) =>
        {
            Console.WriteLine("{0}% completed", e.ProgressPercentage);
        };
        client.DownloadStringCompleted += (sender, e) =>
        {
            // e.Result contains downloaded string
            Console.WriteLine("finished downloading...");
        };
        client.DownloadStringAsync(new Uri("http://www.stackoverflow.com"));
        Console.ReadKey();
    }
}

如果您决定在WinForms应用程序中使用它,请确保从事件处理程序调用/pattern,因为它们不会在UI线程上执行。

Ah完全理解。谢谢你的解释:-)谢谢你的例子。有些服务器显示出进步,有些则没有,我发现对此没有什么可以做的:(