WCF can't find the endpoint configuration issue

39,501

So I assume your service is hosted inside IIS, right??

So the virtual directory where your *.svc lives basically defines your service address - so is this address correct?

Also: you have "relative" address of mex on the service endpoint

<endpoint 
    address="mex" 

(which I believe is a really bad idea - MEX stands for Metadata Exchange, and I would not use that address for a regular service endpoint! It just violates the Principle of Least Surprise - if the endpoint is called MEX, I expect it to BE a metadata exchange endpoint - not a regular service endpoint...)

Anyway - with that regular address, your complete service address becomes:

http://yourserver/DatroseWCFService/DatroseService.svc/mex

What if you call your service on that address - do you get a response??

Update: not sure how you're trying to test this. This is a SOAP web service - you will see the "landing page" (the "help" page) for the service in your browser, but to test the service itself, you need to use a SOAP capable testing tool (like the WCF Test Client or SoapUI) - you cannot test the SOAP web service by just browsing to its web address .
(ok, so your testing this by invoking the service from a test app - that should definitely work!)

Update #2: since you're hosting this in IIS (right?), your service address is basically defined by the virtual directory where your *.svc file lives. So my next attempt would be: just let that address be your service address.

Change your service-side config to:

<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>

and your client-side config to:

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

Does that work??

The next attempt would be to use the client-side config without a bindingConfiguration= value - since that's what you're doing on the server, too - just absolutely bare-bones basicHttpBinding without any modifications - does that work??

Share:
39,501
Jeremy Holovacs
Author by

Jeremy Holovacs

I am a professional geek, involved with multiple facets of software engineering. Security, scalability, performance, and usability are all key factors in all my products.

Updated on February 08, 2020

