使用HttpWebRequest上传带有PUT的文件时出错

时间:2009-04-09 14:04:13

标签: c# networking

我们有一个.NET 2.0 WinForms应用程序需要通过WebDav将文件上传到IIS6服务器。我们不时会收到来自远程办公室的投诉,他们会收到以下错误消息之一

  • 基础连接已关闭: 发送时发生意外错误。
  • 基础连接已关闭: 发生意外错误 接收。

这似乎只发生在大文件(~20Mb plus)上。我用家用电脑上的40Mb文件对它进行了测试,并尝试将'Sleep'置于循环中以模拟慢速连接,因此我怀疑它是在网络问题结束时...但是

  1. 远程办公室的IT人员没有帮助
  2. 我想排除我的代码有问题的可能性。
  3. 所以 - 任何人都可以发现任何错误或建议任何可能“防止”代码解决此问题的变通办法。谢谢你的帮助。切碎版本的代码如下:

        public bool UploadFile(string localFile, string uploadUrl)
        {
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uploadUrl);
    
            try
            {
                req.Method = "PUT";
                req.AllowWriteStreamBuffering = true;
                req.UseDefaultCredentials = Program.WebService.UseDefaultCredentials;
                req.Credentials = Program.WebService.Credentials;
                req.SendChunked = false;
                req.KeepAlive = true;
                Stream reqStream = req.GetRequestStream();
                FileStream rdr = new FileStream(localFile, FileMode.Open, FileAccess.Read);
                byte[] inData = new byte[4096];
                int bytesRead = rdr.Read(inData, 0, inData.Length);
    
                while (bytesRead > 0)
                {
                    reqStream.Write(inData, 0, bytesRead);
                    bytesRead = rdr.Read(inData, 0, inData.Length);
                }
    
                reqStream.Close();
                rdr.Close();
    
                System.Net.HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                if (response.StatusCode != HttpStatusCode.OK && response.StatusCode!=HttpStatusCode.Created)
                {
                    MessageBox.Show("Couldn't upload file");
                    return false;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                return false;
            }
            return true;
        }
    

6 个答案:

答案 0 :(得分:6)

尝试将KeepAlive设为false:

req.KeepAlive = false;

这将允许关闭连接并再次打开。它不允许使用persistent connection。我发现网上有很多引用,以便解决类似于你的错误。这是一个相关的link

无论如何,使用HTTP PUT(或HTTP POST)上传大文件并不是一个好主意。最好使用FTP或下载/上传管理器。这些将自动处理重试,连接问题,超时。上传速度也会更快,您也可以恢复停止上传。如果您决定继续使用HTTP,则至少应尝试添加重试机制。如果上传时间过长,则很可能会因代理,服务器超时,防火墙或任何理由不对您的代码而失败。

答案 1 :(得分:5)

要消除代码中存在错误的风险,请尝试使用WebClient

using (WebClient client = new WebClient())
{
    client.UseDefaultCredentials = Program.WebService.UseDefaultCredentials;
    client.Credentials = Program.WebService.Credentials;
    client.UploadFile(uploadUrl, "PUT", localFile);
}

答案 2 :(得分:1)

也许尝试使用POST,但真正的罪魁祸首可能是内容类型。

尝试设置

req.ContentType = "application/octet-stream";
req.ContentLength = inData.Length;

或查看接受的答案中的代码:Upload files with HTTPWebrequest (multipart/form-data)

我的示例和我提供的链接都涉及修改ContentType - 我的示例更简单但可能不起作用,因为大多数接收文件的应用程序都期望多部分

答案 3 :(得分:1)

请检查IIS管理器的[网站]选项卡上是否设置了[启用Http Keep-Alives]。

答案 4 :(得分:0)

上传的大小可能有限。

请参阅此处进行一次讨论: http://www.codeproject.com/KB/aspnet/uploadlargefilesaspnet.aspx

答案 5 :(得分:0)

首先检查一些基本配置。以下任一项的默认值可能会导致文件上载出现问题 - 包括终止连接。我相信IIS 6永远不会允许文件上传> 2GB(即使它可以完成,无论配置如何)。 Msdn describes these nicely

<httpRuntime executionTimeout = "30"  maxRequestLength="200"/>

编辑:当然,这是ASP.NET配置,它假定您在ASP.NET中运行自己的webdav服务器或3rd party server。如果它是一个不同的webdav服务器,您将需要查找等效服务器。