I'm from Brazil and our government released a WebService meant to inform employees' payroll that's called eSocial. I'm developing a solution to communicate with this service for about a year now and I found this error in some customers' machines while trying to send information to the government WebService:
System.ServiceModel.CommunicationException:
An error occurred while making the HTTP request to 'https://webservices.producaorestrita.esocial.gov.br/servicos/empregador/enviarloteeventos/WsEnviarLoteEventos.svc'. This could be due to the fact that the server certificate is not configured properly with HTTP.SYS in the HTTPS case. This could also be caused by a mismatch of the security binding between the client and the server.---> System.Net.WebException: The underlying connection was closed: The connection was closed unexpectedly.
---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)...
In most machines our program is working perfectly, the error arises just on some computers. My target platform is .NET Framework 4.7.
During my researches I've found two solutions for the problem:
- Set the property
ServicePointManager.SecurityProtocol
(https://stackoverflow.com/a/33084791/8133067); - Let Windows Update install the updates needed (https://stackoverflow.com/a/45494549).
In case of the first solution: eSocial WebService uses the TLS 1.2 security protocol, but this is not always the default machine configuration. I already did this in the code and did not solve in most cases:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
In case of the second solution: In the research I did the problem could happen on computers with an outdated Windows 7, and theoretically the update via Windows Update would solve, but in most cases did not solve, and I have even caught some cases of this error in Windows 10.
I even did a test program, with the message log and trace log turned on, to see if I could get any more information, but the only other thing I found out (because of tracing) is that the error occurs when the message is sent by the channel (communication channel with the WebService).
Here is the code I'm using to instantiate and call the service:
const string UrlSvcBase = @"https://webservices.{0}.esocial.gov.br/servicos/empregador/{1}";
string urlServico = String.Format(UrlSvcBase, "producaorestrita", @"enviarloteeventos/WsEnviarLoteEventos.svc");
var address = new EndpointAddress(urlServico);
//var binding = new BasicHttpBinding(BasicHttpsSecurityMode.Transport);
var binding = new BasicHttpsBinding(); //Available since .NET Framework 4.5
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
// Manual de Orientação do Desenvolvedor v1.4, página 39, item '5.4.5. Validações aplicadas':
// "O tamanho limite da mensagem SOAP é 750 kbytes."
// O valor padrão da propriedade MaxReceivedMessageSize é 65.536,
// que é alterado então para 750 KB * 1024 = 768.000 bytes.
// Caso contrário, ocorre a exceção:
// Exception: System.ServiceModel.CommunicationException
// InnerException: System.Exception {System.ServiceModel.QuotaExceededException}
// "The maximum message size quota for incoming messages (65536) has been exceeded.
// To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element."
// HResult: -2146233087 (0x80131501)
binding.MaxReceivedMessageSize = 768000;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls |
SecurityProtocolType.Tls11 |
SecurityProtocolType.Tls12;
var wsClient = new WsEnviar.ServicoEnviarLoteEventosClient(binding, address);
// 'certificado' variable's type is X509Certificate2.
wsClient.ClientCredentials.ClientCertificate.Certificate = certificado;
wsClient.Open();
// 'lote' variable's type is XElement.
var retorno = wsClient.EnviarLoteEventos(lote);
wsClient.Close();
Does anyone have any idea what might cause this error, or any idea of what else I can do to try to figure out the cause of the problem?
[EDIT]
My question was flagged as a possible duplicate of that one:
But, I had already tried almost all those solutions without success (actually, you can see that question already linked on my original post), that's why I've posted a new question, and there is a fundamental difference because in that question the service was made by the user and in my case the service is third-party. Fortunately I've got the answer somewhere else, so I'll post it here.