代码之家  ›  专栏  ›  技术社区  ›  Simon

VB6 HTTP请求到VB.Net 2.0的转换

  •  2
  • Simon  · 技术社区  · 17 年前

    我正在尝试将旧版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禁止-协议错误”: Using Response As HttpWebResponse = DirectCast(HTTPRequest.GetResponse(), HttpWebResponse) . VB6代码运行良好。有人能找出这两者之间可能导致这种情况的任何差异吗?这让我左右为难。。。。

    4 回复  |  直到 17 年前
        1
  •  2
  •   Peter Lange    17 年前

    当然,这只是一个猜测。

        2
  •  2
  •   steamer25    17 年前

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

    我先试试小提琴手 http://www.fiddler2.com/fiddler2/ 这是一个免费的HTTP调试代理。

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

        3
  •  1
  •   AnthonyWJones    17 年前

    试着这样做:-

    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这样的工具。

    应用程序

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

    启动fiddler并将enabled属性轻弹为“true”。现在,您应该看到新代码试图与ASP服务器进行的对话。确保在使用新代码之前设置enabled=“false”,而不使用fiddler捕获。

        4
  •  1
  •   Simon    17 年前

    在经历了很多痛苦之后,我终于设法让它工作了。问题在于文本编码,我已将其更改为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
    

    感谢所有帮助过我的人。全体投票。