WCF找不到终结点配置问题。

3

我有一个使用WCF的Web服务,在本地机器上进行测试,但是遇到了难题。

我的服务配置如下:

<system.serviceModel>
   <services>
      <service name="GHMDatroseIntegration.GHMDatroseWCFService.DatroseService" 
               behaviorConfiguration="DatroseServiceBehavior">
         <endpoint 
             address="mex"
             binding="basicHttpBinding" 
             contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService" />
      </service>
   </services>
   <behaviors>
      <serviceBehaviors>
         <behavior name="DatroseServiceBehavior">
            <serviceMetadata httpGetEnabled="true"/>
            <serviceDebug includeExceptionDetailInFaults="true"/>
            <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
         </behavior>
      </serviceBehaviors>
   </behaviors>
   <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

我的客户端配置如下:

<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="BasicHttpBinding_IDatroseService" 
             closeTimeout="00:02:00" openTimeout="00:01:00" 
             receiveTimeout="00:10:00" sendTimeout="00:02:00"
             allowCookies="false" bypassProxyOnLocal="false" 
             hostNameComparisonMode="StrongWildcard"
             maxBufferSize="524288" maxBufferPoolSize="524288" 
             maxReceivedMessageSize="524288" 
             messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
             useDefaultWebProxy="true">
            <readerQuotas 
                 maxDepth="32" maxStringContentLength="524288" 
                 maxArrayLength="524288" maxBytesPerRead="524288" 
                 maxNameTableCharCount="524288" />
            <security mode="None">
                 <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                 <message clientCredentialType="UserName" algorithmSuite="Default" />
            </security>
         </binding>
      </basicHttpBinding>
   </bindings>
   <client>
       <endpoint name="BasicHttpBinding_IDatroseService"
           address="http://localhost/DatroseWCFService/DatroseService.svc"  
           behaviorConfiguration="DatroseServiceBehavior"
           binding="basicHttpBinding"  
           bindingConfiguration="BasicHttpBinding_IDatroseService"
           contract="DatroseWCFService.IDatroseService"  />
   </client>
   <behaviors>
      <endpointBehaviors>
         <behavior name="DatroseServiceBehavior">
             <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
         </behavior>
      </endpointBehaviors>
   </behaviors>
 </system.serviceModel>

我收到的错误是:

没有端点在http://localhost/DatroseWCFService/DatroseService.svc监听可以接受消息。这通常是由于地址或SOAP操作不正确引起的。有关更多详细信息,请参见InnerException(如果存在)。

...然而,如果我浏览到该位置,则会获得服务屏幕,因此似乎已正确设置。
我确定这与我的端点配置有关,但我无法弄清它们应该是什么样子。在这里提供一些帮助将不胜感激。 更新 哎呦,我把错误消息放错了。现在已经修复了。 更新2 根据我认为在这些响应中建议的,我已将服务器配置更改为:
<system.serviceModel>
   <services>
      <service name="GHMDatroseIntegration.GHMDatroseWCFService.DatroseService" 
               behaviorConfiguration="DatroseServiceBehavior">
         <endpoint 
             address="/svc"
             binding="basicHttpBinding"
             contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService"  />
         <endpoint 
             address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
       </service>
   </services>
   <behaviors>
       <serviceBehaviors>
          <behavior name="DatroseServiceBehavior">
             <serviceMetadata httpGetEnabled="true"/>
             <serviceDebug includeExceptionDetailInFaults="true"/>
             <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
          </behavior>
       </serviceBehaviors>
   </behaviors>
   <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

并将我的客户端配置设置为:

<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="BasicHttpBinding_IDatroseService" 
             closeTimeout="00:02:00" openTimeout="00:01:00" 
             receiveTimeout="00:10:00" sendTimeout="00:02:00"
             allowCookies="false" bypassProxyOnLocal="false" 
             hostNameComparisonMode="StrongWildcard"
             maxBufferSize="524288" maxBufferPoolSize="524288" 
             maxReceivedMessageSize="524288"
             messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
             useDefaultWebProxy="true">
          <readerQuotas 
              maxDepth="32" maxStringContentLength="524288" maxArrayLength="524288"
              maxBytesPerRead="524288" maxNameTableCharCount="524288" />
          <security mode="None">
              <transport clientCredentialType="None" proxyCredentialType="None"
                        realm="" />
              <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
       </binding>
     </basicHttpBinding>
   </bindings>
   <client>
      <endpoint name="BasicHttpBinding_IDatroseService" 
          address="http://localhost/DatroseWCFService/DatroseService.svc/svc" 
          behaviorConfiguration="DatroseServiceBehavior"
          binding="basicHttpBinding" 
          bindingConfiguration="BasicHttpBinding_IDatroseService"
          contract="DatroseWCFService.IDatroseService" />
   </client>
   <behaviors>
      <endpointBehaviors>
         <behavior name="DatroseServiceBehavior">
            <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
         </behavior>
      </endpointBehaviors>
   </behaviors>
