我正在构建一个 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);
这是我的应用程序配置:
<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功能,并为WCF调用启用了.net 3框架节点。
我还尝试将WebReference与.NET 2.0应用程序一起使用,但它给出了相同的错误。我将代码升级为在 .net 4.6.1 中使用 wcf,希望它能正常工作。
我尝试使用提琴手来跟踪问题,它返回代码 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 更新并让它安装所有重要更新解决了问题。
在对HTTP进行了一些研究之后.SYS我发现一个Microsoft网站说HTTP.SYS有一些"已知问题",我认为它可以在一些更新中得到修复。幸运的是,情况确实如此。
下载IIS 加密并设置建议的更改。调用设置 tls 1.2 时
System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;