2009-06-02 111 views
2

我試圖將傳統的VB6組件(不是我寫的)更新到.NET平臺。有哪些職位的XML字符串的URL一個功能:將VB6 HTTP請求轉換爲VB.Net 2.0

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代碼運行良好。任何人都可以找出兩者之間可能造成這種差異的任何差異嗎?這是讓我難倒....

+0

它不容易移植那些低質量的東西開始。你確定你不想分析更多功能級別的組件並在.NET中實現新鮮事嗎? – AnthonyWJones 2009-06-02 18:45:21

+0

絕對!我深入研究這個VB6函數的唯一原因是,我無法運行.Net代碼! – Simon 2009-06-03 10:36:38

回答

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 

感謝所有誰幫助。全面贊成。

2

看起來你不喜歡你設置一個HOST頭int他.net版本,除非我想念它。如果您的服務器使用HostHeaderResolution在相同的IP地址上託管多個域,那麼您將得到一個403.

這當然是一個瘋狂的猜測。

2

您是否嘗試過捕獲來自兩個來源的流量並對它們進行比較?

我想先試試Fiddler http://www.fiddler2.com/fiddler2/這是一個免費的HTTP調試代理。

如果這不起作用,你可以嘗試WireShark這是一個免費的協議分析儀(稍低一點,所以會有很多細節過濾掉)。 http://www.wireshark.org/

1

我不認爲你已經正確排序了Credential事物。您正在使用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 

BTW,我同意steamer25,對於這樣的事情你真的需要一個工具如小提琴手。

如果您在運行此代碼的計算機上有一箇舊東西工作地點提琴手的示例。啓動fiddler並使用命令proxycfg -u。現在您可以觀察原始資料與ASP服務器之間的通話了。在關閉fiddler之前使用proxycfg -d。

現在在你的.NET代碼的地方在應用的.config如下: -

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

開始提琴手和輕彈enabled屬性爲 「true」。現在你應該看到你的新代碼試圖與ASP服務器進行對話。在使用新代碼之前,請確保你設置了enabled =「false」,而不用提琴手捕捉。