System.Net.HttpWebRequest genereert verschillende WebExceptionStatus voor SSL- en niet-SSL-aanvragen onder speciale voorwaarden
Dit artikel helpt u bij het oplossen van het probleem waarbij anders WebExceptionStatus
wordt gegenereerd wanneer u de System.Net.HttpWebRequest
klasse gebruikt.
Oorspronkelijke productversie: .Net Framework
Origineel KB-nummer: 2007873
Symptomen
U gebruikt de System.Net.HttpWebRequest
klasse van Microsoft .Net Framework om een HTTP-aanvraag (Hypertext Transfer Protocol) of Hypertext Transfer Protocol Secure (HTTPS) te verzenden naar een server. Het duurt even voordat deze aanvraag een antwoord van de server ontvangt. Als tijdens deze wachttijd de kloktijd van het systeem handmatig wordt verhoogd of als de systeemklok achterloopt en de Windows Time-service zich vervolgens aanpast aan de werkelijke lokale tijd, ondervindt u een van de volgende scenario's:
Voor een aanvraag, die is verzonden via HTTP zonder opmaak, genereert de System.Net.HttpWebRequest
klasse de volgende uitzondering:
De aanvraag is afgebroken: er is een time-out opgetreden voor de bewerking.
Bovendien geeft de Status
eigenschap op de gegenereerde WebException
de waarde WebExceptionStatus.Timeout
aan.
Voor een aanvraag die via HTTPS is verzonden, genereert de System.Net.HttpWebRequest
klasse een van de volgende uitzonderingen:
De onderliggende verbinding is gesloten: er is een onverwachte fout opgetreden bij een ontvangst.
Bovendien geeft de Status
eigenschap op de gegenereerde WebException
de waarde WebExceptionStatus.ReceiveFailure
aan.
Of
De onderliggende verbinding is gesloten: een verbinding die naar verwachting in leven zou blijven, is gesloten door de server.
Bovendien geeft de Status
eigenschap op de gegenereerde WebException
de waarde WebExceptionStatus.KeepAliveFailure
aan.
In alle bovenstaande scenario's heeft de, die wordt gevangen, de InnerException
eigenschap. Als u de WebException
eigenschap vangt en verwijst WebException.InnerException.InnerException
, ziet u dat voor alle bovenstaande gevallen de tekenreeks het Message
volgende aangeeft:
Een verbindingspoging is mislukt omdat de verbonden partij na een periode niet correct heeft gereageerd of omdat de verbinding is mislukt omdat de verbonden host niet heeft gereageerd.
Dit bericht is de uitgebreide interpretatie van de Winsock-foutcode 10060 = WSAETIMEDOUT.
Wanneer de systeemtijd handmatig wordt verhoogd, genereert Winsock de time-outfout 10060 correct, maar deze wordt ingepakt als verschillende uitzonderingstypen voor SSL-aanvragen (Secure Sockets Layer) en niet-SSL-aanvragen.
Onder normale time-outomstandigheden waarbij niet met de systeemtijd wordt geknoeid, geven de SSL- en niet-SSL-scenario's de WebExceptionStatus.Timeout
status correct weer en wordt de algemene uitzondering gegenereerd: er is een time-out opgetreden voor de bewerking.
Oorzaak
Wanneer u de aanvraag via SSL of niet-SSL doet, wijst de klasse de System.Net.ServicePointManager
aanvraag toe aan een interne verbinding, die uiteindelijk de Winsock-verbinding maakt. In het geval van SSL-aanvragen gaat deze aanvraag of verbinding via een andere interne SSL/TLS-klasse, die verantwoordelijk is voor de versleuteling of ontsleuteling van de gegevens. Voor niet-SSL-verbindingen is deze interne SSL/TLS-klasse helemaal niet betrokken.
Wanneer de tijd wordt gewijzigd en de uitzondering wordt aangetroffen op de Winsock-laag, moet deze fout nu omhoog gaan van Winsock naar de toepassingslaag. Voor niet-SSL-verbindingen wordt deze uitzondering rechtstreeks opgevangen door de interne verbindingsklasse, maar voor SSL-aanvragen wordt deze fout verwerkt door de interne SSL/TLS-klasse. Deze klasse beschouwt deze niet-SSL-fout als een ReceiveFailure
of KeepAliveFailure
en heeft daarom een andere uitzonderingsstatus, terwijl voor een niet-SSL-verbinding de fout correct wordt gecast omdat deze wordt verwerkt door een andere klasse.
Status
Dit gedrag is inherent aan het ontwerp van het product.
Oplossing
Om dit verschil op te lossen van de gegenereerde uitzonderingstypen onder deze speciale voorwaarde waarbij de systeemtijd wordt gemanipuleerd, moet de toepassing de WebException
opvangen en vervolgens verwijzen naar de WebException.InnerException.InnerException.Message
eigenschap.
Als de Message
tekenreeks gelijk is aan het winsock uitgebreide foutequivalent van 10060 = WSAETIMEDOUT, kunt u de ReceiveFailure
of KeepAliveFailure
beschouwen als een normale time-out en niet als een ReceiveFailure
of KeepAliveFailure
.
De toepassing kan de onderstaande tijdelijke oplossing gebruiken bij het uitvoeren van de catch()
WebException
voor een Engelse versie van het framework. Voor een gelokaliseerde versie van het framework moet de onderstaande tijdelijke oplossing worden aangepast, afhankelijk van de taallokalisatie.
Belangrijk
Deze voorbeeldcode wordt geleverd als zodanig en is alleen bedoeld voor voorbeelddoeleinden. Het wordt verstrekt zonder garanties en verleent geen rechten.
try
{
......
}
catch (WebException oWEx)
{
WebExceptionStatus oStatus = oWEx.Status;
String strTimeoutErrorMessage = "A connection attempt failed because the connected party did not properly respond "
+ "after a period of time, or established connection failed because connected host has failed to respond";
switch (oStatus)
{
case WebExceptionStatus.KeepAliveFailure:
if ((oWEx.InnerException != null) && (oWEx.InnerException.InnerException != null)
&& oWEx.InnerException.InnerException.Message.ToString().Equals(strTimeoutErrorMessage, StringComparison.CurrentCultureIgnoreCase))
{ //----------------------------------------------------------------------
// This is Timeout Error which is wrongly thrown as a ReceiveFailure for
// SSL requests under this special condition.
//
// Handle this as a Timeout Error
//----------------------------------------------------------------------
}
else
{
//----------------------------------------------------------------------
// This is truly a KeepAliveFailure.
//----------------------------------------------------------------------
}
break;
case WebExceptionStatus.Timeout:
//----------------------------------------------------------------------
// This is a Timeout.
//----------------------------------------------------------------------
break;
case WebExceptionStatus.ReceiveFailure:
if ((oWEx.InnerException != null)
&& (oWEx.InnerException.InnerException != null)
&& oWEx.InnerException.InnerException.Message.ToString ().Equals (strTimeoutErrorMessage, StringComparison.CurrentCultureIgnoreCase))
{ //----------------------------------------------------------------------
// This is Timeout Error which is wrongly thrown as a ReceiveFailure for
// SSL requests under this special condition.
//
// Handle this as a Timeout Error
//----------------------------------------------------------------------
}
else
{ //----------------------------------------------------------------------
// This is truly a ReceiveFailure.
//----------------------------------------------------------------------
}
break;
default:
//----------------------------------------------------------------------
// This is some other Exception
//----------------------------------------------------------------------
break;
}
}
Feedback
https://aka.ms/ContentUserFeedback.
Binnenkort beschikbaar: In de loop van 2024 zullen we GitHub Issues geleidelijk uitfaseren als het feedbackmechanisme voor inhoud. Het wordt vervangen door een nieuw feedbacksysteem. Zie voor meer informatie:Feedback verzenden en weergeven voor