</system.serviceModel>

当我运行这个程序时,现在出现了400(错误请求)的错误。我不确定这是向前还是向后迈进了一步。我是创造了一个新问题,还是为下一个问题铺平了道路?
更新3:
根据niao的建议,我将服务器配置更改为以下内容:
<system.serviceModel>
    <services>
        <service name="GHMDatroseIntegration.GHMDatroseWCFService.DatroseService" behaviorConfiguration="DatroseServiceBehavior">
            <endpoint contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService" binding="basicHttpBinding" address="http://localhost/DatroseWCFService/DatroseService.svc"/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="DatroseServiceBehavior">
                <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                <serviceMetadata httpGetEnabled="true"/>
                <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

...然而,当我浏览到这个地址时,我得到了一个黄色的死亡屏幕:

'/DatroseWCFService'应用程序中的服务器错误。
当配置中设置'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' 为true时,端点需要指定相对地址。如果在端点上指定了相对听取URI,则地址可以是绝对的。要解决此问题, 请为端点指定相对URI 'http://localhost/DatroseWCFService/DatroseService.svc'。

...所以,我尝试将其变成相对路径,就像这样:

<endpoint 
   address="localhost/DatroseWCFService/DatroseService.svc"
   binding="basicHttpBinding" 
   contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService" />

...但是在发布后,我收到了404错误。客户端终点被配置为:

<endpoint name="BasicHttpBinding_IDatroseService"
    address="http://localhost/DatroseWCFService/DatroseService.svc" 
    behaviorConfiguration="DatroseServiceBehavior"
    binding="basicHttpBinding" 
    bindingConfiguration="BasicHttpBinding_IDatroseService"
    contract="DatroseWCFService.IDatroseService"  />

更新4 根据marc_s的建议,我从客户端中删除了绑定配置,所以我的配置看起来像这样:

<system.serviceModel>
    <client>
        <endpoint address="http://localhost/DatroseWCFService/DatroseService.svc" behaviorConfiguration="DatroseServiceBehavior"
         binding="basicHttpBinding" 
         contract="DatroseWCFService.IDatroseService" name="BasicHttpBinding_IDatroseService" />
    </client>
    <behaviors>
        <endpointBehaviors>
            <behavior name="DatroseServiceBehavior">
                <dataContractSerializer maxItemsInObjectGraph="10000000"/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
</system.serviceModel>

"我的服务器配置如下:"
<system.serviceModel>
    <services>
        <service name="GHMDatroseIntegration.GHMDatroseWCFService.DatroseService" behaviorConfiguration="DatroseServiceBehavior">
            <endpoint contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService" binding="basicHttpBinding" address=""/>
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior name="DatroseServiceBehavior">
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="true" httpsHelpPageEnabled="true" httpHelpPageEnabled="true"/>
                <dataContractSerializer maxItemsInObjectGraph="10000000"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

我不再收到404错误。

然而,我收到了一个400(ProtocolException,Bad Request),没有提供有关它得到什么或为什么不好的信息。我认为我已经超越了终端点问题,进入了全新的服务配置地狱。

更新5

按要求,这是我的服务“骨架”(我假设接口会做到?):

[ServiceContract]
public interface IDatroseService
{

    [OperationContract]
    bool SubmitPayableTransaction(List<InvoiceItem> invoices);

    [OperationContract]
    Dictionary<string, bool> ValidateAccounts(List<string> accounts);

    [OperationContract]
    Dictionary<string, int> GetVendor1099Types(List<string> vendors);

    [OperationContract]
    Dictionary<string, string> GetPaymentTerms(List<string> vendors);

}

