我正在尝试调试a specific issue with my ASP.NET application。客户端运行以下代码:
void uploadFile( string serverUrl, string filePath )
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.
Create( serverUrl );
CredentialCache cache = new CredentialCache();
cache.Add( new Uri( serverUrl ), "Basic", new NetworkCredential( "User", "pass" ) );
request.Credentials = cache;
request.Method = "POST";
request.ContentType = "application/octet-stream";
request.Timeout = 60000;
request.KeepAlive = true;
using( BinaryReader reader = new BinaryReader(
File.OpenRead( filePath ) ) ) {
request.ContentLength = reader.BaseStream.Length;
using( Stream stream = request.GetRequestStream() ) {
byte[] buffer = new byte[1024];
while( true ) {
int bytesRead = reader.Read( buffer, 0, buffer.Length );
if( bytesRead == 0 ) {
break;
}
stream.Write( buffer, 0, bytesRead );
}
}
}
HttpWebResponse result = (HttpWebResponse)request.GetResponse();
//handle result - not relevant
}
和Write()
引发异常,“无法将数据写入传输连接:已建立的连接已被主机中的软件中止。”文本。我使用System.Net tracing时发现,当我使用Content-Length
设置发送请求时出现问题。
具体来说,如果我省略上面代码中using
语句内的所有内容,服务器会立即回复WWW-Authenticate
,然后客户端会使用WWW-Authenticate
重新发送请求,一切顺利,除了文件未上传,请求失败的时间很晚。
我想执行以下操作:发送没有数据的请求,等待WWW-Authenticate
,然后使用WWW-Authenticate
和数据重复该请求。所以我尝试修改上面的代码:首先设置所有参数,然后调用GetResponse()
,然后执行发送,但是当我尝试设置ContentLength
属性时,抛出异常“此属性无法设置写完后已开始“文字。
所以HttpWebRequest
似乎是不可重用的。
如何重新发送请求而不关闭连接?
答案 0 :(得分:16)
您不会重复使用请求 - 顾名思义,这是一个请求。但是,如果您为同一主机发出多个请求,则默认情况下.NET将重用基础网络连接。
请注意,您执行需要处理WebResponse
返回的request.GetResponse
- 否则底层基础架构将无法知道您实际已完成此操作,并且将无法重复使用该连接。
(顺便说一下,你为什么要使用BinaryReader
?直接使用File.OpenRead
返回的流。)
答案 1 :(得分:2)
除了Jon Skeet的回答之外,您无需手动设置ContentLength属性。 HttpWebRequest将自动计算并填充该属性。