HttpWebRequest仅能在.NET 4.0上运行。

5

我遇到了一个奇怪的问题,甚至是WebRequest的行为。首先,这是我正在尝试做的事情:

Dim req As HttpWebRequest = CType(Net.WebRequest.Create("https://cloud.myweb.de/myenginge/dostuff"), HttpWebRequest)

Dim inputString As String = "text=DoStuff"
Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes(inputString)

req.Method = "POST"
req.Accept = "application/xml;q=0.9,*/*;q=0.8"

req.ContentType = "application/x-www-form-urlencoded"
req.ContentLength = data.Length

str2 = req.GetRequestStream()

str2.Write(data, 0, data.Length)
str2.Close()

Dim resp As HttpWebResponse = CType(req.GetResponse, HttpWebResponse)
str = resp.GetResponseStream()
buffer = New IO.StreamReader(str, System.Text.Encoding.ASCII).ReadToEnd

但是,将.NET Framework 3.5设置为我的编译设置会导致以下操作超时:

str2 = req.GetRequestStream()

在设置框架版本为4.0时,一切都正常通过了,没有超时问题。有人知道这是为什么吗?我也尝试了3.0,但也不行。

(在本例中,我使用的是VB.NET,但C#解决方案也可以。)


2
使用类似 Fiddler 的工具来查看请求的差异。从技术上讲,如果请求完全相同,则远程服务器不应该知道差异以便能够以不同的方式响应。要么请求在某些细微的点上不同,要么不同的框架以两种不同的方式处理相同的响应。 - mellamokb
好的,我会先尝试使用 Fiddler。谢谢你的提示。 - inva
如果你将 req.Timeout 设置为比你经历的超时时间更长的值,那么会起作用吗?不过,使用 Fiddler 可以看到它是否真正发送请求以及是否存在任何差异,这点还是要给个赞。 - greg84
@mellamokb 我认为在你调用“GetResponseStream”之前,Fiddler不会显示任何内容?我现在不在我的电脑前进行测试。 - James
哦,我想我得更详细地了解一下 Fiddler … 如果我正在使用 Fiddler,那我使用哪个框架版本都无所谓,一切最终都会在 GetResponseStream 上以一个异常告诉我连接已关闭且发生了未知错误。(如果我使用的是 4.0 而没有 fiddler,则它可以正常工作,但在其中使用 fiddler 将使其无法正常工作) - inva
显示剩余6条评论
2个回答

2

我猜想您可能还有其他未处理的请求。在适用的情况下,请更新您的代码以使用 using 语句(在处理任何实现 IDisposable 的对象时应始终使用此语句)例如:

using (var stream = req.GetRequestStream())
{
    ...
}

在进行下一步操作之前,这将确保所有流都可靠地关闭。

更新

这绝不是切换.NET Framework的问题,我将您的代码隔离到一个小型控制台应用程序中,并按照以下方式重新编写了代码(显然将您的URL替换为另一个):

Dim request = CType(WebRequest.Create("https://cloud.myweb.de/myenginge/dostuff"), HttpWebRequest)
Dim data As Byte() = System.Text.Encoding.ASCII.GetBytes("text=DoStuff")
request.Method = WebRequestMethods.Http.Post
request.Accept = "application/xml;q=0.9,*/*;q=0.8"
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = data.Length
Using inputStream = request.GetRequestStream()
    inputStream.Write(data, 0, data.Length)
End Using

Dim response = CType(request.GetResponse(), HttpWebResponse)
Dim buffer As String = ""
Using outputStream = response.GetResponseStream()
    Using streamReader = New StreamReader(outputStream, System.Text.Encoding.ASCII)
        buffer = streamReader.ReadToEnd()
    End Using
End Using
Console.WriteLine(buffer)

每次请求我都得到了成功的响应。我在.NET 4.0和3.5下运行了相同的代码。以下是每个请求的样子,由Fiddler提供:

POST someurl HTTP/1.1
Accept: application/xml;q=0.9,/;q=0.8
Content-Type: application/x-www-form-urlencoded
Host: someurl
Content-Length: 12
Expect: 100-continue
Connection: Keep-Alive

text=DoStuff


我现在会尝试这个,实际上包装这样的东西通常是个好主意。但是正如我所说,使用版本4.0可以工作,但是低于4.0的版本都无法发送请求:( - inva
使用这个包装的想法并不能解决我的问题 - 我无法确定是否有任何未完成的请求。它只是执行上面显示的代码。此外,我使用了lock()语句(甚至在Vb.net中使用SyncLock),但这也没有帮助。 - inva
@inva 你可能需要再读一遍你最后的陈述哈哈。使用我更新答案的代码进行重写,看看是否解决了问题。你最初的代码会保留流(即使在异常结果上),这可能会导致线程池耗尽连接以提供服务。这个问题可能来自服务器吗?你对服务器端有控制权吗? - James
@James 我差点从椅子上摔下来了。 - Alex
啊,好的,那么在那种情况下我不确定它是否有效,我认为代理属性更适用于如果您有一个连接到网络的代理。如果您可以使用内部IP,我会选择使用它。 - James
显示剩余11条评论

0

我会使用ILSpy比较您的exe文件的IL代码。
也许在这个层面上的检查可以让您了解版本之间的差异。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接