2009-06-02 112 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”,而不用提琴手捕捉。