[c#] HttpStatusCode가 성공 또는 실패를 나타내는 지 확인

다음 변수가 있다고 가정 해 보겠습니다.

System.Net.HttpStatusCode status = System.Net.HttpStatusCode.OK;

이것이 성공 상태 코드인지 실패 코드인지 어떻게 확인할 수 있습니까?

예를 들어 다음을 수행 할 수 있습니다.

int code = (int)status;
if(code >= 200 && code < 300) {
    //Success
}

또한 일종의 화이트리스트를 가질 수 있습니다.

HttpStatusCode[] successStatus = new HttpStatusCode[] {
     HttpStatusCode.OK,
     HttpStatusCode.Created,
     HttpStatusCode.Accepted,
     HttpStatusCode.NonAuthoritativeInformation,
     HttpStatusCode.NoContent,
     HttpStatusCode.ResetContent,
     HttpStatusCode.PartialContent
};
if(successStatus.Contains(status)) //LINQ
{
    //Success
}

이러한 대안 중 어느 것도 나를 설득하지 못했으며 다음과 같이 나를 위해이 작업을 수행 할 수있는 .NET 클래스 또는 메서드를 원했습니다.

bool isSuccess = HttpUtilities.IsSuccess(status);



답변

HttpClient수업을 사용하는 경우 HttpResponseMessage다시 받을 수 있습니다.

이 클래스에는 IsSuccessStatusCode검사를 수행 하는 유용한 속성 이 있습니다.

using (var client = new HttpClient())
{
    var response = await client.PostAsync(uri, content);
    if (response.IsSuccessStatusCode)
    {
        //...
    }
}

궁금한 경우이 속성은 다음 과 같이 구현 됩니다.

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}

따라서 직접 사용 하지 않는 경우이 알고리즘을 재사용 할 수 HttpClient있습니다.

EnsureSuccessStatusCode응답이 성공하지 못한 경우 예외를 throw하는 데 사용할 수도 있습니다 .


답변

HttpResponseMessage 클래스에는 IsSuccessStatusCode 속성이 있습니다. 소스 코드를 살펴보면 usr이 이미 200-299가 최선을 다할 수 있다고 제안했기 때문입니다.

public bool IsSuccessStatusCode
{
    get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); }
}


답변

받아 들여지는 대답은 두 번째 부분에 매직 넘버가 포함되어 있기 때문에 약간 귀찮습니다. 그리고 첫 번째 부분은 내 대답에 가깝지만 일반 정수 상태 코드에 일반적이지 않습니다.

상태 코드로 HttpResponseMessage를 인스턴스화하고 성공 여부를 확인하여 정확히 동일한 결과를 얻을 수 있습니다. 값이 0보다 작거나 999보다 큰 경우 인수 예외가 발생합니다.

if (new HttpResponseMessage((HttpStatusCode)statusCode).IsSuccessStatusCode)
{
    // ...
}

이것은 정확히 간결하지는 않지만 확장으로 만들 수 있습니다.


답변

@TomDoesCode 답변에 추가 HttpWebResponse를 사용하는 경우 다음 확장 메서드를 추가 할 수 있습니다.

public static bool IsSuccessStatusCode(this HttpWebResponse httpWebResponse)
{
    return ((int)httpWebResponse.StatusCode >= 200) && ((int)httpWebResponse.StatusCode <= 299);
}


답변

나는 확장 방법의 발견 가능성에 부분적입니다.

public static class HttpStatusCodeExtensions
{
    public static bool IsSuccessStatusCode(this HttpStatusCode statusCode)
    {
        var asInt = (int)statusCode;
        return asInt >= 200 && asInt <= 299;
    }
}

네임 스페이스가 범위 내에있는 한 사용은 statusCode.IsSuccessStatusCode().


답변

호출하는 HTTP 리소스에 따라 다릅니다. 일반적으로 2xx범위는 성공 상태 코드 의 범위로 정의됩니다. 이는 모든 HTTP 서버가 준수하지 않는 규칙입니다.

예를 들어 웹 사이트에서 양식을 제출하면 종종 302 리디렉션이 반환됩니다.

일반적인 방법을 고안하려면 code >= 200 && code < 300 아이디어가 최선의 선택 일 것입니다.

자신의 서버를 호출하는 경우에서 표준화해야합니다 200.


답변

이것은 각 호출에 대한 새 개체의 생성 및 후속 가비지 수집을 방지하는 이전 답변의 확장입니다.

public static class StatusCodeExtensions
{
    private static readonly ConcurrentDictionary<HttpStatusCode, bool> IsSuccessStatusCode = new ConcurrentDictionary<HttpStatusCode, bool>();
    public static bool IsSuccess(this HttpStatusCode statusCode) => IsSuccessStatusCode.GetOrAdd(statusCode, c => new HttpResponseMessage(c).IsSuccessStatusCode);
}