none
HelloWorld Web Service - ASMX works / WCF doesn't RRS feed

  • Question

  • Hello,

    For one of our partner, we have to buid a https web service that they are going to call.

    In our environment we have a DMZ with a firewall that redirects the web service calls to our internal IIS/BizTalk server.

    So we built a WCF and it didn't work, the URL was not responding at all. After days of tests and research, I decided to start again by the basics :

    On our IIS server I created 2 simple HelloWorld services, one ASMX and one WCF.

    They are all working locally (from inside our network), but from Internet, only the ASMX is working.

    The only "strange" thing or real difference between the two, I have noticed so far, is the content of <soap:address location ... /> in the wsdl.

    Locally:

    - asmx - <soap:address location="https://IP Adress/Site/NS/service.asmx" />

    - wcf - <soap:address location="https://local.IISserver.name/Site/NS/service.asmx" />

    From Internet

    - asmx - <soap:address location="https://external.server.name/Site/NS/service.asmx" />

    - wcf - nothing, doesn't work

    I would say it's a WCF configuration issue, but I'm not a web services expert, so I really have no idea where to look ...

    Any help would be appreciate.

    Thanks.

    Thursday, August 8, 2013 11:21 PM

Answers

  • I've finally been able to have the WCF to work as well.

    I've had to do quite a lot of change in the web.config, to make it works, here is the resulting and working web.config:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
    
      <system.serviceModel>
    
        <services>
          <service name="xxx.xxxxxxxxx.xxxxxxxxxx.WebService.Ack" behaviorConfiguration="Default">
            <host>
              <baseAddresses>
                <add baseAddress="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc" />
              </baseAddresses>
            </host>
            <endpoint name="BasicHttpEndpoint"
    		address="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc"
    		binding="basicHttpBinding"
    		bindingConfiguration="defaultBasicHttpBinding" 
                    bindingNamespace="http://www.xxxxxx.com/wsdl/xxx/xxxxxxxxxxxxxxxxxxxxxx"
    		contract="xxxxxxxxxxxxxxxxPortType" />
            <endpoint name="MexEndpoint"
    		address="mex"
    		binding="mexHttpBinding"
    		contract="IMetadataExchange"	/>
          </service>
        </services>
    
        <bindings>
          <basicHttpBinding>
            <binding name="defaultBasicHttpBinding">
              <security mode="Transport">
                <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                <message clientCredentialType="Certificate" algorithmSuite="Default" />
              </security>
              <!--<security mode="Transport" />-->
            </binding>
          </basicHttpBinding>
        </bindings>
    
        <behaviors>
          <serviceBehaviors>
            <behavior name="Default">
              <serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc/mex"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <useRequestHeadersForMetadataAddress />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
    
      </system.serviceModel>
    
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    
      <!-- <system.diagnostics>
        <sources>
          <source name="System.ServiceModel"
                  switchValue="Information, ActivityTracing"
                  propagateActivity="true">
            <listeners>
              <add name="traceListener"
                  type="System.Diagnostics.XmlWriterTraceListener"
                  initializeData= "C:\Traces.svclog" />
            </listeners>
          </source>
        </sources>
      </system.diagnostics> -->
    
    </configuration>

    • Marked as answer by Jer-ome Monday, August 19, 2013 10:18 PM
    Monday, August 19, 2013 10:18 PM

