将VB6 HTTP请求转换为VB.Net 2.0

时间:2009-06-02 15:30:56

标签: .net vb.net vb6 httpwebrequest

我正在尝试将旧版VB6组件(不是我编写的)更新到.NET平台。有一个函数可以将XML字符串发布到URL:

Function PostToUrl(ByRef psUrl, ByRef psData, Byref psResponseText, ByRef psErrorMsg, ByRef psUsername, ByRef psPassword)

    On Error Resume Next    
    Dim objWinHTTP

    PostToUrl = False
    psErrorMsg = ""
    psResponseText = ""
    Dim m_lHTTPREQUEST_SETCREDENTIALS_FOR_SERVER
    m_lHTTPREQUEST_SETCREDENTIALS_FOR_SERVER    =0  

    Set objWinHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")


    objWinHTTP.Open "POST", psUrl

    If psUsername <> "" Then
        Call objWinHTTP.SetCredentials(psUsername, psPassword, m_lHTTPREQUEST_SETCREDENTIALS_FOR_SERVER)
    End If
    objWinHTTP.SetRequestHeader "Host", "http://www.xxx.com/CSIHTTP.asp"
    objWinHTTP.SetRequestHeader "X-Method", "Submit"
    objWinHTTP.SetRequestHeader "Content-Type", "text/xml"

    objwinHTTP.setTimeouts 3000, 15000, 15000, 120000


    Call objWinHTTP.Send(psData)

    ' Handle errors  '


    If Err.Number <> 0 Then

        psErrorMsg = Err.Description & " test"
        PostToUrl = False

    ElseIf objWinHTTP.Status <> 200 AND objWinHTTP.Status <> 202 Then

        psErrorMsg = "(" & objWinHTTP.Status & ") " & objWinHTTP.StatusText
        PostToUrl = False

    Else

        psErrorMsg = objWinHTTP.ResponseText & "(" & objWinHTTP.Status & ") " & objWinHTTP.StatusText
        PostToUrl = True

    End If

    Set objWinHTTP = Nothing
End Function

我已将此更新为:

Public Function PostXml(ByVal XML As String) As Boolean

        Try
            Dim URL As String = My.Settings.NTSPostURL 
            'TODO: supply username and password!  '
            Dim Bytes As Byte() = Me.Encoding.GetBytes(XML)
            Dim HTTPRequest As HttpWebRequest = DirectCast(WebRequest.Create(Me.PostURL), HttpWebRequest)
            Dim Cred As New NetworkCredential("username", "password", "http://www.xxx.com")

            With HTTPRequest
                .Method = "POST"
                .ContentLength = Bytes.Length
                .ContentType = "text/xml"
                .Credentials = Cred
                .Timeout = 120000
                .Method = "Submit"
            End With

            Using RequestStream As Stream = HTTPRequest.GetRequestStream()
                RequestStream.Write(Bytes, 0, Bytes.Length)
                RequestStream.Close()
            End Using

            Using Response As HttpWebResponse = DirectCast(HTTPRequest.GetResponse(), HttpWebResponse)

                If Response.StatusCode <> HttpStatusCode.OK Then

                    Dim message As String = [String].Format("POST failed. Received HTTP {0}", Response.StatusCode)

                    Throw New ApplicationException(message)

                End If

            End Using

        Catch ex As WebException
            Dim s As String = ex.Response.ToString() & " " & ex.Status.ToString()
            Throw
        End Try

    End Function

但是当我运行.NET代码时,服务器返回错误'403 Forbidden - protocol error': Using Response As HttpWebResponse = DirectCast(HTTPRequest.GetResponse(), HttpWebResponse) 。 VB6代码运行正常。任何人都可以发现两者之间可能造成这种差异的任何差异吗?这让我很难过......

4 个答案:

答案 0 :(得分:2)

看起来你没有在.net版本中设置HOST标头,除非我错过它。如果您的服务器使用HostHeaderResolution在同一个IP地址上托管多个域,那么您将获得403.

这当然是一个疯狂的猜测。

答案 1 :(得分:2)

您是否尝试从两个来源捕获流量并进行比较?

我首先尝试Fiddler http://www.fiddler2.com/fiddler2/这是一个免费的HTTP调试代理。

如果这不起作用,你可以尝试使用WireShark这是一个免费的协议分析器(稍低一点,所以会有很多细节要过滤掉)。 http://www.wireshark.org/

答案 2 :(得分:1)

我认为您没有正确排序凭据。您正在使用URL的权限部分作为凭据域。

试试这样: -

Dim myCache as New CredentialCache()
myCache.Add(New Uri("http://www.xxx.com"), "Basic", New NetworkCredential("username", "password"))

HTTPRequest.Credentials = myCache

这假设需要基本身份验证,另一个竞争者是“摘要”或“NTLM”,可能需要域。例如,如果用户名的文本在旧代码中就像这个“域\用户名”那么你会想要: -

Dim myCache as New CredentialCache()
myCache.Add(New Uri("http://www.xxx.com"), "NTLM", New NetworkCredential("username", "password", "domain"))

HTTPRequest.Credentials = myCache
顺便说一下,我同意steamer25,对于这类事情,你真的需要一个像提琴手这样的工具。

如果你在这个代码运行的机器上有一个老东西工作场所fiddler的例子。启动fiddler并使用命令proxycfg -u。现在,您可以观察原始内容与ASP服务器的对话。在关闭fiddler之前使用proxycfg -d。

现在,在您的.NET代码中,将以下内容放在 app .config中: -

<system.net>
    <defaultProxy enabled="false">
        <proxy proxyaddress="http://127.0.0.1:8888" bypassonlocal="False"/>
    </defaultProxy>
</system.net>

启动fiddler并将enabled属性设置为“true”。现在您应该看到新代码尝试与ASP Server进行的对话。在使用没有fiddler捕获的新代码之前,请确保设置enabled =“false”。

答案 3 :(得分:1)

经过多次痛苦,我终于成功了。问题在于文本编码,我已将其更改为ASCII并且一切正常:

Try
            Dim Bytes As Byte() = Me.Encoding.GetBytes(XML)
            Dim HTTPRequest As HttpWebRequest = DirectCast(WebRequest.Create(Me.PostURL), HttpWebRequest)

            With HTTPRequest
                .Method = "POST"
                .ContentLength = Bytes.Length
                .ContentType = "text/xml"
                .Credentials = New NetworkCredential("user", "password") 'myCache
            End With

            Using RequestStream As Stream = HTTPRequest.GetRequestStream()
                RequestStream.Write(Bytes, 0, Bytes.Length)
                RequestStream.Close()
            End Using

            Using Response As HttpWebResponse = DirectCast(HTTPRequest.GetResponse(), HttpWebResponse)

                Return Response.StatusCode

            End Using

        Catch ex As WebException
            Dim s As String = ex.Status.ToString
            Throw
        End Try

感谢所有帮助过的人。全面提升。