• 快过闪电,MIUI 10与MIUI 9速度对比 2019-03-21
  • 泽州去年“免费教育”资金达5211万元 2019-03-19
  • 看你这么可怜,再提示你一下:你重孙算1,父母为2,父母的父母为4,父母的父母的父母为8…… 2019-03-19
  • 习近平春节前夕赴江西看望慰问广大干部群众 2019-03-05
  • 三只树懒漂洋过海亮相杭州 看着都困 2019-03-01
  • 健康管理进入精准时代 中检健康与正大制药启动健康管理2050公益工程 2019-02-24
  • A股市场具有较强估值支撑 机构看好政策受益板块 2019-02-19
  • 社会消费品零售总额 上月增长8.5% 2019-02-19
  • 紫光阁中共中央国家机关工作委员会 2018-11-22
  • “无中生有”也能助力文旅 2018-11-21
  • 中国何以成为数字大国 2018-11-20
  • 记一次.net core调用SOAP接口遇到的问题

    背景

    快乐彩开奖号码 www.752o.com ???????最近需要将一些外部的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="//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("//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工具抓包比对,我发现了差别。

    请求正常的抓包截图
    成功

    请求失败的抓包截图
    失败

    通过两个请求的比对发现,失败的请求头部信息中没有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的时候找到一些相关东西,特别是这一条https://github.com/dotnet/wcf/issues/3008。其中提到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包管理中看到有更新但又不能更新的包是一件很不爽的事情!

    posted @ 2018-11-15 15:29 xiangxiren 阅读(...) 评论(...) 编辑 收藏
  • 快过闪电,MIUI 10与MIUI 9速度对比 2019-03-21
  • 泽州去年“免费教育”资金达5211万元 2019-03-19
  • 看你这么可怜,再提示你一下:你重孙算1,父母为2,父母的父母为4,父母的父母的父母为8…… 2019-03-19
  • 习近平春节前夕赴江西看望慰问广大干部群众 2019-03-05
  • 三只树懒漂洋过海亮相杭州 看着都困 2019-03-01
  • 健康管理进入精准时代 中检健康与正大制药启动健康管理2050公益工程 2019-02-24
  • A股市场具有较强估值支撑 机构看好政策受益板块 2019-02-19
  • 社会消费品零售总额 上月增长8.5% 2019-02-19
  • 紫光阁中共中央国家机关工作委员会 2018-11-22
  • “无中生有”也能助力文旅 2018-11-21
  • 中国何以成为数字大国 2018-11-20