Send Messages from TopicClient to WCF Subscription Service

How to send Message to ServiceBus topic using TopicClient and receive it with WCF as Subscription Service that acts as a Subscription client, without the use of SubscriptionClient classes of Service Bus?

Relevant Facts and Documentaion:

Solution:

Since the sender and receiver are based on two different technologies we have to make sure the encoding on both sides match and a WCF data contract is defined. Please follow the steps below. Also, here's a good blog where Abhishek (from Service Bus product group) talks about different ways of formatting the content for Service Bus Messages - https://abhishekrlal.com/2012/03/30/formatting-the-content-for-service-bus-messages/

  • Define the data contract

   static class Constants

    {

        public const string ContractNamespace = "urn:wcsubscriptionservice";

    }

 

    [DataContract(Namespace = Constants.ContractNamespace)]

    public class TestMessage

    {

        [DataMember]

        public string MsgNumber { get; set; }

        [DataMember]

        public string MsgContent { get; set; }

 

    }

  •  Format the brokered message when sending from client.

    BrokeredMessage message = new BrokeredMessage(new TestMessage() { MsgNumber = 1, MsgContent = "Test Message" }, new DataContractSerializer(typeof(TestMessage)));

                     // Send message to the topic

                     topicClient.Send(message);

  • Set the ListenURI in WCF Service:

……………………       

private static Uri serviceBusEndpointAddress = new Uri("sb://<namespace>.servicebus.windows.net/<topic>");

        private static Uri subscriptionUri = new

Uri("sb://<namespace>.servicebus.windows.net/<topic>/subscriptions/<subscription>");

 

……………………….

           var endpoint = new ServiceEndpoint(contract, binding, new

EndpointAddress(serviceBusEndpointAddress.AbsoluteUri));

            endpoint.ListenUri = subscriptionUri;

            endpoint.Behaviors.Add(transportBehavior);

            endpoint.Name = "ReceiveMessage";

 

  • Manually Control the Receive Context, if you would like the user code to control the incoming message for any further processing purposes.

 [ServiceContract(Namespace="urn:wcsubscriptionservice")]

    public interface IServiceBusReader

    {

        [OperationContract(IsOneWay = true, Action = "*"), ReceiveContextEnabled(ManualControl = true)]

        void ReceiveMessage(TestMessageContract someMsg);

    }

     

    [ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]

    public class ServiceBusReader : IServiceBusReader

    {

        public void ReceiveMessage(TestMessageContract someMsg)

        {

            TestMessage msg = someMsg.TestMessage;

            var incomingProperties = OperationContext.Current.IncomingMessageProperties;

            var property = incomingProperties[BrokeredMessageProperty.Name] as BrokeredMessageProperty;

            ReceiveContext receiveContext;

            if (ReceiveContext.TryGet(incomingProperties, out receiveContext))

            {

                receiveContext.Complete(TimeSpan.FromSeconds(10.0d));

            }

            else

            {

                throw new InvalidOperationException("...");

            }        

        }

    }

 

I've attached the sample code, please feel free to use it. Just make sure, you input the values for service bus namespace, key, topic name and subscription name.

Files: TopicSender.cs, WCFSubscriptionService.cs

TopicSenderAndWCFReceive.zip