.NET httpwebrequest.getResponse () HTTP 상태 코드 400 (불량 요청)이 반환 될 때 예외가 발생합니다.

StackOverflow https://stackoverflow.com/questions/692342

  •  22-08-2019
  •  | 
  •  

문제

서버에서 HTTP 400 코드를 얻을 때 서버가 내 요청에 무엇이 잘못되었는지 알려주는 완전히 합법적 인 방법입니다 (HTTP 응답 콘텐츠에서 메시지 사용).

그러나 .NET httpwebrequest는 상태 코드가 400 인 경우 예외를 제기합니다.

이것을 어떻게 처리합니까? 나에게 400은 완전히 합법적이며 오히려 도움이됩니다. HTTP 컨텐츠에는 몇 가지 중요한 정보가 있지만 예외는 저를 경로에서 벗어납니다.

도움이 되었습니까?

해결책

"비증제 코드를 던지는"방법이 꺼져 있으면 좋을 것입니다. 그러나 WebException을 포착하면 최소한 응답을 사용할 수 있습니다.

using System;
using System.IO;
using System.Web;
using System.Net;

public class Test
{
    static void Main()
    {
        WebRequest request = WebRequest.Create("http://csharpindepth.com/asd");
        try
        {
            using (WebResponse response = request.GetResponse())
            {
                Console.WriteLine("Won't get here");
            }
        }
        catch (WebException e)
        {
            using (WebResponse response = e.Response)
            {
                HttpWebResponse httpResponse = (HttpWebResponse) response;
                Console.WriteLine("Error code: {0}", httpResponse.StatusCode);
                using (Stream data = response.GetResponseStream())
                using (var reader = new StreamReader(data))
                {
                    string text = reader.ReadToEnd();
                    Console.WriteLine(text);
                }
            }
        }
    }
}

별도의 메소드에서 "성공 코드가 아니더라도 응답을 받으십시오"비트를 캡슐화하고 싶을 수도 있습니다. (응답이 없다면 여전히 던지는 것이 좋습니다. 예를 들어 연결할 수없는 경우).)

오류 응답이 클 수있는 경우 (비정상적) 조정할 수 있습니다. HttpWebRequest.DefaultMaximumErrorResponseLength 전체 오류가 발생하는지 확인하십시오.

다른 팁

나는 이것이 오래 전에 이미 대답을 받았다는 것을 알고 있지만, 나는이 질문에 오는 다른 사람들을 도울 확장 방법을 만들었습니다.

암호:

public static class WebRequestExtensions
{
    public static WebResponse GetResponseWithoutException(this WebRequest request)
    {
        if (request == null)
        {
            throw new ArgumentNullException("request");
        }

        try
        {
            return request.GetResponse();
        }
        catch (WebException e)
        {
            if (e.Response == null)
            {
                throw;
            }

            return e.Response;
        }
    }
}

용법:

var request = (HttpWebRequest)WebRequest.CreateHttp("http://invalidurl.com");

//... (initialize more fields)

using (var response = (HttpWebResponse)request.GetResponseWithoutException())
{
    Console.WriteLine("I got Http Status Code: {0}", response.StatusCode);
}

흥미롭게도 HttpWebResponse.GetResponseStream() 당신이 WebException.Response 서버에서받은 응답 스트림과는 다릅니다. 우리 환경에서 우리는 400 HTTP 상태 코드는 HttpWebRequest/HttpWebResponse 사물. 우리가 본 것에서와 관련된 응답 스트림 WebException's HttpWebResponse 클라이언트에서 생성되며 서버에서 응답 본문을 포함하지 않습니다. 우리는 고객에게 나쁜 요청의 이유를 고객에게 다시 메시지를 보내고 싶어서 매우 실망 스럽습니다.

Google의 OAUTH2 서비스에 연결하려고 할 때 비슷한 문제가있었습니다.

나는 다음과 같이 WebRequest를 사용하지 않고 수동으로 게시물을 작성하게되었습니다.

TcpClient client = new TcpClient("accounts.google.com", 443);
Stream netStream = client.GetStream();
SslStream sslStream = new SslStream(netStream);
sslStream.AuthenticateAsClient("accounts.google.com");

{
    byte[] contentAsBytes = Encoding.ASCII.GetBytes(content.ToString());

    StringBuilder msg = new StringBuilder();
    msg.AppendLine("POST /o/oauth2/token HTTP/1.1");
    msg.AppendLine("Host: accounts.google.com");
    msg.AppendLine("Content-Type: application/x-www-form-urlencoded");
    msg.AppendLine("Content-Length: " + contentAsBytes.Length.ToString());
    msg.AppendLine("");
    Debug.WriteLine("Request");
    Debug.WriteLine(msg.ToString());
    Debug.WriteLine(content.ToString());

    byte[] headerAsBytes = Encoding.ASCII.GetBytes(msg.ToString());
    sslStream.Write(headerAsBytes);
    sslStream.Write(contentAsBytes);
}

Debug.WriteLine("Response");

StreamReader reader = new StreamReader(sslStream);
while (true)
{  // Print the response line by line to the debug stream for inspection.
    string line = reader.ReadLine();
    if (line == null) break;
    Debug.WriteLine(line);
}

응답 스트림에 기록되는 응답에는 후에 특정 오류 텍스트가 포함되어 있습니다.

특히, 내 문제는 URL 인코딩 된 데이터 조각 사이에 엔드 라인을 넣고 있다는 것이었다. 내가 그들을 꺼내면 모든 것이 효과가있었습니다. 유사한 기술을 사용하여 서비스에 연결하고 실제 응답 오류 텍스트를 읽을 수 있습니다.

이것을 시도하십시오 (VB 코드 :-) :

Try

Catch exp As WebException
  Dim sResponse As String = New StreamReader(exp.Response.GetResponseStream()).ReadToEnd
End Try

확장 기능의 비동기 버전 :

    public static async Task<WebResponse> GetResponseAsyncNoEx(this WebRequest request)
    {
        try
        {
            return await request.GetResponseAsync();
        }
        catch(WebException ex)
        {
            return ex.Response;
        }
    }

이것은 나를 위해 해결했습니다.
https://gist.github.com/beccasaurus/929007/A8F820B153A1CFDEE3D06A9C0A1D7EBFCED8BB77

tl; dr :
문제:
LocalHost는 예상 컨텐츠를 반환하고 원격 IP는 400 컨텐츠를 "불량 요청"으로 변경합니다.
해결책:
첨가 <httpErrors existingResponse="PassThrough"></httpErrors> 에게 web.config/configuration/system.webServer 나를 위해 이것을 해결했다. 이제 모든 서버 (로컬 및 원격) IP 주소 및/또는 HTTP 코드 I에 관계없이 동일한 컨텐츠 (ME에 의해 생성)를 반환합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top