Problema: aparece esta excepción "LA CONEXIÓN SUBYACENTE SE CERRÓ: OCURRIÓ UN ERROR INESPERADO EN UN ENVÍO" en mis registros y está interrumpiendo nuestra integración OEM con nuestro sistema de marketing por correo electrónico en momentos aleatorios que varían de [1 hora a 4 horas]
Mi sitio web está alojado en un servidor Windows 2008 R2 con IIS 7.5.7600. Este sitio web tiene una gran cantidad de componentes OEM y un panel completo. Todo funciona bien con todos los demás elementos del sitio web, excepto con uno de nuestros componentes de marketing por correo electrónico que estamos utilizando como una solución de iframe dentro de nuestro panel de control. La forma en que funciona es, envío un httpWebRequestobject con todas las credenciales y obtengo una URL que puse en un iframe y funciona. Pero solo funciona durante un tiempo [1 hora - 4 horas] y luego obtengo la siguiente excepción "LA CONEXIÓN SUBYACENTE FUE CERRADA: OCURRIÓ UN ERROR INESPERADO EN UN ENVÍO" e incluso si el sistema intenta obtener la URL de httpWebRequest. falla con la misma excepción. La única forma de hacerlo funcionar de nuevo es reciclar el grupo de aplicaciones o cualquier cosa se edita en web.config.
Opción probada
Agregado explícitamente, keep-alive = false
keep-alive = true
Aumentó el tiempo de espera: <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />
He subido esta página a un sitio web que no es SSL para comprobar si el certificado SSL en nuestro servidor de producción está haciendo que la conexión se caiga de alguna manera.
Cualquier dirección hacia la resolución es muy apreciada.
Codigo:
Public Function CreateHttpRequestJson(ByVal url) As String
Try
Dim result As String = String.Empty
Dim httpWebRequest = DirectCast(WebRequest.Create("https://api.xxxxxxxxxxx.com/api/v3/externalsession.json"), HttpWebRequest)
httpWebRequest.ContentType = "text/json"
httpWebRequest.Method = "PUT"
httpWebRequest.ContentType = "application/x-www-form-urlencoded"
httpWebRequest.KeepAlive = False
'ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3
'TODO change the integratorID to the serviceproviders account Id, useremail
Using streamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
Dim json As String = New JavaScriptSerializer().Serialize(New With { _
Key .Email = useremail, _
Key .Chrome = "None", _
Key .Url = url, _
Key .IntegratorID = userIntegratorID, _
Key .ClientID = clientIdGlobal _
})
'TODO move it to the web.config, Following API Key is holonis accounts API Key
SetBasicAuthHeader(httpWebRequest, holonisApiKey, "")
streamWriter.Write(json)
streamWriter.Flush()
streamWriter.Close()
Dim httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
Using streamReader = New StreamReader(httpResponse.GetResponseStream())
result = streamReader.ReadToEnd()
result = result.Split(New [Char]() {":"})(2)
result = "https:" & result.Substring(0, result.Length - 2)
End Using
End Using
Me.midFrame.Attributes("src") = result
Catch ex As Exception
objLog.WriteLog("Error:" & ex.Message)
If (ex.Message.ToString().Contains("Invalid Email")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Email Taken")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Access Level")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Unsafe Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Invalid Password")) Then
'TODO Show message on UI
ElseIf (ex.Message.ToString().Contains("Empty Person Name")) Then
'TODO Show message on UI
End If
End Try
End Function
Public Sub SetBasicAuthHeader(ByVal request As WebRequest, ByVal userName As [String], ByVal userPassword As [String])
Dim authInfo As String = Convert.ToString(userName) & ":" & Convert.ToString(userPassword)
authInfo = Convert.ToBase64String(Encoding.[Default].GetBytes(authInfo))
request.Headers("Authorization") = "Basic " & authInfo
End Sub`
fuente
Respuestas:
Para mí fue tls12:
fuente
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 -bor [Net.SecurityProtocolType]::Tls11 -bor [Net.SecurityProtocolType]::Tls
Si está atascado con .Net 4.0 y el sitio de destino usa TLS 1.2, necesita la siguiente línea en su lugar.
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
fuente: Compatibilidad con TLS 1.2 y .NET: Cómo evitar errores de conexión
fuente
(SecurityProtocolType)768
se puede usar para "Tls11" (es decir, TLS 1.1).El siguiente código resolvió el problema
fuente
ServicePointManager.SecurityProtocol
es un objeto estático, lo que significa que cambiar este valor afectará a todas las subsecuenciasWebRequest
oWebClient
llamadas. Puede crear por separadoAppDomain
si deseaServicePointManager
tener diferentes configuraciones. Consulte stackoverflow.com/questions/3791629/… para obtener más detalles.He tenido el mismo problema durante días con una integración que también "solía funcionar antes".
Por pura depresión, lo intenté
Esto me resolvió ... aunque la integración estrictamente solo hace uso de SSLv3.
Me di cuenta de que algo estaba mal desde que Fiddler informó que había un "cifrado de negociación TLS vacío" o algo por el estilo.
¡Ojalá funcione!
fuente
En mi caso, el sitio al que me estoy conectando se ha actualizado a TLS 1.2. Como resultado, tuve que instalar .net 4.5.2 en mi servidor web para admitirlo.
fuente
Vaya a su web.config / App.config para verificar qué tiempo de ejecución .net está utilizando
Esta es la solucion:
.NET 4.6 y superior. No necesita realizar ningún trabajo adicional para admitir TLS 1.2, es compatible de forma predeterminada.
.NET 4.5. Se admite TLS 1.2, pero no es un protocolo predeterminado. Debes suscribirte para usarlo. El siguiente código hará que TLS 1.2 sea el predeterminado, asegúrese de ejecutarlo antes de realizar una conexión a un recurso seguro:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
fuente
Descubrí que esto es una señal de que el servidor donde está implementando el código tiene instalado un marco .NET antiguo que no es compatible con TLS 1.1 o TLS 1.2. Pasos para solucionarlo:
Puede obtener el último .NET Developer Pack y Runtime desde esta URL: http://getdotnet.azurewebsites.net/target-dotnet-platforms.html
fuente
Tuvimos este problema por el cual un sitio web que estaba accediendo a nuestra API recibía el mensaje "La conexión subyacente se cerró: se produjo un error inesperado en un envío". mensaje.
Su código era una mezcla de .NET 3.xy 2.2, lo que, según tengo entendido, significa que están usando TLS 1.0.
La respuesta a continuación puede ayudarlo a diagnosticar el problema habilitando TLS 1.0, SSL 2 y SSL3, pero para ser muy claro, no desea hacerlo a largo plazo, ya que los tres protocolos se consideran inseguros y ya no deberían serlo. utilizado :
Para que nuestro IIS responda a sus llamadas a la API, tuvimos que agregar configuraciones de registro en el servidor de IIS para habilitar explícitamente versiones de TLS - NOTA: Debe reiniciar el servidor de Windows (no solo el servicio IIS) después de realizar estos cambios:
Si eso no funciona, también puede experimentar agregando la entrada para SSL 2.0:
Para ser claros, esta no es una buena solución , y la solución correcta es hacer que la persona que llama use TLS 1.2, pero lo anterior puede ayudar a diagnosticar que este es el problema.
Puede acelerar la adición de esas entradas de registro con este script de PowerShell:
Esa es una versión modificada del script de la página de ayuda de Microsoft para Configurar TLS para VMM . Este artículo de basics.net fue la página que originalmente me dio la idea de mirar estas configuraciones.
fuente
Solo agrega:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
fuente
Si ayuda a alguien, el nuestro fue un problema con un certificado faltante. El entorno es Windows Server 2016 Standard con .Net 4.6.
Hay un URI https de servicio WCF autohospedado, para el cual Service.Open () se ejecutaría sin errores. Otro hilo seguiría accediendo a https: // OurIp: 443 / OurService? Wsdl para asegurarse de que el servicio estuviera disponible. Acceder al WSDL solía fallar con:
Se cerró la conexión subyacente: se produjo un error inesperado en un envío.
El uso de ServicePointManager.SecurityProtocol con la configuración aplicable no funcionó. Jugar con las funciones y funciones del servidor tampoco ayudó. Luego intervino Jaise George , el SE, resolviendo el problema en un par de minutos. Jaise instaló un certificado autofirmado en IIS, solucionando el problema. Esto es lo que hizo para abordar el problema:
(1) Abra el administrador de IIS (inetmgr) (2) Haga clic en el nodo del servidor en el panel izquierdo y haga doble clic en "Certificados de servidor". (3) Haga clic en "Crear certificado autofirmado" en el panel derecho y escriba lo que desee para el nombre descriptivo. (4) Haga clic en "Sitio web predeterminado" en el panel izquierdo, haga clic en "Enlaces" en el panel derecho, haga clic en "Agregar", seleccione "https", seleccione el certificado que acaba de crear y haga clic en "Aceptar" (5) Acceso la URL https, debe ser accesible.
fuente
Simplemente cambie la versión de su aplicación como 4.0 a 4.6 y publique ese código.
También agregue las siguientes líneas de código:
fuente
El uso de un proxy de depuración HTTP puede causar esto, como Fiddler.
Estaba cargando un certificado PFX desde un archivo local (autenticación en Apple.com) y falló porque Fiddler no pudo pasar este certificado.
Intente deshabilitar Fiddler para verificar y si esa es la solución, entonces probablemente necesite instalar el certificado en su máquina o de alguna manera que Fiddler pueda usarlo.
fuente
El siguiente código resolvió mi problema:
fuente