0

我一直在拉我的头发试图弄清楚这里发生了什么......

我们有一个尝试部署到服务器的应用程序,我们需要更改它所使用的 SOAP 服务的端点。最初添加服务时,它在 Web 配置文件中创建了一个条目:

<endpoint address="http://subdomain.example.com/path/to/mapserver" binding="basicHttpBinding" bindingConfiguration="MapServerBinding" contract="ServiceReference1.MapServerPort" name="MapServerPort" />

我们正在尝试将其更改为本地地址,以避免在使用服务时将其传出到互联网并返回(为了效率和防火墙问题):

<endpoint address="http://serverAlias/path/to/mapserver" binding="basicHttpBinding" bindingConfiguration="MapServerBinding" contract="ServiceReference1.MapServerPort" name="MapServerPort" />

在服务器上更改此配置值不会导致其查找位置发生变化,它仍会转到 subdomain.example.com。

我尝试过的事情:

  • 创建一个运行相关代码位的控制台应用程序,然后在配置文件中更改其端点(按预期适用于该应用程序,并证明该服务器可以连接到 SOAP 服务)
  • IISReset(不起作用,配置的值仍然不被接受)
  • 更改 Web 配置中的其他内容以确保确实重新加载了配置文件(我更改的每个设置都会正确影响行为,端点更改除外)
  • 将相同的应用程序部署到可比较的服务器(在 DMZ、IIS 7.5 中)并更改该实例的配置(实例按预期更改)
  • 更改了 hosts 文件以将对 subdomain.example.com 的调用重定向到内部 IP(这可行,但感觉像是解决它的一种 hacky 方法)
  • 重新启动服务器以查看是否会清除它拥有的任何神奇缓存(没有改变行为)

任何想法可能导致端点保持其初始配置?

这是配置文件的更完整的摘录(请注意,我们可以在其他服务器上随意更改端点地址,只是生产服务器似乎忽略了它)。根据 Brian 将所有绑定名称匹配为相同的建议进行了更改,最初 [binding name=""] 和 [endpoint bindingConfiguration=""] 都是“MapServerBinding”,否则与原始配置相同。

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="MapServerPort" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://serverAlias/path/to/mapserver"
        binding="basicHttpBinding" bindingConfiguration="MapServerPort"
        contract="ServiceReference1.MapServerPort" name="MapServerPort" />
    </client>
  </system.serviceModel>
4

2 回答 2

1

这东西更糟。我感觉到你的痛苦。这正是我必须实际获取服务引用以尊重我的生产服务器上的 web.config 设置:(另外,以防万一,确保您没有防火墙问题,考虑使用本地 ips 或编辑您的主机文件如果是,请在此处查看我的问题和答案:

Web 服务错误“没有端点正在侦听...”防火墙问题

以下代码将尊重您的生产 web.config,我会同时使用自定义绑定和基本绑定而不提出问题,我不知道您是否需要两者,但这是一个我不在乎的拉扯场景:

VB.net

Dim offerService As ServiceReferenceOffer.OfferServiceSoapClient
 offerService = New ServiceReferenceOffer.OfferServiceSoapClient("OfferServiceSoap")

网络配置

     <system.serviceModel>
        <bindings>
          <basicHttpBinding>
            <binding name="OfferServiceSoap" />
       </basicHttpBinding>
      <customBinding>
            <binding name="OfferServiceSoap12">
              <textMessageEncoding messageVersion="Soap12" />
              <httpTransport />
            </binding>
     </customBinding>
        </bindings>
    <client>
     <endpoint address="http://serverAlias/path/to/mapserver/OfferService.asmx" binding="basicHttpBinding" bindingConfiguration="OfferServiceSoap" contract="ServiceReferenceOffer.OfferServiceSoap" name="OfferServiceSoap" />
          <endpoint address="http://serverAlias/path/to/mapserver/OfferService.asmx" binding="customBinding" bindingConfiguration="OfferServiceSoap12" contract="ServiceReferenceOffer.OfferServiceSoap" name="OfferServiceSoap12" />
        </client>
 </system.serviceModel>
于 2013-06-10T21:23:57.693 回答
0

所以,这个问题的答案是更多地关注堆栈跟踪,傻瓜......我知道我必须在某个地方遗漏一些简单的东西,结果我把所有的努力都集中在了错误的地方。我一直在查看模型,这是代码中我试图更改的服务引用的唯一位置......当控制器中有另一个对我完全丢失的appsetting配置条目的调用时。

创建此代码的开发人员按照以下方式做了一些事情:

控制器

FooClass foo = new FooClass( configFileEntry["serviceRestURL"] );
return View(Models.bar(foo.fooMethod()));

模型

using (BazServiceClient baz = new BazServiceClient("MapServerPort"))
{
  baz.GetSomeImportantInformation();
  //Do some more work here
}

因此,我们有两个与服务器通信的不同端点(一个是控制器中基于 REST 的 API,另一个是模型中基于 SOAP 的端点)。由于基于 REST 的 API 隐藏在其他面向最终用户的 REST url 中(这些是 web 映射层服务,所以还有一些其他类似的服务)我最终专注于唯一一个(我认为)服务器应该用于服务器到服务器的通信。

由于从服务器访问 REST URL 的防火墙限制,控制器在模型有机会执行之前引发了异常,因此我的服务引用编辑没有反映。这也有助于解释为什么我添加的一些工具以确保我的配置编辑得到反映实际上似乎从未起作用。如果它曾经帮助某人进行故障排除,我将在下面粘贴我尝试使用的故障排除代码,以验证应用程序对服务引用的视图是否与 Web 配置的服务引用匹配。

        /*
         * This code is using (abusing?) the wonderful Elmah nuget package [ http://nuget.org/packages/elmah/ ] 
         * to surface the error in a way that is easy for me to find, so either install the package or swap it out
         * with your own way of surfacing the information.
         */
        System.ServiceModel.Configuration.ClientSection clientEndpoints = System.Configuration.ConfigurationManager.GetSection("system.serviceModel/client") as System.ServiceModel.Configuration.ClientSection;

        if (clientEndpoints != null)
        {
            //Loop through all the endpoints in the config to see what the config thinks it is set to
            foreach (System.ServiceModel.Configuration.ChannelEndpointElement endpoint in clientEndpoints.Endpoints)
            {
                string configFileMessage = "In Web config: [" + endpoint.Contract + "] points to [" + endpoint.Address.AbsoluteUri + "]";
                Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception(configFileMessage));
            }

            //Now see what the application is actually registering when it instantiates the service.
            //If all is well in the .NET world, this should match the web config entry!
            using (MapServerPortClient client = new MapServerPortClient("MapServerPort"))
            {
                string endPointMessage = "In application: " + client.Endpoint.Address.ToString();
                Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception(endPointMessage));
            }

        }
        else
        {
            Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("This is a bit embarrasing, but... I couldn't read the client endpoints at all.."));
        }
于 2013-06-18T13:36:15.170 回答