Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Este artículo le ayuda a resolver el problema en el que se produce un error al WebExceptionStatus
usar la System.Net.HttpWebRequest
clase .
Versión original del producto: .Net Framework
Número de KB original: 2007873
Síntomas
Está usando la System.Net.HttpWebRequest
clase de Microsoft .Net Framework para enviar una solicitud de protocolo de transferencia de hipertexto (HTTP) o protocolo seguro de transferencia de hipertexto (HTTPS) a un servidor. Esta solicitud tarda algún tiempo en recibir una respuesta del servidor. Durante este tiempo de espera, si el tiempo del reloj del sistema aumenta manualmente o si el reloj del sistema se retrasa y, a continuación, el servicio hora de Windows se ajusta a la hora local real, experimenta uno de los escenarios siguientes:
Para una solicitud, que se envió a través de HTTP de texto no cifrado, la System.Net.HttpWebRequest
clase producirá la siguiente excepción:
Se anuló la solicitud: la operación ha agotado el tiempo de espera.
Además, la Status
propiedad en el elemento WebException
producido indicará el valor WebExceptionStatus.Timeout
.
Para una solicitud, que se envió a través de HTTPS, la System.Net.HttpWebRequest
clase iniciará una de las siguientes excepciones:
Se ha cerrado la conexión subyacente: Error inesperado de recepción.
Además, la Status
propiedad en el elemento WebException
producido indicará el valor WebExceptionStatus.ReceiveFailure
.
O bien,
Se cerró la conexión subyacente: el servidor cerró una conexión que se esperaba mantener activa.
Además, la Status
propiedad en el elemento WebException
producido indicará el valor WebExceptionStatus.KeepAliveFailure
.
En todos los escenarios anteriores, que se detecta tiene la InnerException
propiedad . Si detecta y WebException
hace referencia a la WebException.InnerException.InnerException
propiedad , observará que para todos los casos anteriores, la Message
cadena indicará lo siguiente:
Se produjo un error durante el intento de conexión ya que la parte conectada no respondió adecuadamente tras un período de tiempo, o bien se produjo un error en la conexión establecida ya que el host conectado no ha podido responder.
Este mensaje es la interpretación detallada del código de error de Winsock 10060 = WSAETIMEDOUT.
Por lo tanto, cuando se aumenta manualmente la hora del sistema, Winsock produce correctamente el error de tiempo de espera 10060, pero se encapsula como tipos de excepción diferentes para las solicitudes de Capa de sockets seguros (SSL) y no SSL.
En circunstancias de tiempo de espera normales en las que no se manipula la hora del sistema, los escenarios SSL y no SSL reflejarán correctamente el WebExceptionStatus.Timeout
estado y producirán la excepción común: la operación ha agotado el tiempo de espera.
Causa
Al realizar la solicitud a través de SSL o no SSL, la System.Net.ServicePointManager
clase asignará la solicitud a una conexión interna, que finalmente va a realizar la conexión winsock. En el caso de las solicitudes SSL, esta solicitud o conexión pasa por otra clase SSL/TLS interna, que es responsable del cifrado o descifrado de los datos. En el caso de las conexiones que no son SSL, esta clase SSL/TLS interna no está implicada en absoluto.
Cuando se modifica la hora y se encuentra la excepción en la capa de Winsock, este error ahora debe desplazarse hacia arriba desde Winsock hasta la capa de aplicación. En el caso de las conexiones que no son SSL, esta excepción se detecta directamente mediante la clase de conexión interna, pero para las solicitudes SSL, este error se controla mediante la clase SSL/TLS interna. Esta clase considera este error que no es SSL como ReceiveFailure
o KeepAliveFailure
y, por tanto, tiene un estado de excepción diferente, mientras que para la conexión que no es SSL, el error se convierte correctamente, ya que se controla mediante una clase diferente.
Estado
Este comportamiento es por diseño.
Resolución
Para resolver esta discrepancia de los tipos de excepción producidos en esta condición especial en la que se manipula la hora del sistema, la aplicación debe capturar WebException
y, a continuación, hacer referencia a la WebException.InnerException.InnerException.Message
propiedad .
Si la Message
cadena es igual al error detallado de winsock equivalente a 10060 = WSAETIMEDOUT, puede considerar o ReceiveFailure
KeepAliveFailure
como un tiempo de espera normal y no considerarlo como o ReceiveFailure
KeepAliveFailure
.
La aplicación puede usar la siguiente solución alternativa al realizar la catch()
WebException
de para una versión en inglés del marco. Para una versión localizada del marco, es necesario ajustar la siguiente solución alternativa en función de la localización del idioma.
Importante
Este código de ejemplo se proporciona tal cual y está pensado solo para fines de ejemplo. Se proporciona sin garantías y no concede ningún derecho.
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;
}
}