wcfmsmq.net-4.5wasnetmsmqbinding

WCF Activation for MSMQ where the service (.svc) is on the root


VS 2012/.NET4.5, Windows 8/IIS8 and 64 bit

Using WCF Service application, all the documentation that I've seen so far in naming my MSMQ queue to match the service name assume the fact that I am using an application or a virtual directory underneath the IIS website.

This is quoted from MSDN http://msdn.microsoft.com/en-us/library/ms789042.aspx

The application being activated must match (longest match) the prefix of the queue name.

For example, a queue name is: msmqWebHost/orderProcessing/service.svc. If Application 1 has a virtual directory /msmqWebHost/orderProcessing with a service.svc under it, and Application 2 has a virtual directory /msmqWebHost with an orderProcessing.svc under it, Application 1 is activated. If Application 1 is deleted, Application 2 is activated.

Also, http://blogs.msdn.com/b/tomholl/archive/2008/07/12/msmq-wcf-and-iis-getting-them-to-play-nice-part-1.aspx

However when you are hosting your MSMQ-enabled service in IIS 7 WAS, the queue name must match the URI of your service's .svc file. In this example we'll be hosting the service in an application called MsmqService with an .svc file called MsmqService.svc, so the queue must be called MsmqService/MsmqService.svc. Queues used for WCF services should always be private

And, http://msdn.microsoft.com/en-us/magazine/cc163357.aspx

It's important to note that the activation of MSMQ endpoints only works correctly if the queue has the same name as the .svc file (minus the machine name). That means that if your service endpoint is /server/app/service.svc, the queue name must be app/service.svc.

MyService.svc file is directly under the root of my IIS website (which is using a .NET 4 pool in integrated mode), so I did the following:

  1. Creating a private transactional queue called MyService.svc and giving Network Services full control (for testing).
  2. Setting my web.config endpoint: address="net.msmq://localhost/private/MyService.svc"
  3. I was able to push a message to the queue using a client test application using the address in (2).
  4. I added MSMQ protocol support to the website by executing the following: C:\Windows\System32\inetsrv>appcmd set site "MyWebsite" /+bindings.[protocol='net.msmq',bindingInformation='localhost'] (and checked that it added the support properly)
  5. From my website advanced settings I have http,net.tcp,net.msmq In Enabled Protocols
  6. I double checked that "Net.Msmq Listener Adapter", which is responsible for activating the service when a message arrives, is running and I restarted it.
  7. My web.config:
<configuration>
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
  </appSettings>
  <system.web>
    <compilation debug="true" targetFramework="4.5" />
    <httpRuntime targetFramework="4.5" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpBinding" scheme="http" />
      <add binding="netMsmqBinding" scheme="net.msmq" />
    </protocolMapping>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="false"
        multipleSiteBindingsEnabled="true" />
    <bindings>
      <netMsmqBinding>
        <binding name="MsmqBinding_IMyService" exactlyOnce="true"
            receiveErrorHandling="Move">
          <security mode="None"/>
        </binding>
      </netMsmqBinding>
    </bindings>
    <services>
      <service name="CompanyName.Service.MyService">
        <endpoint name="MyService"
          address="net.msmq://localhost/private/MyService.svc"
          bindingConfiguration="MsmqBinding_IMyService"
          binding="netMsmqBinding" contract="IMyService" >
        </endpoint>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <directoryBrowse enabled="false" />
  </system.webServer>
</configuration>

My service is not getting activated with the arrival of new messages to the queue and the messages stay in the queue. Is that because I am not using an application or a virtual directory or is there something I am missing?


Solution

  • The problem is sorted by creating an application within the default website and modifying the configuration to fit the new path.