0

除了 WebRequest 类之外,还有其他方法可以轻松地在 .NET 中发出 POST 请求吗?我有一个非常非常小的数据需要发布:

密码=密码

...但是 WebRequest 随机,我的意思是随机,在发布到我的服务器时丢弃数据。我已经通过使用我的服务器中将请求转储到控制台的一段代码对其进行了测试,我可以发现客户端有时会发送,有时不会发送 POST 数据。

在与 IIS 对话时,我使用的使用 WebRequest 的代码在另一个项目中工作。每次我通过 Firefox 向其发送数据时,与之交谈的服务器(另一个系统中的最小 Web 服务器)都会正确响应。我在同一个项目中有一个函数可以触发 GET 请求,并且可以正常工作。似乎我的 POST 函数没有完成交易......我过去在要求 WebRequest 处理小字符串时注意到的事情。

这是给我适合的代码。如果有任何 .NET 专家可以指出我的错误或建议另一个 Web 客户端,我将不胜感激。谢谢!

Private Function PostRequest(ByVal url As String, ByVal data As String) As String
    Return ControlFunctions.PostRequest(url, data, 0)
End Function

Private Function PostRequest(ByVal url As String, ByVal data As String, ByVal times As Integer) As String
    Dim req As HttpWebRequest = WebRequest.Create(url)
    Dim retval As String = ""

    req.Method = "POST"
    req.UserAgent = "TSControl"
    req.ContentType = "application/x-www-form-urlencoded"
    req.ContentLength = data.Length
    req.Headers.Add("Keep-Alive", "300")
    req.KeepAlive = True
    req.Timeout = 5000

    Try
        Dim DataStream As StreamWriter = New StreamWriter(req.GetRequestStream())
        DataStream.AutoFlush = True
        DataStream.Write(data)
        DataStream.Close()

        Dim sr As StreamReader = New StreamReader(req.GetResponse().GetResponseStream())
        retval = sr.ReadToEnd()
        sr.Close()
    Catch x As Exception
        If times < 5 Then
            Threading.Thread.Sleep(1000)
            times = times + 1
            ControlFunctions.PostRequest(url, data, times)
        Else
            ErrorMsg.Show("Could not post to server" + vbCrLf + x.Message + vbCrLf + x.StackTrace)
        End If
    End Try

    Return retval
End Function

- - 更新 - -

我不得不降低它来修复它,但幸运的是我过去曾涉足过 .NET 的套接字库:

Private Function PostRequest(ByVal url As String, ByVal data As String) As String
    Dim uri As New Uri(url)
    Dim read(16) As Byte
    Dim FullTime As New StringBuilder
    Dim PostReq As New StringBuilder
    Dim WebConn As New TcpClient

    PostReq.Append("POST ").Append(uri.PathAndQuery).Append(" HTTP/1.1").Append(vbCrLf)
    PostReq.Append("User-Agent: TSControl").Append(vbCrLf)
    PostReq.Append("Content-Type: application/x-www-form-urlencoded").Append(vbCrLf)
    PostReq.Append("Content-Length: ").Append(data.Length.ToString).Append(vbCrLf)
    PostReq.Append("Host: ").Append(uri.Host).Append(vbCrLf).Append(vbCrLf)
    PostReq.Append(data)

    WebConn.Connect(uri.Host, uri.Port)
    Dim WebStream As NetworkStream = WebConn.GetStream()
    Dim WebWrite As New StreamWriter(WebStream)

    WebWrite.Write(PostReq.ToString)
    WebWrite.Flush()

    Dim bytes As Integer = WebStream.Read(read, 0, read.Length)

    While bytes > 0
        FullTime.Append(Encoding.UTF8.GetString(read))
        read.Clear(read, 0, read.Length)
        bytes = WebStream.Read(read, 0, read.Length)
    End While

    ' Closes all the connections
    WebWrite.Close()
    WebStream.Close()
    WebConn.Close()

    Dim temp As String = FullTime.ToString()

    If Not temp.Length <= 0 Then
        Return temp
    Else
        Return "No page"
    End If
End Function
4

2 回答 2

2

如果您收到“分块”响应怎么办?你怎么解码它?

这就是我今天一整天都在挣扎的事情。如果我处理的是普通的 Web 服务,我不会太费劲,但是我正在制作一个读取 eBay 的 API 数据的应用程序,并且 eBay 有时会发送错误的块大小,这会使解码器破坏响应(即使你的解码器通过 HTTP 1.1 规则对其进行解码)。在尝试解码 eBay 的 BAD API 这么多小时后,我终于在 VB.net 中创建了一个解码分块 http 响应的函数,并且可以使用许多在线工具之一轻松将其转换为 C#。首先,如果响应内容类型被分块,则检查 HTTP 响应标头,如果是,只需将响应的主体传递给此函数,该函数通过引用获取变量并对其进行操作:

Public Shared Sub DechunkString(ByRef strString As String)
        Dim intChunkSize As Integer = 0
        Dim strSeperator(0) As String
        strSeperator(0) = vbCrLf

        Dim strChunks As String() = strString.Split(strSeperator, StringSplitOptions.RemoveEmptyEntries)

        strString = ""

        For Each strChunk As String In strChunks
            If strChunk.Length = intChunkSize Then ' for normal behaviour this would be enough
                strString &= strChunk
                intChunkSize = 0
                Continue For
            End If

            ' because of sometimes wrong chunk sizes let's check if the next chunk size is a valid hex, and if not, treat it as part chunk
            If strChunk.Length <= 4 Then ' this is probably a valid hex, but could have invalid characters
                Try
                    intChunkSize = CInt("&H" & strChunk.Trim())

                    If intChunkSize = 0 Then
                        Exit For
                    End If

                    Continue For
                Catch ex As Exception

                End Try
            End If

            ' if got to this point, then add the chunk to output and reset chunk size
            strString &= strChunk
            intChunkSize = 0
        Next
    End Sub

我只是希望它可以帮助一些人节省大量的时间和精力。

于 2011-08-26T09:08:27.177 回答
0

当您说“.net 丢弃数据”时,您是什么意思?

如果您只想发布一个名称值对,您可以按如下方式进行:

WebClient client = new WebClient();
NameValueCollection nv = new NameValueCollection();
nv.Add("password", "theword");
client.UploadValues(url, "POST", nv);

请注意,您可能必须检查传递给 UploadValues 的参数的顺序,我不确定这个顺序是否正确,并且现在懒得查找 MSDN。

于 2010-02-24T18:03:31.840 回答