HttpWebRequest.GetResponse () 실패시 오류 정보를 얻는 방법


86

HttpWebRequest를 시작한 다음 응답을 검색하고 있습니다. 때때로 500 (또는 적어도 5 ##) 오류가 발생하지만 설명이 없습니다. 두 끝점을 모두 제어 할 수 있으며 수신 측에서 더 많은 정보를 얻고 싶습니다. 예를 들어 서버에서 클라이언트로 예외 메시지를 전달하고 싶습니다. HttpWebRequest 및 HttpWebResponse를 사용하여 가능합니까?

암호:

try
{
    HttpWebRequest webRequest = HttpWebRequest.Create(URL) as HttpWebRequest;
    webRequest.Method = WebRequestMethods.Http.Get;
    webRequest.Credentials = new NetworkCredential(Username, Password);
    webRequest.ContentType = "application/x-www-form-urlencoded";
    using(HttpWebResponse response = webRequest.GetResponse() as HttpWebResponse)
    {
        if(response.StatusCode == HttpStatusCode.OK)
        {
            // Do stuff with response.GetResponseStream();
        }
    }
}
catch(Exception ex)
{
    ShowError(ex);
    // if the server returns a 500 error than the webRequest.GetResponse() method
    // throws an exception and all I get is "The remote server returned an error: (500)."
}

이것에 대한 도움을 많이 주시면 감사하겠습니다.

답변:


151

HttpWebRequest 및 HttpWebResponse를 사용하여 가능합니까?

웹 서버에서 예외 텍스트를 포착하여 응답 본문에 기록한 다음 상태 코드를 500으로 설정할 수 있습니다. 이제 클라이언트는 500 오류가 발생하면 예외를 throw하지만 응답 스트림을 읽고 가져올 수 있습니다. 예외 메시지.

따라서 서버에서 200이 아닌 상태 코드가 반환되고 본문을 읽을 경우 발생 하는 WebException 을 포착 할 수 있습니다.

catch (WebException ex)
{
    using (var stream = ex.Response.GetResponseStream())
    using (var reader = new StreamReader(stream))
    {
        Console.WriteLine(reader.ReadToEnd());
    }
}
catch (Exception ex)
{
    // Something more serious happened
    // like for example you don't have network access
    // we cannot talk about a server exception here as
    // the server probably was never reached
}

감사합니다! WebResponse의 disposer가이를 지우므로 using 문 내부의 스트림을 using 문 외부에서 사용할 수 없다는 점에 유의해야합니다. 이것은 몇 분 동안 나를 넘어 뜨렸다.
Thorin

@Thorin. 첫 번째 명령문의 "스트림"은 다음 명령문으로 이어집니다. 한 줄의 IF 문처럼, 예를 들어 if (something) do-stuff-here;
RealityDysfunction

1
GetRequestStream그리고 GetResponse던질 수있는 예외를 ?
PreguntonCojoneroCabrón

@ PreguntonCojoneroCabrón 네, 옳지 않은 것 같습니다. 고맙게도 Microsoft는 요즘 대부분이 사용하고 있다고 생각하는 HttpClient 클래스를 도입했습니다. msdn.microsoft.com/en-us/library/…
Morten Nørgaard

8

FTP 사이트에 파일이 있는지 확인하려고 할 때이 질문을 보았습니다. 파일이 존재하지 않으면 타임 스탬프를 확인하려고 할 때 오류가 발생합니다. 그러나 유형을 확인하여 오류가 다른 것이 아닌지 확인하고 싶습니다.

Response속성 은 어떤 FTP 오류가 있는지 확인하기 위해 속성을 확인할 수있는 WebException유형 FtpWebResponse입니다 .StatusCode

내가 끝낸 코드는 다음과 같습니다.

    public static bool FileExists(string host, string username, string password, string filename)
    {
        // create FTP request
        FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://" + host + "/" + filename);
        request.Credentials = new NetworkCredential(username, password);

        // we want to get date stamp - to see if the file exists
        request.Method = WebRequestMethods.Ftp.GetDateTimestamp;

        try
        {
            FtpWebResponse response = (FtpWebResponse)request.GetResponse();
            var lastModified = response.LastModified;

            // if we get the last modified date then the file exists
            return true;
        }
        catch (WebException ex)
        {
            var ftpResponse = (FtpWebResponse)ex.Response;

            // if the status code is 'file unavailable' then the file doesn't exist
            // may be different depending upon FTP server software
            if (ftpResponse.StatusCode == FtpStatusCode.ActionNotTakenFileUnavailable)
            {
                return false;
            }

            // some other error - like maybe internet is down
            throw;
        }
    }

4

비슷한 상황에 직면했습니다.

BasicHTTPBinding을 사용하여 SOAP 서비스를 사용하는 HTTP 오류의 경우 원시 응답을 읽으려고했습니다.

그러나를 사용하여 응답을 읽을 때 GetResponseStream()오류가 발생했습니다.

스트림을 읽을 수 없음

그래서이 코드는 저에게 효과적이었습니다.

try
{
    response = basicHTTPBindingClient.CallOperation(request);
}
catch (ProtocolException exception)
{
    var webException = exception.InnerException as WebException;
    var rawResponse = string.Empty;

    var alreadyClosedStream = webException.Response.GetResponseStream() as MemoryStream;
    using (var brandNewStream = new MemoryStream(alreadyClosedStream.ToArray()))
    using (var reader = new StreamReader(brandNewStream))
        rawResponse = reader.ReadToEnd();
}

0

이 라이브러리를 사용할 수도 있습니다.HttpWebRequest 및 Response를 결과에 따라 개체를 반환하는 간단한 메서드로 래핑 를 . 이 답변에 설명 된 기술 중 일부를 사용하며 this 및 유사한 스레드의 답변에서 영감을 얻은 많은 코드가 있습니다. 모든 예외를 자동으로 포착하고 이러한 웹 요청을 가능한 한 많이 생성하는 데 필요한 상용구 코드를 추상화하고 응답 객체를 자동으로 역 직렬화합니다.

이 래퍼를 사용하는 코드의 예는 다음과 같이 간단합니다.

    var response = httpClient.Get<SomeResponseObject>(request);
    
    if(response.StatusCode == HttpStatusCode.OK)
    {
        //do something with the response
        console.Writeline(response.Body.Id); //where the body param matches the object you pass in as an anonymous type.  
    }else {
         //do something with the error
         console.Writelint(string.Format("{0}: {1}", response.StatusCode.ToString(), response.ErrorMessage);

    }

전체 공개이 라이브러리는 무료 오픈 소스 래퍼 라이브러리이며 저는 해당 라이브러리의 작성자입니다. 나는 이것으로 돈을 벌지 못하지만 수년에 걸쳐 매우 유용하다는 것을 알았으며 HttpWebRequest / HttpWebResponse 클래스를 여전히 사용하는 사람도 그렇게 될 것이라고 확신합니다.

은색 총알은 아니지만 get 및 post뿐만 아니라 JSON 또는 XML 요청 및 응답에 대해 비동기 및 비 비동기 모두를 사용하여 가져 오기, 게시, 삭제를 지원합니다. 2020 년 6 월 21 일 현재 적극적으로 유지 보수 중입니다.


-3
HttpWebRequest myHttprequest = null;
HttpWebResponse myHttpresponse = null;
myHttpRequest = (HttpWebRequest)WebRequest.Create(URL);
myHttpRequest.Method = "POST";
myHttpRequest.ContentType = "application/x-www-form-urlencoded";
myHttpRequest.ContentLength = urinfo.Length;
StreamWriter writer = new StreamWriter(myHttprequest.GetRequestStream());
writer.Write(urinfo);
writer.Close();
myHttpresponse = (HttpWebResponse)myHttpRequest.GetResponse();
if (myHttpresponse.StatusCode == HttpStatusCode.OK)
 {
   //Perform necessary action based on response
 }
myHttpresponse.Close(); 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.