vb.net 当状态不是 200 时,如何从 Web 请求读取响应?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7146525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 15:40:17  来源:igfitidea点击:

How can I read the response from a web request when the Status is not 200?

vb.netwebexception

提问by Ruairi O'Brien

I am having difficulty getting the response text from a HTTP web request in vb.net when I get a web exception.

当我收到 Web 异常时,我很难从 vb.net 中的 HTTP Web 请求中获取响应文本。

This is the code I am doing it with.

这是我正在使用的代码。

Try
            myWebResponse = CType(request.GetResponse(), HttpWebResponse)
            myStreamReader = New StreamReader(myWebResponse.GetResponseStream())

            ResponseText = myStreamReader.ReadToEnd
            If myWebResponse.StatusCode = HttpStatusCode.Accepted Or myWebResponse.StatusCode = 200 Then
                SendResult = True 'Sent 
                SendStatus = 1 'message sent successfully
                Try
                    Integer.TryParse(myWebResponse.Headers("Number-Of-MT-PDU"), num_MT_PDU)
                Catch ex As Exception
                End Try
            Else
                SendStatus = 2 'message processed but not sent successfully
            End If
        Catch e As WebException
            If (e.Status = WebExceptionStatus.ProtocolError) Then
                Dim response As WebResponse = e.Response
                Using (response)
                    Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
                    statusCode = httpResponse.StatusCode
                    Try
                        myStreamReader = New StreamReader(response.GetResponseStream())
                        Using (myStreamReader)
                            ResponseText = myStreamReader.ReadToEnd & "Status Description = " & HttpWebResponse.StatusDescription
                        End Using
                    Catch ex As Exception
                        Logger.LogError(Me, ex)
                    End Try
                End Using

Annoyingly, the API I am contacting uses a 404 as a valid response. If I put the request in a browser some message text will be displayed. I want to be able to use that text in my program. I can not simply use the error code to determine actions as I don't think I can differentiate between a valid 404 response and an actual error.

令人讨厌的是,我正在联系的 API 使用 404 作为有效响应。如果我将请求放入浏览器,则会显示一些消息文本。我希望能够在我的程序中使用该文本。我不能简单地使用错误代码来确定操作,因为我认为我无法区分有效的 404 响应和实际错误。

In the code this line

在代码这一行

myWebResponse = CType(request.GetResponse(), HttpWebResponse)

throws an exception.

抛出异常。

In the exception I can get the 404 code and the description but not the response stream. It is always null.

在例外情况下,我可以获得 404 代码和描述,但不能获得响应流。它始终为空。

If I get a 200 response I get the text in the Response stream no problem.

如果我得到 200 响应,我在响应流中得到文本没问题。

In the web exception response object (in Visual Studios debugger) I have checked the headers and the object values and can't find the response text anywhere. If I stick the request URL in a browser I get response text back even though it is a 404.

在 Web 异常响应对象(在 Visual Studios 调试器中)中,我检查了标头和对象值,但在任何地方都找不到响应文本。如果我将请求 URL 粘贴到浏览器中,即使它是 404,我也会得到响应文本。

The raw response in fiddler:

fiddler 中的原始响应:

HTTP/1.1 404 Not Found Connection: close Content-Type: text/plain; charset=UTF-8 Content-Length: 35 "The response Message"

Any ideas on how I can get "The response Message" in my program? I have to use .Net on the server.

关于如何在我的程序中获得“响应消息”的任何想法?我必须在服务器上使用 .Net。

Thanks for any help anybody can give.

感谢任何人可以提供的任何帮助。

采纳答案by Mark Hurd

This LINQPad query works fine, dumping the HTML provided by my web server's "Not Found" error web page:

这个 LINQPad 查询工作正常,转储了我的网络服务器的“未找到”错误网页提供的 HTML:

Dim rq = System.Net.WebRequest.Create(New Uri("http://localhost/test"))
Try 
  Dim rs = rq.GetResponse
  rs.Dump
