我正在建立一个消费来自巴西政府机构的服务的wcf客户端。此连接使用Soap 1.2,需要使用数字证书进行签名。
此示例使用的代码是使用.Net 4.6.1的控制台应用程序。主要应用程序是WPF应用程序(我不使用IIS)。此代码在Windows 10上没有问题,但是当我尝试在Windows 7上运行它时,它给出了以下错误:
System.ServiceModel.CommunicationException:向https://nfce-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico2.asmx发出HTTP请求时发生错误。这可能是由于在HTTPS情况下未使用HTTP.SYS正确配置服务器证书。这也可能是由客户端和服务器之间的安全绑定不匹配引起的。 ---> System.Net.WebException:底层连接已关闭:发送时发生意外错误。 ---> System.IO.IOException:无法从传输连接读取数据:远程主机强制关闭现有连接。 ---> System.Net.Sockets.SocketException:远程主机强行关闭现有连接。
这是客户端调用代码:
XmlNode node = null;
var parametro = new TConsStatServ();
parametro.cUF = NFeAPI.XMLSchemas.NfeStatusServico2.Envio.TCodUfIBGE.Item53;
parametro.tpAmb = NFeAPI.XMLSchemas.NfeStatusServico2.Envio.TAmb.Item2;
parametro.versao = "3.10";
parametro.xServ = TConsStatServXServ.STATUS;
var certificate = GetCertificateByName("Certificate Name", false);
string nFeNamespaceName = "http://www.portalfiscal.inf.br/nfe";
string parametroXML = XmlUtil.Serialize(parametro, nFeNamespaceName);
XmlDocument doc = new XmlDocument();
XmlReader reader = XmlReader.Create(new StringReader(parametroXML));
reader.MoveToContent();
node = doc.ReadNode(reader);
nfeCabecMsg soapHeader = new nfeCabecMsg();
soapHeader.cUF = parametro.cUF.ToString().Replace("Item", "");
soapHeader.versaoDados = "3.10";
var soapClient = new NfeStatusServico2SoapClient("NfeStatusServico2Soap");
soapClient.ClientCredentials.ClientCertificate.Certificate = certificate;
XmlNode result = soapClient.nfeStatusServicoNF2(ref soapHeader, node);
这是我的App.config:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NfeStatusServico2Soap">
<security mode="Transport">
<transport clientCredentialType="Certificate"/>
</security>
</binding>
<binding name="NfeStatusServico2Soap1" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://nfce-homologacao.svrs.rs.gov.br/ws/NfeStatusServico/NfeStatusServico2.asmx"
binding="basicHttpBinding" bindingConfiguration="NfeStatusServico2Soap"
contract="NfeStatusServico2.NfeStatusServico2Soap" name="NfeStatusServico2Soap" />
</client>
</system.serviceModel>
GetCertificateByName是我创建的帮助方法,用于返回服务对X509Certificate2的需求。
我已经尝试过禁用Windows 7防火墙,我进入了程序和功能 - >打开或关闭Windows功能,并启用.net 3框架节点进行wcf调用。
我也尝试使用带有.NET 2.0应用程序的WebReference,它也给出了同样的错误。我将代码升级为在.net 4.6.1中使用wcf,希望它能够正常工作。
我试图使用fiddler来跟踪问题并返回代码200,但对此没什么帮助。
已经5天了,我无法解决这个问题。因此,我即将在我的应用程序上放弃Windows 7支持。
在我的情况下,问题是我的项目仍在使用.Net Framework 4.0,它不支持TLS 1.1或1.2,我连接的服务自2018年1月1日起关闭了对TLS 1.0的支持。一旦我将项目升级到.Net Framework 4.5并强制使用TLS 1.2,一切正常。
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
在我的情况下,激活Windows Update并让它安装所有重要的更新解决了问题。
在对HTTP.SYS进行一些研究后,我发现一个微软网站说HTTP.SYS有一些“已知问题”,我认为它可以在某些更新中修复。我的运气就是这样。