Odpowiedzi:
Może coś takiego ...
try
{
// ...
}
catch (WebException ex)
{
if (ex.Status == WebExceptionStatus.ProtocolError)
{
var response = ex.Response as HttpWebResponse;
if (response != null)
{
Console.WriteLine("HTTP Status Code: " + (int)response.StatusCode);
}
else
{
// no http status code available
}
}
else
{
// no http status code available
}
}
Używając operatora warunkowego zerowego ( ?.
), możesz uzyskać kod stanu HTTP za pomocą jednej linii kodu:
HttpStatusCode? status = (ex.Response as HttpWebResponse)?.StatusCode;
Zmienna status
będzie zawierać HttpStatusCode
. Gdy wystąpi bardziej ogólna awaria, taka jak błąd sieciowy, w którym nie jest wysyłany żaden kod statusu HTTP, wówczas status
będzie miał wartość NULL. W takim przypadku można sprawdzić ex.Status
, aby uzyskać WebExceptionStatus
.
Jeśli chcesz, aby opisowy ciąg był rejestrowany w przypadku niepowodzenia, możesz użyć operatora łączenia wartości null ( ??
), aby uzyskać odpowiedni błąd:
string status = (ex.Response as HttpWebResponse)?.StatusCode.ToString()
?? ex.Status.ToString();
Jeśli wyjątek zostanie zgłoszony w wyniku kodu stanu HTTP 404, ciąg znaków będzie zawierał „NotFound”. Z drugiej strony, jeśli serwer jest offline, ciąg będzie zawierał „ConnectFailure” i tak dalej.
(I dla każdego, kto chce wiedzieć, jak uzyskać kod podstatusu HTTP. To nie jest możliwe. Jest to koncepcja Microsoft IIS, która jest logowana tylko na serwerze i nigdy nie jest wysyłana do klienta).
?.
operator został pierwotnie nazwany operatorem propagacji wartości null, czy operatorem warunkowym o wartości null podczas wersji zapoznawczej. Jednak Atlassian resharper ostrzega przed użyciem operatora propagacji wartości null w takich scenariuszach. Dobrze wiedzieć, że jest również nazywany operatorem warunkowym zerowym.
działa to tylko wtedy, gdy WebResponse jest HttpWebResponse.
try
{
...
}
catch (System.Net.WebException exc)
{
var webResponse = exc.Response as System.Net.HttpWebResponse;
if (webResponse != null &&
webResponse.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
MessageBox.Show("401");
}
else
throw;
}
(Zdaję sobie sprawę, że pytanie jest stare, ale jest jednym z najpopularniejszych w Google).
Typowa sytuacja, w której chcesz poznać kod odpowiedzi, dotyczy obsługi wyjątków. Począwszy od C # 7, możesz użyć dopasowania do wzorca, aby faktycznie wprowadzić klauzulę catch tylko wtedy, gdy wyjątek pasuje do twojego predykatu:
catch (WebException ex) when (ex.Response is HttpWebResponse response)
{
doSomething(response.StatusCode)
}
Można to łatwo rozszerzyć na dalsze poziomy, na przykład w tym przypadku, gdy WebException
faktycznie był wewnętrznym wyjątkiem innego (i tylko nas interesuje 404
):
catch (StorageException ex) when (ex.InnerException is WebException wex && wex.Response is HttpWebResponse r && r.StatusCode == HttpStatusCode.NotFound)
Na koniec: zwróć uwagę, że nie ma potrzeby ponownego zgłaszania wyjątku w klauzuli catch, gdy nie pasuje on do twoich kryteriów, ponieważ nie wprowadzamy klauzuli na pierwszym miejscu w powyższym rozwiązaniu.
Możesz wypróbować ten kod, aby uzyskać kod stanu HTTP z WebException. Działa również w Silverlight, ponieważ SL nie ma zdefiniowanego WebExceptionStatus.ProtocolError.
HttpStatusCode GetHttpStatusCode(WebException we)
{
if (we.Response is HttpWebResponse)
{
HttpWebResponse response = (HttpWebResponse)we.Response;
return response.StatusCode;
}
return null;
}
return 0
? lub lepiej HttpStatusCode?
( null )?
var code = GetHttpStatusCode(ex); if (code != HttpStatusCode.InternalServerError) {EventLog.WriteEntry( EventLog.WriteEntry("MyApp", code, System.Diagnostics.EventLogEntryType.Information, 1);}
Nie jestem pewien, czy istnieje, ale gdyby istniała taka nieruchomość, nie zostałaby uznana za wiarygodną. WebException
Może być zwolniony z przyczyn innych niż HTTP Kody błędów w tym prostych błędów sieciowych. Te nie mają takiego pasującego kodu błędu http.
Czy możesz nam podać więcej informacji na temat tego, co próbujesz osiągnąć za pomocą tego kodu. Może istnieć lepszy sposób na uzyskanie potrzebnych informacji.