Catch Ex As System.Net.WebException
 Dim rs = Ex.Response
 Call (New StreamReader(rs.GetResponseStream)).ReadToEnd.Dump
End Try

FYI Your code works for me, except the presumed typo re HttpWebResponse.StatusDescription(and commenting out "unrelated stuff"), again as a LINQPad query (in .NET 4.0):

仅供参考,您的代码对我有用,除了假定的错字HttpWebResponse.StatusDescription(并注释掉“无关的东西”),再次作为 LINQPad 查询(在 .NET 4.0 中):

Dim request = WebRequest.Create("http://localhost/test")
Dim myStreamReader As StreamReader
Dim SendStatus As Integer = -1
Dim statusCode As HttpStatusCode
Dim ResponseText As String
Try
    Dim myWebResponse = CType(request.GetResponse(), HttpWebResponse)
        myStreamReader = New StreamReader(myWebResponse.GetResponseStream())

        ResponseText = myStreamReader.ReadToEnd
        If myWebResponse.StatusCode = HttpStatusCode.Accepted Or myWebResponse.StatusCode = 200 Then
            'SendResult = True 'Sent 
            SendStatus = 1 'message sent successfully
            'Try
            '    Integer.TryParse(myWebResponse.Headers("Number-Of-MT-PDU"), num_MT_PDU)
            'Catch ex As Exception
            'End Try
        Else
            SendStatus = 2 'message processed but not sent successfully
        End If
    Catch e As WebException
        If (e.Status = WebExceptionStatus.ProtocolError) Then
            Dim response As WebResponse = e.Response
            Using (response)
                Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
                statusCode = httpResponse.StatusCode
                Try
                    myStreamReader = New StreamReader(response.GetResponseStream())
                    Using (myStreamReader)
                        ResponseText = myStreamReader.ReadToEnd & "Status Description = " & httpResponse.StatusDescription ' HttpWebResponse.StatusDescription
                    End Using
                Catch ex As Exception
                    'Logger.LogError(Me, ex)
                    ex.Dump("Exception")
                End Try
            End Using
      End If
End Try
ResponseText.Dump("ResponseText")

I have also confirmed the above code (with the inferred Asclauses added and converting the .Dumpcalls to Console.WriteLine) works in .NET 2.0 with VB8.

我还确认了上面的代码(添加了推断的As子句并将.Dump调用转换为Console.WriteLine)在 .NET 2.0 和 VB8 中工作。

回答by Marvin

Note that the key is that even though the act of GetResponseStream() throws a .NET WebException, the HttpWebResponse is actually passed to the WebException object, so when in the Catch, you do a new GetResponseStream() on the WebException.Response object.

请注意,关键是即使 GetResponseStream() 的行为抛出了 .NET WebException,但 HttpWebResponse 实际上被传递给 WebException 对象,因此在 Catch 中时,您对 WebException.Response 对象执行新的 GetResponseStream()。

Below, very similar code for when in the Catch of the initial GetResponseStream()

下面,非常相似的代码在初始 GetResponseStream() 的 Catch 中

   Try 
            OriginalResponseStream = GetResponseStream(OriginalHTTPWebResponse)

   Catch wex as WebException
            Dim response As WebResponse = wex.Response
            Dim statusCode As HttpStatusCode
            Dim ResponseText As String

            Dim httpResponse As HttpWebResponse = CType(response, HttpWebResponse)
            statusCode = httpResponse.StatusCode

            Try

                Dim myStreamReader As New StreamReader(response.GetResponseStream())
                Using (myStreamReader)
                    ResponseText = myStreamReader.ReadToEnd
                    Process(ResponseText) '<===as in whatever you need to do with the response
                End Using
            Catch ex As Exception

                HandleIt(ex.Message) '<===as in whatever you want to do if Exception during the above

            End Try

   End Try