欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

记一次.net core调用SOAP接口遇到的问题

程序员文章站 2024-01-28 20:04:22
背景        最近需要将一些外部的 及其他 接口的调用移到一个独立的 项目中,然后供其他 项目调用。之前的几个 已经成功迁移,但是在迁移一个需要用户名密码认证的 接口的时候却始终调用不成功。下面直接上代码。 示例代码 在 中 ......

背景

       最近需要将一些外部的web service及其他soap接口的调用移到一个独立的webapi项目中,然后供其他.net core项目调用。之前的几个web service已经成功迁移,但是在迁移一个需要用户名密码认证的soap接口的时候却始终调用不成功。下面直接上代码。

示例代码

.net framework中通过添加服务引用会自动在web.config(或者app.config)中生成类似以下绑定配置:

<system.servicemodel>
  <bindings>
    <custombinding>
      <binding name="binding">
        <mtommessageencoding ="soap11wsaddressing10" />
        <httptransport authenticationscheme="basic"/>
      </binding>
    </custombinding>
  </bindings>
  <client>
    <endpoint address="http://sampl.url" binding="custombinding" bindingconfiguration="binding" contract="testclient" name="binding" />
  </client>
</system.servicemodel>

可以直接调用client的无参构造函数(会从配置中读取相应的配置)来获取客户端实例,但是由于.net core中已经不支持web.config(或者app.config),因此需要自己通过代码来创建bindingendpointaddress来获取客户端实例

var binding = new custombinding(new httptransportbindingelement
{
    authenticationscheme = authenticationschemes.basic
});

var client = new testclient(binding, new endpointaddress(new uri("http://sample.url")));
client.clientcredentials.username.username = "admin";
client.clientcredentials.username.password = "123456";

var response = client.add(new request()).result

发现问题

      在测试过程中始终抛异常the server returned an invalid or unrecognized response.。使用上面相同的代码在.net framework里测试却能正常获取响应,初步判断应该是.net core中的问题。通过wireshark工具抓包比对,我发现了差别。

请求正常的抓包截图
记一次.net core调用SOAP接口遇到的问题

请求失败的抓包截图
记一次.net core调用SOAP接口遇到的问题

通过两个请求的比对发现,失败的请求头部信息中没有authorization信息。接着我使用httpclient发送post请求来模拟对soap接口的调用。

httpclient.defaultrequestheaders.authorization = new authenticationheadervalue("basic", "ywrtaw46mtizndu2==");

在设置和不设置authorization的分别测试中发现设置了authorization能够成功请求并获得响应,不设置authorization的请求获得了一段html格式的文本响应,其中有一段很说明问题http 401 - unauthorized。在这两个不同的请求抓包中也发现成功的请求头部中是包含authorization信息的,另一个则没有。因此基本断定问题就出现在这里。

如何解决

      问题找到了,是因为请求头部中缺少authorization信息,但是如何解决我却始终没有找到好的办法,soap接口的调用不像使用httpclient发送post请求可以对header进行修改。直接使用httpclient发送post请求来调用soap接口对xml的序列化和反序列化又很是麻烦,也不想使用这种过于牵强的做法。翻遍了博客园和stackoverfolw也始终没有找到解决办法。

      终于,在我不懈的努力中看到了曙光,在github上翻dotnet/wcfissues的时候找到一些相关东西,特别是这一条。其中提到system.private.servicemodel版本高于或等于4.5.0的时候会抛异常the server returned an invalid or unrecognized response.,虽然他的使用跟我的不太一样,但是异常信息却相同。我当即将版本降到4.4.4再次测试,结果令人惊喜,请求成功了,通过抓包分析authorization信息在请求头部中。这证实我之前的判断,就是因为没有authorization信息导致请求失败。

结语

      问题解决了,system.private.servicemodel4.5.0及以上版本会存在此问题,降级到4.4.4方可解决,希望微软早日修复此问题,在nuget包管理中看到有更新但又不能更新的包是一件很不爽的事情!