VENDITE: 1-800-867-1389

 none
How to expose an IIS Hosted WCF Rest Service (using WebHttpRelayBinding) on the AppFabric Service Bus

    Domanda

  • So what I want to do is host a WCF service in IIS, and expose it on the AppFabric Service Bus, which is to be accessed by Java clients so also want to use an HTTP REST interface.

     

    1.       I started with this sample tutorial project which worked fine: http://msdn.microsoft.com/en-us/apitest/wazplatformtrainingcourse_introtoappfabricsb2010part2_topic4#_Toc309641049 but it’s hosted in a console application.

     

    2.       I created a new wcf service application, and added the interface and implementation from the sample project linked to above.

     

    3.       I modified the web.config to look like this:

     

    <?xml version="1.0"?>

    <configuration>

      <system.serviceModel>

        <bindings>

          <webHttpRelayBinding>

            <binding name="lab">

              <security relayClientAuthenticationType="None"/>

            </binding>

          </webHttpRelayBinding>

        </bindings>

        <services>

          <service behaviorConfiguration="default" name="ImageService.ImageService">

            <endpoint address="https://XXXXX.servicebus.windows.net/ImageOps" behaviorConfiguration="SharedSecretCredentials" 

    binding="webHttpRelayBinding" bindingConfiguration="lab" contract="ImageService.IImageContract"/>

          </service>

        </services>

        <behaviors>

          <endpointBehaviors>

            <behavior name="SharedSecretCredentials">

              <transportClientEndpointBehavior credentialType="SharedSecret">

                <clientCredentials>

                  <sharedSecret issuerName="owner" issuerSecret="XXXXX

                </clientCredentials>

              </transportClientEndpointBehavior>

            </behavior>

          </endpointBehaviors>

          <serviceBehaviors>

            <behavior name="default">

              <serviceDebug httpHelpPageEnabled="false" httpsHelpPageEnabled="false"/>

            </behavior>

          </serviceBehaviors>

        </behaviors>

        <extensions>

          <behaviorExtensions>

            <add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

          </behaviorExtensions>

          <bindingExtensions>

            <add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>

          </bindingExtensions>

        </extensions>

     

      </system.serviceModel>

      <startup>

        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>

      </startup>

     

      <system.web>

        <compilation debug="true"/>

      </system.web>

    </configuration>

     

     

    4.       Using Visual Studio from the projects properties page, I specified to use IIS and created a virtual directory, and then using IIS Manager also configured the wcf service application for Auto-Start. I added to the above web.config to enable diagnostic logging (actually couldn’t get the service to be recognized at all until the diagnostic logging sections were added to web.config, and then anytime I remove them from the web.config the service again won’t be recognized by Azure (which returns list of publically available services for the namespace being hit when your service isn’t recognized)).

     

    5.       Running a web browser as a client (https://XXXX.servicebus.windows.net/ImageOps/GetImage) , produced this error:

     

    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">

    <Code>

    <Value>Sender</Value>

    <Subcode>

    <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:DestinationUnreachable</Value>

    </Subcode>

    </Code>

    <Reason>

    <Text xml:lang="en-US">

    The message with To 'https://XXXX.servicebus.windows.net/imageops/getimage' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

    </Text>

    </Reason>

    </Fault>

     

     

    6.  Since I’d set up the wcf service to use webHttpRelayBinding, and used a browser to access, this was unexpected. Also, I had added an attribute on the interface method definition to specify REST access. ([OperationContract, WebGet(UriTemplate = "/GetImage")]) 

    Not knowing what the issue is, I attempted this attribute on the class (specifically I added the AddressFilterMode) : [ServiceBehavior(Name = "ImageService", Namespace = "http://samples.microsoft.com/ServiceModel/Relay/", AddressFilterMode=AddressFilterMode.Any)]

     

    7.       Then error now changes to this:

     

    <Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">

    <Code>

    <Value>Sender</Value>

    <Subcode>

    <Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>

    </Subcode>

    </Code>

    <Reason>

    <Text xml:lang="en-US">

    The message with Action 'GET' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).

    </Text>

    </Reason>

    </Fault>

     

     

    8.       So I’m not sure what to change, I did find this page (http://soapfault.com/blog/) but not sure if it will have any effect. From that page, I think I will try the match any message filter extension.

     

     

     

    So what I’m really after is a sample project that shows an IIS hosted WCF service which uses WebHttpRelayBinding. Or some help on getting this one working. The WCF service is specified using an .svc file, has REST access, is auto-started.

     

     

     

     

    lunedì 28 novembre 2011 18:53

Risposte

  • Here's the web.config, and it's working. Two things I changed that have made a difference:

     

    1. added WebHttpBehavior

    2. added Service Registration

    So it's hosted in IIS AppFabric, uses ServerAppFabric's Auto-Start (so it looks like it's message activated but is SAFabric activated), and uses WebHttpRelayBinding.

    <?xml version="1.0"?>
    <configuration>
      <system.serviceModel>
        <bindings>
          <!-- Application Binding -->
          <webHttpRelayBinding>
            <binding name="lab">
              <security relayClientAuthenticationType="None"/>
            </binding>
          </webHttpRelayBinding>
        </bindings>
        <services>
            <service  name="ImageService.ImageService">
              <endpoint address="https://{namespace}.servicebus.windows.net/ImageOps/"
                        behaviorConfiguration="CloudBehavior" binding="webHttpRelayBinding"
                        bindingConfiguration="lab" contract="ImageService.IImageContract"/>
          </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="CloudBehavior">
              <webHttp/>
              <serviceRegistrySettings discoveryMode="Public" displayName="ImageOps.ImageService"/>
              <transportClientEndpointBehavior credentialType="SharedSecret">
                <tokenProvider>
                  <sharedSecret issuerName="{service identity}" issuerSecret="{secret}"/>
                </tokenProvider>
              </transportClientEndpointBehavior>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <extensions>
          <behaviorExtensions>
            <add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          </behaviorExtensions>
          <bindingExtensions>
            <add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
     </bindingExtensions>
        </extensions>
      </system.serviceModel>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
      <system.web>
        <compilation debug="true" targetFramework="4.0"/>
      </system.web>
    </configuration>

    • Contrassegnato come risposta bogatiy martedì 29 novembre 2011 20:19
    martedì 29 novembre 2011 19:18

Tutte le risposte

  • Hi,

    I take you’re using Windows Server AppFabric’s auto start feature. Please make sure you’ve properly configured it. Refer to http://social.technet.microsoft.com/wiki/contents/articles/host-wcf-services-with-service-bus-endpoints-in-iis-and-windows-server-appfabric.aspx?wa=wsignin1.0 for more information. Also try to enable Windows Server AppFabric’s monitoring feature. It will tell you more details about what’s wrong.

     

    Best Regards,

    Ming Xu.


    Please mark the replies as answers if they help or unmark if not.
    If you have any feedback about my replies, please contact msdnmg@microsoft.com.
    Microsoft One Code Framework
    martedì 29 novembre 2011 13:18
  • Hi Ming,

     

    Thanks for the response. The service is hosted in IIS using Server AppFabric for auto-start. Yes, I do also use WCF monitoring features.

    I have logging on verbose and all messages are also being logged, but frankly the WCF monitoring/tracking messages haven't been helpful as the issue is with the binding and azure servicebus.

    The link you post is interesting, but as most of Microsoft's examples, it unfortunately uses NetTcpRelayBinding, rather then WebHttpRelayBinding.

     

    So let's get to the real issue ...

     

    The REAL issue, as the title suggests, is how to use webHTTPRelayBinding for an IIS (local server, not Azure role) hosted WCF service with endpoints on Azure ServiceBus.

     

    Perhaps a better starting point is: http://msdn.microsoft.com/en-us/wazplatformtrainingcourse_introtoappfabricsb2010part1_topic4#_Toc303678125 

    This is a calculator service, but doesn't use the webHttpRelayBinding. If it did, my questions would be answered.

    So if that sample was enhanced to also use the WebHttpRelayBinding this would answer my questions.

    I have found this blog helpful, as the service has been specified fully in the config file, though in the sample he hosts the service in a console app: http://seroter.wordpress.com/2011/10/27/testing-out-the-new-appfabric-service-bus-relay-load-balancing/ 

     

    The part of that blog post that is most interesting is line 7 of the app.config file. 

    That tag adds a WebHttpBehavior to the endpoint behavior for the WebHttpRelayBinding's endpoint behavior. 

    <WebHttp />

    And I think that is the key to what I've been missing.  I'll update this later to give the answer once I have it if no one beats me to it.

    Another related item is when using a console host or other non-IIS host where you end up calling host.Open(), it's important to use WebServiceHost, rather than ServiceHost IF USING WebHttpRelayBinding. As I understand, IIS will already use WebServiceHost, rather than ServiceHost.


    • Modificato bogatiy martedì 29 novembre 2011 18:30 Forgot some of the text in the original.
    • Contrassegnato come risposta bogatiy martedì 29 novembre 2011 19:18
    • Contrassegno come risposta annullato bogatiy martedì 29 novembre 2011 20:18
    martedì 29 novembre 2011 18:27
  • Here's the web.config, and it's working. Two things I changed that have made a difference:

     

    1. added WebHttpBehavior

    2. added Service Registration

    So it's hosted in IIS AppFabric, uses ServerAppFabric's Auto-Start (so it looks like it's message activated but is SAFabric activated), and uses WebHttpRelayBinding.

    <?xml version="1.0"?>
    <configuration>
      <system.serviceModel>
        <bindings>
          <!-- Application Binding -->
          <webHttpRelayBinding>
            <binding name="lab">
              <security relayClientAuthenticationType="None"/>
            </binding>
          </webHttpRelayBinding>
        </bindings>
        <services>
            <service  name="ImageService.ImageService">
              <endpoint address="https://{namespace}.servicebus.windows.net/ImageOps/"
                        behaviorConfiguration="CloudBehavior" binding="webHttpRelayBinding"
                        bindingConfiguration="lab" contract="ImageService.IImageContract"/>
          </service>
        </services>
        <behaviors>
          <endpointBehaviors>
            <behavior name="CloudBehavior">
              <webHttp/>
              <serviceRegistrySettings discoveryMode="Public" displayName="ImageOps.ImageService"/>
              <transportClientEndpointBehavior credentialType="SharedSecret">
                <tokenProvider>
                  <sharedSecret issuerName="{service identity}" issuerSecret="{secret}"/>
                </tokenProvider>
              </transportClientEndpointBehavior>
            </behavior>
          </endpointBehaviors>
        </behaviors>
        <extensions>
          <behaviorExtensions>
            <add name="transportClientEndpointBehavior" type="Microsoft.ServiceBus.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
            <add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Configuration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
          </behaviorExtensions>
          <bindingExtensions>
            <add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configuration.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
     </bindingExtensions>
        </extensions>
      </system.serviceModel>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
      </startup>
      <system.web>
        <compilation debug="true" targetFramework="4.0"/>
      </system.web>
    </configuration>

    • Contrassegnato come risposta bogatiy martedì 29 novembre 2011 20:19
    martedì 29 novembre 2011 19:18