5

This is both information to those experiencing the issue and a question.

edit: The question is why does dropping "www." from the URL cause this error when a website running at the same address can be referenced without "www.".

I recently reproduced this problem using a trivial WCF service (the one from endpoint.tv) after resolving the usual config issues one faces moving a service from local IIS to shared hosting.

The problem was the following response (from fiddler) upon checking the url in browser. In searching the web for posts on the topic I found a number of unresolved issues pointing to the same problem in addition to the posts where the usual shared hosting config issues fix them up.

HTTP/1.1 400 Bad Request Server: Microsoft-IIS/7.0 X-Powered-By: ASP.NET Date: Tue, 17 Aug 2010 00:27:52 GMT Content-Length: 0

In Safari/Chrome this manifests as a blank page.

In IE you get "The webpage cannot be found".

In FF you get "XML Parsing Error: no element found Location: http://................ Line Number 1, Column 1:" (which I saw in numerous unresolved posts on the web - feel free to backlink a possible solution)

In Opera you get "Invalid Address"

I was scratching my head regarding this for a while, then I thought to try putting in the "www." which I was previously omitting from my url for no particular reason.

Problem solved.

I can now see the normal output in the browser and interact with the service via WCF Test Client.

So the question is:

Why does this make a difference to the hosted WCF service when I know it does not make a difference for browsing to the website hosted at the same address? With or without the "www." I can browse to the website at the same domain, hosted on the same account.

So far I've tested this repro on a GoDaddy service. I may try some others later.

Also, if you happen to know - I'd be interested to know what features are likely to make my WCF services need full trust rather than medium trust. And any thoughts you have on whether it is a good idea to utilise such features (in context of least priv ideology).

For reference this is the web.config, including an additional endpoint suggested by Mike to try and resolve this.

<?xml version="1.0"?>
<configuration>

  <system.web>
    <customErrors mode="Off"/>
    <compilation><!--debug="true"-->
        <buildProviders>
          <remove extension=".svc"/>
          <add extension=".svc" type="System.ServiceModel.Activation.ServiceBuildProvider,System.ServiceModel, Version=3.0.0.0, Culture=neutral,PublicKeyToken=b77a5c561934e089"/>
        </buildProviders>
    </compilation>
  </system.web>

  <!-- When deploying the service library project, the content of the config file must be added to the host's 
  app.config file. System.Configuration does not support config files for libraries. -->
  <system.serviceModel>
    <services>
      <service behaviorConfiguration="blah" 
               name="WCFServ.EvalService">
        <endpoint address="http://www.abcdomain.com/WCFServ/WCFServ.EvalService.svc" 
                  binding="basicHttpBinding" 
                  contract="WCFServ.IEvalService" />
        <endpoint address="http://abcdomain.com/WCFServ/WCFServ.EvalService.svc"
                  binding="basicHttpBinding"
                  contract="WCFServ.IEvalService" />
        <!--<endpoint address="" 
                  binding="mexHttpBinding" 
                  contract="IMetadataExchange" />-->
        <!--<host>
          <baseAddresses>
            <add baseAddress="http://abcdomain.com/WCFServ/" />
          </baseAddresses>
        </host>-->
      </service>
    </services>


    <behaviors>
      <serviceBehaviors>
        <behavior name="blah">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <serviceHostingEnvironment>
      <baseAddressPrefixFilters>
        <add prefix="http://www.abcdomain.com/WCFServ/"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

  </system.serviceModel>




  <!--http://localhost/WCFServ/WCFServ.EvalService.svc-->

<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>
Mick N
  • 14,892
  • 2
  • 35
  • 41

3 Answers3

1

Because you're using absolute URLs as your endpoint addresses, WCF needs to see a specific host header in HTTP requests in order to bind to those addresses.

Web servers are no different; if they're configured for a specific host, the request headers must have the host name or they won't serve up content. However, multiple host names can be bound to web sites, however, so sometimes a site may be tied to both www.example.com and example.com. Also, some web browsers, if you go to example.com and get a 404 or if the DNS lookup fails, will automatically retry the request at www.example.com.

I think the easiest thing for you to do to resolve your issue is to modify your endpoint(s) so they are host neutral. For example:

<services>
  <service behaviorConfiguration="blah" name="WCFServ.EvalService">
    <endpoint address="/WCFServ/WCFServ.EvalService.svc" 
              binding="basicHttpBinding" 
              contract="WCFServ.IEvalService"/>
  </service>
</services>

<!-- Just leave this out
<serviceHostingEnvironment>
  <baseAddressPrefixFilters>
    <add prefix="http://www.abcdomain.com/WCFServ/"/>
  </baseAddressPrefixFilters>
</serviceHostingEnvironment>
-->
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • Hi Jacob, Thanks for your reply. Unfortunately I can't leave out baseAddressPrefixFilters, because this solves the problem of running the service on a shared hosting server. This is apparently the accepted solution to http://stackoverflow.com/questions/561823/wcf-error-this-collection-already-contains-an-address-with-scheme-http. I'll see if I can get the address specified how you've suggested though and report back. – Mick N Aug 26 '10 at 02:28
  • The 400 Bad Request is now a 404 Server Error in '/wcfserv' Application. Requested URL: /WCFServ/WCFServ.EvalService.svc. I tried a few pathing variants in the endpoint address and baseAddressPrefixFilter. No change in successful www. result. I also tried adding an extra prefix for w/ www but this brought back "This collection already contains an address with scheme http" on www addressing. – Mick N Aug 26 '10 at 02:41
0

Make sure that you have endpoints defined without the www in your web config.

Mike
  • 3,462
  • 22
  • 25
0

This page has some good explanations about WCF addressing: WCF Adressing In Depth.

Is your problem solved by adding the following attribute on your serviceclass?

[ServiceBehavior(AddressFilterMode=AddressFilterMode.Any)]
Kris van der Mast
  • 16,343
  • 8
  • 39
  • 61
Michel van Engelen
  • 2,791
  • 2
  • 29
  • 45
  • Hi Michel, thanks for the link, it looks like an interesting read. Unfortunately the attribute alone on my service class hasn't changed the result though. – Mick N Aug 27 '10 at 09:18
  • Hmm ok. Can you implement a custom host factory to see whether your service is reached at all? Google for 'CustomHostFactory ServiceHostFactory' and find several examples. Set a breakpoint in the CreateServiceHost function, make sure to kill the worker process before you test it, it's possible that the service is already running. – Michel van Engelen Aug 27 '10 at 09:47