Comments

  • Jeremy Holovacs
    Jeremy Holovacs over 4 years

    I have a webservice with WCF I'm testing on my local machine that's giving me a headscratcher.

    My service is configured like so:

    <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>
    

    My client is configured like so:

    <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>
    

    The error I receive is:

    There was no endpoint listening at http://localhost/DatroseWCFService/DatroseService.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

    ... and yet, if I browse to the location I get the service screen, so it appears to be set up properly.

    I'm sure this has do do with my configuration of the endpoints, but I can't figure out what they are supposed to look like. Some help would be appreciated here.

    UPDATE whups I put the wrong error message in. It's fixed now.

    UPDATE 2 per what I believe has been suggested in these responses I have changed my server config to :

    <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>
    

    and my client configuration to:

    <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>
    

    and when I run this I now get a 400 (bad request) error. I am not sure if this is a step forward or a step back. Have I created a new problem, or have I cleared my way to the next problem?

    UPDATE 3

    Upon niao' advice, I changed to this for the server config:

    <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>
    

    ...however, when I browsed to this address, I got a yellow screen of death:

    Server Error in '/DatroseWCFService' Application.
    When 'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled' is set to true in configuration, the endpoints are required to specify a relative address. If you are specifying a relative listen URI on the endpoint, then the address can be absolute. To fix this problem, specify a relative uri for endpoint 'http://localhost/DatroseWCFService/DatroseService.svc'.

    ...so with that, I tried making it a relative path like so:

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

    ... but after publishing that, I get the 404 error. The client endpoint is configured as such:

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

    UPDATE 4 Per marc_s' advice, I removed the binding config from the client, so my config looks like this:

    <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>
    

    and my server configuration looks like this:

    <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>
    

    I no longer get the 404 error.

    However, I do get a 400 (ProtocolException, Bad Request) with no edifying information of what it got or why it's bad. I expect I've progressed beyond the endpoint issue, into a brand new void of service configuration hell.

    UPDATE 5

    Per request, the "skeleton" of my service (I assume the interface will do?):

    [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);
    
    }
    
    • deltree
      deltree over 12 years
      your webservice is on port 80?!?
    • Brad Semrad
      Brad Semrad over 12 years
      I ran into this issue. One helpful item is to use fiddler. It might request a crossdomainpolicy.xml (name might be sightly different) that will cause it to fail. Also I misconfigured my database connection which threw an error and therefore the service was not listening. Try looking for these types of items to see if this is causing it. Your configuration of the service might be correct but something else might be wrong.
    • niao
      niao over 12 years
      specify an endpoint address (localhost/DatroseWCFService/DatroseService.svc) intthe server's web.config file - msdn.microsoft.com/en-us/library/ms733749.aspx
    • Jeremy Holovacs
      Jeremy Holovacs over 12 years
      I have an endpoint defined (see first config)... you mean define another one?
    • niao
      niao over 12 years
      Yes I know, but the address is "mex" instead of localhost/DatroseWCFService/DatroseService.svc. Mex is for metatada, not your service. Therefore, you should define 2 endpoints as described here: msdn.microsoft.com/en-us/library/ms733749.aspx .("Defining Endpoint Addresses in Configuration")
    • niao
      niao over 12 years
      @Jeremy, you're almost there. Change your endpoint address on the server to: localhost/DatroseWCFService/DatroseService.svc (instead of /svc). Specify the same endpoint address on the client side.Also leave the mex endpoint address on the server as it is now
    • Jeremy Holovacs
      Jeremy Holovacs over 12 years
      @niao, that does not work; When 'system.serviceModel/serviceHostingEnvironment/multipleSiteB‌​indingsEnabled' is set to true in configuration, the endpoints are required to specify a relative address. If you are specifying a relative listen URI on the endpoint, then the address can be absolute. To fix this problem, specify a relative uri for endpoint 'http://localhost/DatroseWCFService/DatroseService.svc'.
    • Jeremy Holovacs
      Jeremy Holovacs over 12 years
      @marc_s, I run this by invoking a service method on a client console application.
    • niao
      niao over 12 years
      @JeremyHolovacs can you show your configs now?
    • marc_s
      marc_s over 12 years
      @JeremyHolovacs: hmm.... at first sight, this seems to be OK to me. I'm at a loss by now..... I might try to "trim down" the configs to the bare minimum - they seems a bit overloaded right now - just to see if there's any discrepancy in the binding configurations between server and client....
    • niao
      niao over 12 years
      @JeremyHolovacs - try to add the service reference and point to: localhost/DatroseWCFService/DatroseService.svc this should generate a config file for you. Is your contract on the client and server the same?
    • niao
      niao over 12 years
      @JeremyHolovacs set the following in your server config file: <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
    • marc_s
      marc_s over 12 years
      Can you show us your DatroseService.svc file?? I'm beginning to suspect there might be something broken with that file.....
    • Rajesh
      Rajesh over 12 years
      @JeremyHolovacs: Can you post the skeleton of your WCF service
  • Shiraz Bhaiji
    Shiraz Bhaiji over 12 years
    +1 I had almost finished writing the answer :) the problem is that he only has a mex endpoint, the actual service is missing
  • Jeremy Holovacs
    Jeremy Holovacs over 12 years
    the web service responds on http://localhost/DatroseWCFService/DatroseService.svc. What should my address look like? Blank? something else? I must confess I was just following "how-to" guides I found on the internet, this is just shy of being Greek to me.
  • Jeremy Holovacs
    Jeremy Holovacs over 12 years
    @marc_s, yes (currently) I am developing the service locally. Obviously, my laptop will not be its final destination, but for troubleshooting it's all local.
  • niao
    niao over 12 years
    @Jeremy, I wrote the following in the comments for your post: , you're almost there. Change your endpoint address on the server to: localhost/DatroseWCFService/DatroseService.svc (instead of /svc). Specify the same endpoint address on the client side.Also leave the mex endpoint address on the server as it is now. Try this and in my opinion you should be fine
  • Jeremy Holovacs
    Jeremy Holovacs over 12 years
    @marc_s, this gives me a different exception, which may or may not be a bad thing. I now get a ProtocolException with a 400 (Bad Request), which sounds like the endpoints may be properly configured now, but something else is still wrong (I assume with the configuration, but that may not be accurate).
  • niao
    niao over 12 years
    While this is still not working after mine and @marc_s advices, I think that you should at first test the SOAP web service by just browsing to its web address
  • niao
    niao over 12 years
    I know, but he can browse to its web address to test if it's listening
  • Jeremy Holovacs
    Jeremy Holovacs about 12 years
    I ended up abandoning the web service in favor of a direct connection. I just could not get it to work properly.
  • Aaron D
    Aaron D over 9 years
    I had specified the Service.svc in the address - that was it for me. Once I got rid of it, everything worked.