source

웹 클라이언트에서 상태 코드를 가져오는 방법은 무엇입니까?

factcode 2023. 5. 24. 22:26
반응형

웹 클라이언트에서 상태 코드를 가져오는 방법은 무엇입니까?

사용 중입니다.WebClient일부 데이터를 웹 양식에 게시하는 클래스입니다.양식 제출의 응답 상태 코드를 받고 싶습니다.지금까지 예외가 있을 경우 상태 코드를 가져오는 방법을 알아냈습니다.

Catch wex As WebException
        If TypeOf wex.Response Is HttpWebResponse Then
          msgbox(DirectCast(wex.Response, HttpWebResponse).StatusCode)
            End If

그러나 양식이 성공적으로 제출되고 예외가 발생하지 않으면 상태 코드(200,301,302, ...)를 알 수 없습니다.

예외가 발생하지 않을 때 상태 코드를 얻을 수 있는 방법이 있습니까?

PS: httpwebrequest/httpweb 응답을 사용하지 않는 것을 선호합니다.

오류가 유형인지 확인할 수 있습니다.WebException응답 코드를 검사합니다.

if (e.Error.GetType().Name == "WebException")
{
   WebException we = (WebException)e.Error;
   HttpWebResponse response = (System.Net.HttpWebResponse)we.Response;
   if (response.StatusCode==HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

또는

try
{
    // send request
}
catch (WebException e)
{
    // check e.Status as above etc..
}

반사를 이용해서 하는 방법이 있습니다..NET 4.0과 함께 작동합니다.개인 필드에 액세스하며 수정 없이는 다른 버전의 .NET에서 작동하지 않을 수 있습니다.

Microsoft가 왜 이 필드에 속성을 노출하지 않았는지 모르겠습니다.

private static int GetStatusCode(WebClient client, out string statusDescription)
{
    FieldInfo responseField = client.GetType().GetField("m_WebResponse", BindingFlags.Instance | BindingFlags.NonPublic);

    if (responseField != null)
    {
        HttpWebResponse response = responseField.GetValue(client) as HttpWebResponse;

        if (response != null)
        {
            statusDescription = response.StatusDescription;
            return (int)response.StatusCode;
        }
    }

    statusDescription = null;
    return 0;
}

를 사용하는 경우.Net 4.0(이하):

class BetterWebClient : WebClient
{
        private WebRequest _Request = null;

        protected override WebRequest GetWebRequest(Uri address)
        {
            this._Request = base.GetWebRequest(address);

            if (this._Request is HttpWebRequest)
            {
                ((HttpWebRequest)this._Request).AllowAutoRedirect = false;
            }

            return this._Request;
        } 

        public HttpStatusCode StatusCode()
        {
            HttpStatusCode result;

            if (this._Request == null)
            {
                throw (new InvalidOperationException("Unable to retrieve the status 
                       code, maybe you haven't made a request yet."));
            }

            HttpWebResponse response = base.GetWebResponse(this._Request) 
                                       as HttpWebResponse;

            if (response != null)
            {
                result = response.StatusCode;
            }
            else
            {
                throw (new InvalidOperationException("Unable to retrieve the status 
                       code, maybe you haven't made a request yet."));
            }

            return result;
        }
    }

를 사용하는 경우.Net 4.5.X 이상에서 HttpClient:

var response = await client.GetAsync("http://www.contoso.com/");
var statusCode = response.StatusCode;

해봤습니다.응답 머리글에는 상태 코드가 포함되어 있지 않습니다.

내가 틀리지 않았다면,WebClient는 단일 메서드 호출에서 여러 개의 고유 요청을 추상화할 수 있습니다(예: 100개의 계속 응답, 리디렉션 등).사용하지 않은 것 같습니다.HttpWebRequest그리고.HttpWebResponse고유한 상태 코드를 사용할 수 없습니다.

중간 상태 코드에 관심이 없는 경우 최종 상태 코드가 2xx(성공) 범위에 있다고 안전하게 가정할 수 있습니다. 그렇지 않으면 통화가 성공하지 못할 것입니다.

유감스럽게도 상태 코드는 다음에 없습니다.ResponseHeaders사전.

에릭의 대답은 윈도우 폰에서 그대로 작동하지 않습니다.다음 작업을 수행합니다.

class WebClientEx : WebClient
{
    private WebResponse m_Resp = null;

    protected override WebResponse GetWebResponse(WebRequest Req, IAsyncResult ar)
    {
        try
        {
            this.m_Resp = base.GetWebResponse(request);
        }
        catch (WebException ex)
        {
            if (this.m_Resp == null)
                this.m_Resp = ex.Response;
        }
        return this.m_Resp;
    }

    public HttpStatusCode StatusCode
    {
        get
        {
            if (m_Resp != null && m_Resp is HttpWebResponse)
                return (m_Resp as HttpWebResponse).StatusCode;
            else
                return HttpStatusCode.OK;
        }
    }
}

적어도 사용할 때는 그렇습니다.OpenReadAsync다른 사람을 위하여xxxAsync방법은 신중한 테스트를 권장합니다.이 프레임워크는 코드 경로를 따라 어딘가에 GetWebResponse를 호출하며, 응답 개체를 캡처하고 캐시하기만 하면 됩니다.

실제 HTTP 오류(500, 404 등)는 예외로 보고되기 때문에 이 스니펫에서 폴백 코드는 200입니다.이 트릭의 목적은 특정 사례 304(수정되지 않음)에서 비오류 코드를 캡처하는 것입니다.따라서 폴백은 상태 코드를 사용할 수 없는 경우 적어도 오류가 없는 코드라고 가정합니다.

사용해야 합니다.

if (e.Status == WebExceptionStatus.ProtocolError)
{
   HttpWebResponse response = (HttpWebResponse)ex.Response;             
   if (response.StatusCode == HttpStatusCode.NotFound)
      System.Diagnostics.Debug.WriteLine("Not found!");
}

WebClient 기능을 확장하는 데 사용합니다.상태 코드 및 상태 설명에는 항상 최신 응답 코드/설명이 포함됩니다.

                /// <summary>
                /// An expanded web client that allows certificate auth and 
                /// the retrieval of status' for successful requests
                /// </summary>
                public class WebClientCert : WebClient
                {
                    private X509Certificate2 _cert;
                    public WebClientCert(X509Certificate2 cert) : base() { _cert = cert; }
                    protected override WebRequest GetWebRequest(Uri address)
                    {
                        HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(address);
                        if (_cert != null) { request.ClientCertificates.Add(_cert); }
                        return request;
                    }
                    protected override WebResponse GetWebResponse(WebRequest request)
                    {
                        WebResponse response = null;
                        response = base.GetWebResponse(request);
                        HttpWebResponse baseResponse = response as HttpWebResponse;
                        StatusCode = baseResponse.StatusCode;
                        StatusDescription = baseResponse.StatusDescription;
                        return response;
                    }
                    /// <summary>
                    /// The most recent response statusCode
                    /// </summary>
                    public HttpStatusCode StatusCode { get; set; }
                    /// <summary>
                    /// The most recent response statusDescription
                    /// </summary>
                    public string StatusDescription { get; set; }
                }

따라서 다음을 통해 게시를 수행하고 결과를 얻을 수 있습니다.

            byte[] response = null;
            using (WebClientCert client = new WebClientCert())
            {
                response = client.UploadValues(postUri, PostFields);
                HttpStatusCode code = client.StatusCode;
                string description = client.StatusDescription;
                //Use this information
            }

위에 설명한 해킹의 F# 버전이 다른 사람에게 필요할 경우를 대비해서입니다.

open System
open System.IO
open System.Net

type WebClientEx() =
     inherit WebClient ()
     [<DefaultValue>] val mutable m_Resp : WebResponse

     override x.GetWebResponse (req: WebRequest ) =
        x.m_Resp <- base.GetWebResponse(req)
        (req :?> HttpWebRequest).AllowAutoRedirect <- false;
        x.m_Resp

     override x.GetWebResponse (req: WebRequest , ar: IAsyncResult  ) =
        x.m_Resp <- base.GetWebResponse(req, ar)
        (req :?> HttpWebRequest).AllowAutoRedirect <- false;
        x.m_Resp

     member x.StatusCode with get() : HttpStatusCode = 
            if not (obj.ReferenceEquals (x.m_Resp, null)) && x.m_Resp.GetType() = typeof<HttpWebResponse> then
                (x.m_Resp :?> HttpWebResponse).StatusCode
            else
                HttpStatusCode.OK

let wc = new WebClientEx()
let st = wc.OpenRead("http://www.stackoverflow.com")
let sr = new StreamReader(st)
let res = sr.ReadToEnd()
wc.StatusCode
sr.Close()
st.Close()

당신은 "클라이언트"를 사용할 수 있어야 합니다.응답 머리글[...]" 호출, 응답에서 내용을 가져오는 예는 이 링크를 참조하십시오.

이 코드를 사용하여 WebException 또는 OpenReadCompletedEventArgs에서 HTTP 상태 코드를 가져올 수 있습니다.오류. SL에 WebExceptionStatus가 없기 때문에 Silverlight에서도 작동합니다.프로토콜 오류가 정의되었습니다.

HttpStatusCode GetHttpStatusCode(System.Exception err)
{
    if (err is WebException)
    {
        WebException we = (WebException)err;
        if (we.Response is HttpWebResponse)
        {
            HttpWebResponse response = (HttpWebResponse)we.Response;
            return response.StatusCode;
        }
    }
    return 0;
}

언급URL : https://stackoverflow.com/questions/3574659/how-to-get-status-code-from-webclient

반응형