답변:
"성공하지 않은 코드에서 발생"을 해제하는 방법이 있다면 좋을 것입니다. 그러나 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);
}
WebException.Response
할 수 있습니다 null
. 이 경우 다시 던져야합니다.
HttpClient
대신 대신 사용해야 하고 훨씬 더 구성 가능하며 미래의 방법이라고 생각합니다.
((WebRequest) null).GetResponseWithoutException()
는에 NullReferenceException
해당하는로 컴파일되기 때문에 실제로는을 유발 WebRequestExtensions.GetResponseWithoutException(null)
하지 NullReferenceException
않으므로 입력 유효성 검사가 필요 하지 않습니다 .
흥미롭게도 HttpWebResponse.GetResponseStream()
얻는 WebException.Response
것은 서버에서받은 응답 스트림과 동일하지 않습니다. 우리 환경에서는 400 HTTP 상태 코드가 HttpWebRequest/HttpWebResponse
객체를 사용하여 클라이언트에 다시 반환 될 때 실제 서버 응답이 손실 됩니다. 우리가 본 것에서,와 관련된 응답 스트림 WebException's HttpWebResponse
은 클라이언트에서 생성되며 서버의 응답 본문을 포함하지 않습니다. 잘못된 요청의 이유를 고객에게 다시 메시지로 보내려고하므로 매우 실망 스럽습니다.
Google OAuth2 서비스에 연결하려고 할 때 비슷한 문제가 발생했습니다.
다음과 같이 WebRequest를 사용하지 않고 수동으로 POST를 작성했습니다.
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 인코딩 된 데이터 조각 사이에 끝을 두는 것입니다. 내가 꺼내면 모든 것이 효과가있었습니다. 유사한 기술을 사용하여 서비스에 연결하고 실제 응답 오류 텍스트를 읽을 수 있습니다.
이것은 나를 위해 그것을 해결했다.
https://gist.github.com/beccasaurus/929007/a8f820b153a1cfdee3d06a9c0a1d7ebfced8bb77
TL; DR :
문제 :
localhost가 예상 된 컨텐츠를 리턴하고 원격 IP가 400 개의 컨텐츠를 "잘못된 요청"으로 변경합니다.
솔루션 : 이 문제 를 해결하기 위해
추가 ; 이제 모든 서버 (로컬 및 원격)는 내가 반환하는 IP 주소 및 / 또는 HTTP 코드에 관계없이 정확히 동일한 내용 (내가 생성 한)을 반환합니다.<httpErrors existingResponse="PassThrough"></httpErrors>
web.config/configuration/system.webServer