All replies

  • Hi Jer-ome,

    When publishing a WCF HTTP service to IIS server on a production server (which might have external internet DNS address registered), you can use IIS site binding (for the IIS site which hosts the WCF service) to explicitly specify the server/host name used by the WCF service. Here are some blog entries mentioned this:

    #How to change HostName in WSDL for an IIS-hosted service?
    http://blogs.msdn.com/b/wenlong/archive/2007/08/02/how-to-change-hostname-in-wsdl-of-an-iis-hosted-service.aspx

    #HOWTO: Fix WCF Host Name on IIS
    http://gavinmckay.wordpress.com/2009/03/24/howto-fix-wcf-host-name-on-iis/

    and for IIS site bindings configuration, you can refer to the following pages:

    #Add a Binding to a Site (IIS 7)
    http://technet.microsoft.com/en-us/library/cc731692(v=WS.10).aspx

    #Binding <binding>
    http://www.iis.net/configreference/system.applicationhost/sites/site/bindings/binding


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Sunday, August 11, 2013 4:32 PM
    Moderator
  • Thanks Steven that's very interesting!

    So I noticed that I already had a binding defined in IIS (7.5):

    ServerBindings "IP-Address:80:"

    SecureBindings "IP-Address:443:"

    With IP-Address being the ip address of the IIS server on our internal network.

    I tried to add a binding to explicitly set the external domain name, but I cannot figure out how to specify the domain name AND the SSL certificate.

    In IIS GUI, in "Edit bindings" for my site, as soon as I select "https", the Host name field is disabled and I can select the certificate.

    If I use the command line, I can give the domain name but the certificate is not set, and if I go back to GUI to add the certificate, the Host name is removed.

    But, if it changes something, remember that this server (IIS/BizTalk) will not be publicly exposed. The WS call will be forwarded to this server by the firewall/server in the DMZ.

    There is also maybe something missing/wrong in my Web.config:

    <?xml version="1.0"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
      <system.serviceModel>
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
                <serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://external-domain-name.ca/Site/service.svc/basic"/>
              <!-- 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"/>
                <useRequestHeadersForMetadataAddress />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
      </system.serviceModel>
    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
     
    </configuration>

    Monday, August 12, 2013 9:39 PM
  • I've finally been able to have the WCF to work as well.

    I've had to do quite a lot of change in the web.config, to make it works, here is the resulting and working web.config:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
    
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
      </system.web>
    
      <system.serviceModel>
    
        <services>
          <service name="xxx.xxxxxxxxx.xxxxxxxxxx.WebService.Ack" behaviorConfiguration="Default">
            <host>
              <baseAddresses>
                <add baseAddress="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc" />
              </baseAddresses>
            </host>
            <endpoint name="BasicHttpEndpoint"
    		address="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc"
    		binding="basicHttpBinding"
    		bindingConfiguration="defaultBasicHttpBinding" 
                    bindingNamespace="http://www.xxxxxx.com/wsdl/xxx/xxxxxxxxxxxxxxxxxxxxxx"
    		contract="xxxxxxxxxxxxxxxxPortType" />
            <endpoint name="MexEndpoint"
    		address="mex"
    		binding="mexHttpBinding"
    		contract="IMetadataExchange"	/>
          </service>
        </services>
    
        <bindings>
          <basicHttpBinding>
            <binding name="defaultBasicHttpBinding">
              <security mode="Transport">
                <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
                <message clientCredentialType="Certificate" algorithmSuite="Default" />
              </security>
              <!--<security mode="Transport" />-->
            </binding>
          </basicHttpBinding>
        </bindings>
    
        <behaviors>
          <serviceBehaviors>
            <behavior name="Default">
              <serviceMetadata httpsGetEnabled="true" httpsGetUrl="https://xxx.xxx.com/xxxxxxxxxxx/xxxxxxxx/Ack.svc/mex"/>
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <useRequestHeadersForMetadataAddress />
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
    
      </system.serviceModel>
    
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
      </system.webServer>
    
      <!-- <system.diagnostics>
        <sources>
          <source name="System.ServiceModel"
                  switchValue="Information, ActivityTracing"
                  propagateActivity="true">
            <listeners>
              <add name="traceListener"
                  type="System.Diagnostics.XmlWriterTraceListener"
                  initializeData= "C:\Traces.svclog" />
            </listeners>
          </source>
        </sources>
      </system.diagnostics> -->
    
    </configuration>

    • Marked as answer by Jer-ome Monday, August 19, 2013 10:18 PM
    Monday, August 19, 2013 10:18 PM