Проверка того, представляет ли 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);
7 ответов:
если вы используете
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
бросать исключение в случае ответ не был успешным.
класс HttpResponseMessage имеет свойство IsSuccessStatusCode, глядя на исходный код, это похоже на то, что usr уже предложил 200-299, вероятно, лучшее, что вы можете сделать.
public bool IsSuccessStatusCode { get { return ((int)statusCode >= 200) && ((int)statusCode <= 299); } }
принятый ответ немного беспокоит меня, поскольку он содержит магические числа (хотя они находятся в стандартной форме) во второй части. И первая часть не является общей для простых целочисленных кодов состояния, хотя она близка к моему ответу.
вы можете достичь точно такого же результата, создав экземпляр HttpResponseMessage с вашим кодом состояния и проверив его на успех. Он вызывает исключение аргумента, если значение меньше нуля или больше 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); }
Это зависит от того, какой 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); }
я неравнодушен к нахождению методов расширения.
public static class HttpStatusCodeExtensions { public static bool IsSuccessStatusCode(this HttpStatusCode statusCode) { var asInt = (int)statusCode; return asInt >= 200 && asInt <= 299; } }
пока ваше пространство имен находится в области видимости, использование будет
statusCode.IsSuccessStatusCode()
.