2015-09-14 18 views
42

Giả sử tôi có biến sau đây:Kiểm tra nếu HttpStatusCode đại diện cho sự thành công hay thất bại

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

Làm thế nào tôi có thể kiểm tra nếu điều này là một mã trạng thái thành công hay một thất bại?

Ví dụ, tôi có thể làm như sau:

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

Tôi cũng có thể có một số loại danh sách trắng:

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

Không ai trong số những lựa chọn thay thế thuyết phục tôi, và tôi đã hy vọng cho một Lớp hoặc phương thức .NET có thể thực hiện công việc này cho tôi, chẳng hạn như:

bool isSuccess = HttpUtilities.IsSuccess(status); 
+0

bạn cần phải thực hiện 'int code = (int) Response.StatusCode' từ đó bạn sẽ cần phải tạo của riêng bạn' Enum' kiểm tra ở đây để làm việc ví dụ http://stackoverflow.com/questions/1330856/ get-http-status-code-number-200-301-404-etc-from-httpwebrequest-and-ht – MethodMan

+0

Bạn có cơ hội sử dụng lớp 'HttpClient' không? – dcastro

+0

@dcastro Không, tôi xin lỗi. Tôi đang sử dụng API * cấp cao có thể (hoặc có thể không) sử dụng nó trong nội bộ. API hiển thị mã trạng thái của phản hồi, nhưng không hiển thị 'HttpResponseMessage' bên trong ví dụ –

Trả lời

83

Nếu bạn đang sử dụng lớp HttpClient, khi đó bạn sẽ nhận được HttpResponseMessage quay lại.

Lớp học này có tài sản hữu ích được gọi là IsSuccessStatusCode sẽ thực hiện kiểm tra cho bạn.

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

Trong trường hợp bạn đang tò mò, khách sạn này implemented như:

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

Vì vậy, bạn chỉ có thể tái sử dụng thuật toán này nếu bạn không sử dụng HttpClient trực tiếp.

Bạn cũng có thể sử dụng EnsureSuccessStatusCode để ném ngoại lệ trong trường hợp phản hồi không thành công.

3

Tùy thuộc vào tài nguyên HTTP nào bạn đang gọi. Thông thường, phạm vi 2xx được định nghĩa là phạm vi mã trạng thái thành công. Đó rõ ràng là một quy ước mà không phải mọi máy chủ HTTP đều tuân thủ.

Ví dụ: gửi biểu mẫu trên trang web thường sẽ trả về chuyển hướng 302.

Nếu bạn muốn đưa ra một phương pháp chung thì ý tưởng code >= 200 && code < 300 có lẽ là ảnh đẹp nhất của bạn.

Nếu bạn đang gọi máy chủ của riêng mình thì có thể bạn nên đảm bảo rằng bạn chuẩn hóa trên 200.

6

Lớp HttpResponseMessage có thuộc tính IsSuccessStatusCode, nhìn vào mã nguồn nó giống như thế này để usr đã đề xuất 200-299 có lẽ là tốt nhất bạn có thể làm.

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

Thêm vào câu trả lời @TomDoesCode Nếu bạn đang sử dụng HttpWebResponse bạn có thể thêm phương pháp mở rộng này:

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

Câu trả lời được chấp nhận làm tôi bực mình một chút vì nó có chứa con số kỳ diệu, (mặc dù họ đang có trong tiêu chuẩn) trong phần thứ hai của nó. Và phần đầu tiên không phải là chung cho các mã trạng thái số nguyên đơn giản, mặc dù nó gần với câu trả lời của tôi.

Bạn có thể đạt được chính xác kết quả tương tự bằng cách khởi tạo HttpResponseMessage bằng mã trạng thái của bạn và kiểm tra để thành công. Nó không ném một ngoại lệ đối số nếu giá trị nhỏ hơn 0 hoặc lớn hơn 999.

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

Đây không phải là chính xác, nhưng bạn có thể làm cho tiện ích mở rộng.

+0

Điều này làm việc hoàn hảo cho tôi vì tôi chỉ có một HttpStatusCode và không phải là một thông điệp phản hồi. Làm tốt lắm! –

+0

"Câu trả lời được chấp nhận làm phiền tôi một chút vì nó chứa số ma thuật, (mặc dù chúng là tiêu chuẩn)" - Chúng không phải là "ma thuật" nếu chúng được chuẩn hóa, hiểu rõ và sẽ không bao giờ thay đổi. Hoàn toàn không có gì sai khi sử dụng mã trực tiếp. Nếu bạn có 'IsSuccessStatusCode' thì tuyệt vời, sử dụng nó (như câu trả lời được chấp nhận.) Nếu không, không thêm cruft của riêng bạn bằng cách sử dụng một trừu tượng trừ khi bạn đang thực hiện kiểm tra này khắp nơi –

0

Đây là phần mở rộng của câu trả lời trước, tránh việc tạo và thu gom rác tiếp theo của một đối tượng mới cho mỗi lệnh gọi.

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); 
} 
Các vấn đề liên quan