.NET httpwebrequest.getResponse () HTTP 상태 코드 400 (불량 요청)이 반환 될 때 예외가 발생합니다.
-
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에 의해 생성)를 반환합니다.