你的 Web 服务在80端口?!? - deltree
我遇到了这个问题。一个有用的工具是使用Fiddler。它可能会请求crossdomainpolicy.xml文件(名称可能略有不同),这将导致失败。此外,我错误地配置了我的数据库连接,导致出现错误,因此服务未在侦听。尝试查找这些类型的项目,看看是否是这个原因。您的服务配置可能是正确的,但其他方面可能存在问题。 - Brad Semrad
1
我已经定义了一个端点(请参见第一个配置)...你的意思是再定义一个吗? - Jeremy Holovacs
1
@niao,那个不起作用;当在配置中将'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled'设置为true时,终结点必须指定相对地址。如果您正在端点上指定相对侦听URI,则地址可以是绝对的。要解决此问题,请为端点'http://localhost/DatroseWCFService/DatroseService.svc'指定一个相对URI。 - Jeremy Holovacs
1
@JeremyHolovacs 在您的服务器配置文件中设置以下内容:<serviceHostingEnvironment multipleSiteBindingsEnabled="false" /> - niao
显示剩余9条评论
1个回答

16
我假设您的服务托管在IIS中,对吗?
所以您的*.svc所在的虚拟目录基本上定义了您的服务地址 - 那么这个地址正确吗?
另外:您在服务终结点上具有“相对”地址mex。
<endpoint 
    address="mex" 

(我认为这是一个非常糟糕的想法- MEX代表元数据交换,我不会使用那个地址作为常规服务端点!这违反了最小惊奇原则 - 如果端点被称为MEX,我期望它是一个元数据交换端点,而不是一个常规服务端点...)

无论如何 - 使用该常规地址,您的完整服务地址变为:

http://yourserver/DatroseWCFService/DatroseService.svc/mex
如果您在该地址上调用服务,会得到响应吗? 更新:我不确定您如何尝试测试这个。这是一个SOAP Web服务——您将在浏览器中看到服务的“登陆页”(即“帮助”页面),但要测试服务本身,您需要使用一个SOAP能力测试工具(比如WCF Test Client或者SoapUI)——您不能通过浏览其Web地址来测试SOAP Web服务。
(好的,那么您通过从测试应用程序调用该服务进行测试——这肯定有效!)

更新#2:由于您正在IIS中托管此服务(对吗?),因此您的服务地址基本上由包含*.svc文件的虚拟目录定义。所以我的下一步尝试是:只需让该地址成为您的服务地址。

修改您的服务端配置为:

<service name="GHMDatroseIntegration.GHMDatroseWCFService.DatroseService" 
         behaviorConfiguration="DatroseServiceBehavior">
   <endpoint 
       address=""   <!-- define nothing here - just let the *.svc file determine your service address -->
       binding="basicHttpBinding" 
       contract="GHMDatroseIntegration.GHMDatroseWCFService.IDatroseService" />
   <endpoint 
       address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

并将您的客户端配置更改为:

<endpoint name="BasicHttpBinding_IDatroseService"
    address="http://localhost/DatroseWCFService/DatroseService.svc" 
    behaviorConfiguration="DatroseServiceBehavior"
    binding="basicHttpBinding" 
    bindingConfiguration="BasicHttpBinding_IDatroseService"
    contract="DatroseWCFService.IDatroseService"  />

那个行得通吗??

下一步尝试是在没有 bindingConfiguration= 值的情况下使用客户端配置-因为这也是服务器正在做的事情-只是绝对基本的 basicHttpBinding ,没有任何修改-那个行得通吗??


+1 我差不多写完了答案 :) 问题是他只有一个mex端点,实际的服务却缺失了。 - Shiraz Bhaiji
@marc_s,是的(目前)我正在本地开发服务。显然,我的笔记本电脑不会是它的最终目的地,但为了故障排除,一切都是本地的。 - Jeremy Holovacs
@Jeremy,我在你的帖子评论中写了以下内容:你已经接近成功了。在服务器上更改您的终结点地址为:localhost/DatroseWCFService/DatroseService.svc(而不是/svc)。在客户端上指定相同的终结点地址。同时保留服务器上的mex终结点地址不变。尝试这样做,我认为你应该没问题了。 - niao
@marc_s,这给了我一个不同的异常,可能是好事也可能是坏事。现在我得到了一个带有400(错误请求)的ProtocolException,这听起来像是端点可能已经正确配置,但仍然有其他问题(我假设是配置问题,但可能不准确)。 - Jeremy Holovacs
我在地址中指定了Service.svc,这就是我的问题所在。一旦我去掉它,一切都正常了。 - Aaron D
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接