简体   繁体   中英

Cannot access WCF service using hostname IIS

I've been facing a tough issue for three days. I have a WCF web api (.svc service file) deployed to an IIS 8.5. The application was working properly and then, suddenly, after I changed some other minor things inside the code, this problem arises: I can connect to the application from inside the server (using localhost). I can connect from outside, using the server IP address. But I cannot, by any means, connect from the outside by using server hostname. The problem is best understood through the examples bellow:

Note: the application is an IIS app inside the main Web Site. The service's URI is http://myhostname/api/servicos.svc

I have searched through many websites and forums but of no avail.

My web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>

  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
    <customErrors mode="Off" />
  </system.web>

  <connectionStrings>
    <!-- My connection string goes here -->
  </connectionStrings>

  <system.serviceModel>
    <services>
      <service name="ServicoWeb.servico" behaviorConfiguration="Wcf_Behavior">
        <endpoint name="" binding="webHttpBinding" contract="ServicoWeb.IServico" />
      </service>
    </services>

    <behaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp automaticFormatSelectionEnabled="true" defaultBodyStyle="Bare" />
        </behavior>
      </endpointBehaviors>

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

    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="removeSvcDaUrl" type="ServicoWeb.Validacao.UrlCustomizacao, ServicoWeb" />
    </modules>    
    <directoryBrowse enabled="true" />
        <rewrite>        
            <rules>
                <remove name="WordPress: https://myhostname.com" />
            </rules>
        </rewrite>
        <handlers accessPolicy="Read, Execute, Script" />
        <security>
            <requestFiltering>
                <verbs>
                    <add verb="*" allowed="true" />
                </verbs>
            </requestFiltering>
        </security>
  </system.webServer>
</configuration>

The error I am presented to when trying to access the API from outside (via hostname) is this:

Server Error in '/Api' Application.

The resource cannot be found.

Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.

Requested URL: /Api/servico.svc/asos/csv/09655055000104

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1069.1

Do you have any idea what should I do in order to fix this bug?

Edit: one more information: other apps inside the same web site in IIS works FINE! There are even other web apis written in C#, just like this one here, and they all work properly.

Edit 2: another thing important to say is that I can access the service path until the service itself (servico.svc). So, for example, when I try to access " http://myhostname.com/api/servico.svc?wsdl " I successfully get the service's metadata. So, only when I try to access the service itself I get the error mentioned above.

There is a file named host file. When you try request a DN windows look into that file. That file inside C:\\WINDOWS\\System32\\drivers\\etc there is host file. Append like below this in your host file (with admin mode).

server_ip_address      myhostname.com

I finally got it solved! For those struggling with this issue without sucess: Amazon EC2 load balance was the cause of my troubles.

It happened that Load Balance was set up to filter all requests and send them to the server machines using transport layer SSL security protocol (HTTPS). So, if I were to request http://myserver.com/servico Amazon Load Balance would internally redirect to https://machine-n/servico where 'n' is the machine used (in my case, I have two machines).

So, what caused my issue, inside WCF, was this: my web.config was not allowing the service to accept HTTPS requests. Once I fixed this, everything worked fine.

It also explains why everything worked when I requested directly using the machine's IP address using HTTP: load balance did not play any role in this case filtering the request and redireting using HTTPS.

So, here we have my web.config, now allowing HTTPS requests:

<?xml version="1.0" encoding="UTF-8"?>
...    
<system.serviceModel>
    <services>
        <service name="ServicoWeb.servico" behaviorConfiguration="Wcf_Behavior">
            <endpoint name="" binding="webHttpBinding" contract="IServico" bindingConfiguration="webHttpTransportSecurity" />
        </service>
    </services>
    <bindings>
        <webHttpBinding>
            <binding name="webHttpTransportSecurity">
                <security mode="Transport" />
            </binding>
        </webHttpBinding>
    </bindings>
    <behaviors>
        <endpointBehaviors>
            <behavior>
                <webHttp automaticFormatSelectionEnabled="true" defaultBodyStyle="Bare" />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="Wcf_Behavior">
                <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="true" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <protocolMapping>
        <add binding="basicHttpsBinding" scheme="https" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
...

In my case below things helped :

  1. Check protocolMapping is binded correctly.

     <protocolMapping> <add binding="basicHttpsBinding" scheme="https" /> </protocolMapping>
  2. Check 443 port is open and working.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM