Click to Rate and Give Feedback
MSDN
MSDN Library
.NET Development
.NET Framework 3.5
WCF Feature Details
Queues in WCF
 How to: Exchange Messages with WCF ...
This page is specific to
Microsoft Visual Studio 2008/.NET Framework 3.5

Other versions are also available for the following:
How to: Exchange Messages with WCF Endpoints and Message Queuing Applications

You can integrate existing Message Queuing (MSMQ) applications with Windows Communication Foundation (WCF) applications by using the MSMQ integration binding to convert MSMQ messages to and from WCF messages. This allows you to call into MSMQ receiver applications from WCF clients as well as call into WCF services from MSMQ sender applications.

In this section, we explain how to use MsmqIntegrationBinding for queued communication between (1) a WCF client and an MSMQ application service written using System.Messaging and (2) an MSMQ application client and a WCF service.

For a complete sample that demonstrates how to call a MSMQ receiver application from a WCF client, see the Windows Communication Foundation to Message Queuing sample.

For a complete sample that demonstrates how to call a WCF service from a MSMQ client, see the Message Queuing to Windows Communication Foundation sample.

To create a WCF service that receives messages from a MSMQ client

  1. Define an interface that defines the service contract for the WCF service that receives queued messages from a MSMQ sender application, as shown in the following example code.

    Visual Basic
    <ServiceContract(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    <ServiceKnownType(GetType(PurchaseOrder))> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    End Interface
    C#
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    [ServiceKnownType(typeof(PurchaseOrder))]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
  2. Implement the interface and apply the ServiceBehaviorAttribute attribute to the class, as shown in the following example code.

    Visual Basic
    Public Class OrderProcessorService
        Implements IOrderProcessor
    
        <OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)> _
        Public Sub SubmitPurchaseOrder(ByVal ordermsg As MsmqMessage(Of PurchaseOrder)) Implements IOrderProcessor.SubmitPurchaseOrder
            Dim po As PurchaseOrder = ordermsg.Body
            Dim statusIndexer As New Random()
            po.Status = statusIndexer.Next(3)
            Console.WriteLine("Processing {0} ", po)
        End Sub
    End Class
    C#
    public class OrderProcessorService : IOrderProcessor
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> ordermsg)
        {
            PurchaseOrder po = (PurchaseOrder)ordermsg.Body;
            Random statusIndexer = new Random();
            po.Status = (OrderStates)statusIndexer.Next(3);
            Console.WriteLine("Processing {0} ", po);
        }
    
        // Host the service within this EXE console application.
    public static void Main()
    {
        // Get base address from appsettings in configuration.
        Uri baseAddress = new Uri(ConfigurationManager.AppSettings["baseAddress"]);
    
        // Create a ServiceHost for the CalculatorService type and provide the base address.
        using (ServiceHost serviceHost = new ServiceHost(typeof(IOrderProcessor), baseAddress))
        {
        // Open the ServiceHostBase to create listeners and start listening for messages.
            serviceHost.Open();
    
        // The service can now be accessed.
            Console.WriteLine("The service is ready.");
            Console.WriteLine("The service is running in the following account: {0}", WindowsIdentity.GetCurrent().Name);
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.WriteLine();
            Console.ReadLine();
    
        // Close the ServiceHostBase to shutdown the service.
            serviceHost.Close();
        }
    }
    
    }
  3. Create a configuration file that specifies the MsmqIntegrationBinding.

    Xml
    <configuration>
      <appSettings>
        <!-- use appSetting to configure MSMQ queue name -->
        <add key="orderQueueName" value=".\private$\Orders" />
        <add key="baseAddress" value="http://localhost:8000/ServiceModelSamples/Service" />
      </appSettings>
      <system.serviceModel>
        <services>
          <service 
            name="Microsoft.ServiceModel.Samples.OrderProcessorService" >
            <endpoint address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                                    binding="msmqIntegrationBinding"
                      bindingConfiguration="OrderProcessorBinding" 
                      contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
            </endpoint>
          </service>
        </services>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel >
    
    </configuration>
  4. Instantiate a ServiceHost object that uses the configured binding.

To create a WCF client that sends messages to a MSMQ receiver application

  1. Define an interface that defines the service contract for the WCF client that sends queued messages to the MSMQ receiver, as shown in the following example code.

    Visual Basic
    <System.ServiceModel.ServiceContractAttribute(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    end interface
    
    Public Interface IOrderProcessorChannel
        Inherits IOrderProcessor, System.ServiceModel.IClientChannel
    End Interface
    C#
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
       
    public interface IOrderProcessorChannel : IOrderProcessor, System.ServiceModel.IClientChannel
    {
    }
  2. Define a client class that the WCF client uses to call the MSMQ receiver.

    Visual Basic
    Dim binding As New MsmqIntegrationBinding()
    Dim address As New EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders")
    Dim channelFactory As New ChannelFactory(Of IOrderProcessor)(binding, address)
    Dim channel As IOrderProcessor = channelFactory.CreateChannel()
    
    Dim po As New PurchaseOrder()
    po.customerId = "somecustomer.com"
    po.poNumber = Guid.NewGuid().ToString()
    
    Dim lineItem1 As New PurchaseOrderLineItem()
    lineItem1.productId = "Blue Widget"
    lineItem1.quantity = 54
    lineItem1.unitCost = 29.99F
    
    Dim lineItem2 = New PurchaseOrderLineItem()
    lineItem2.productId = "Red Widget"
    lineItem2.quantity = 890
    lineItem2.unitCost = 45.89F
    
    Dim lineItems(2) As PurchaseOrderLineItem
    lineItems(0) = lineItem1
    lineItems(1) = lineItem2
    
    po.orderLineItems = lineItems
    
    Dim ordermsg As MsmqMessage(Of PurchaseOrder) = New MsmqMessage(Of PurchaseOrder)(po)
    Using scope As New TransactionScope(TransactionScopeOption.Required)
        channel.SubmitPurchaseOrder(ordermsg)
        scope.Complete()
    End Using
    Console.WriteLine("Order has been submitted:{0}", po)
    C#
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
    EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders");
    ChannelFactory<IOrderProcessor> channelFactory = new ChannelFactory<IOrderProcessor>(binding, address);
    IOrderProcessor channel = channelFactory.CreateChannel();
    
    PurchaseOrder po = new PurchaseOrder();
    po.customerId = "somecustomer.com";
    po.poNumber = Guid.NewGuid().ToString();
    
    PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
    lineItem1.productId = "Blue Widget";
    lineItem1.quantity = 54;
    lineItem1.unitCost = 29.99F;
    
    PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
    lineItem2.productId = "Red Widget";
    lineItem2.quantity = 890;
    lineItem2.unitCost = 45.89F;
    
    po.orderLineItems = new PurchaseOrderLineItem[2];
    po.orderLineItems[0] = lineItem1;
    po.orderLineItems[1] = lineItem2;
    
    
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        channel.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    Console.WriteLine("Order has been submitted:{0}", po);
  3. Create a configuration that specifies use of the MsmqIntegrationBinding binding.

    Visual Basic
    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    C#
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    Xml
    <configuration>
        <system.serviceModel>
    
        <client>
          <endpoint    name="OrderResponseEndpoint" 
                    address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                    binding="msmqIntegrationBinding"
                    bindingConfiguration="OrderProcessorBinding" 
                    contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
          </endpoint>
        </client>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel>
    
    </configuration>
  4. Create an instance of the client class and call the method defined by the message receiving service.

    C#
    // Create the purchase order.
    PurchaseOrder po = new PurchaseOrder();
    po.customerId = "somecustomer.com";
    po.poNumber = Guid.NewGuid().ToString();
    
    PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
    lineItem1.productId = "Blue Widget";
    lineItem1.quantity = 54;
    lineItem1.unitCost = 29.99F;
    
    PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
    lineItem2.productId = "Red Widget";
    lineItem2.quantity = 890;
    lineItem2.unitCost = 45.89F;
    
    po.orderLineItems = new PurchaseOrderLineItem[2];
    po.orderLineItems[0] = lineItem1;
    po.orderLineItems[1] = lineItem2;
             
    OrderProcessorClient client = new OrderProcessorClient("OrderResponseEndpoint");
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        client.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    
    Console.WriteLine("Order has been submitted:{0}", po);
    
    //Closing the client gracefully closes the connection and cleans up resources.
    client.Close();
    
    Console.WriteLine();
    Console.WriteLine("Press <ENTER> to terminate client.");
    Console.ReadLine();

See Also


© 2007 Microsoft Corporation. All rights reserved.
Build Date: 2009-10-13
Tags What's this?: Add a tag
Community Content   What is Community Content?
Add new content RSS  Annotations
Question reg baseAddress      Kris K ... Praveen Chellaboina   |   Edit   |   Show History
In the service implementation it uses ConfigurationManager.AppSettings["baseAddress"]) but I don't see baseAddress defined in the config file.
Tags What's this?: Add a tag
Flag as ContentBug
WCF client - Reorganized code      Siva Muniappan   |   Edit   |   Show History
Instantiating OrderProcessorClient was slightly confusing in the code sample above. Thought of reorganizing a bit.

OrderProcessingClient.cs

public class OrderProcessorClient

{

ChannelFactory<IOrderProcessor> channelFactory = null;

private string bindingConfiguration = String.Empty;

public OrderProcessorClient(string bindingConfiguration)

{

this.bindingConfiguration = bindingConfiguration;

}


public void SubmitOrder(PurchaseOrder po)

{

MsmqIntegrationBinding binding = new MsmqIntegrationBinding(this.bindingConfiguration);

EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders");

channelFactory = new ChannelFactory<IOrderProcessor>(binding, address);

IOrderProcessor channel = channelFactory.CreateChannel();

MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);

using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))

{

channel.SubmitPurchaseOrder(ordermsg);

scope.Complete();

}

Console.WriteLine("Order has been submitted:\n{0}", po);

}

public void Close()

{

channelFactory.Close();

}

}

Program.cs

static void Main(string[] args)

{

// Create the purchase order.

PurchaseOrder po = new PurchaseOrder();

po.CustomerId = "somecustomer.com";

po.PONumber = Guid.NewGuid().ToString();

PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();

lineItem1.ProductId = "Blue Widget";

lineItem1.Quantity = 54;

lineItem1.UnitCost = 29.99F;

PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();

lineItem2.ProductId = "Red Widget";

lineItem2.Quantity = 890;

lineItem2.UnitCost = 45.89F;

po.orderLineItems = new PurchaseOrderLineItem[2];

po.orderLineItems[0] = lineItem1;

po.orderLineItems[1] = lineItem2;

OrderProcessorClient client = new OrderProcessorClient("OrderProcessorBinding");

client.SubmitOrder(po);

//Closing the client gracefully closes the connection and cleans up resources.

client.Close();

Console.WriteLine();

Console.WriteLine("Press <ENTER> to terminate client.");

Console.ReadLine();

}

App.config

<configuration>

<system.serviceModel>

<client>

<endpointname="OrderResponseEndpoint"

address="msmq.formatname:DIRECT=OS:.\private$\Orders"

binding="msmqIntegrationBinding"

bindingConfiguration="OrderProcessorBinding"

contract="MsmqService.IOrderProcessor">

</endpoint>

</client>


<bindings>

<msmqIntegrationBinding>

<bindingname="OrderProcessorBinding" >

<securitymode="None" />

</binding>

</msmqIntegrationBinding>

</bindings>

</system.serviceModel>

</configuration>

Tags What's this?: Add a tag
Flag as ContentBug
Need to link to full sample code      natebell   |   Edit   |   Show History
You need to have a link to the complete sample code. This code doesn't work by itself.
Tags What's this?: Add a tag
Flag as ContentBug
Processing
© 2009 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement
Page view tracker