I have been tasked to Expose my service that reside on a network that is behind a firewall. Obvious choice was to utilize Azure Service Bus. The Relay mechanism provided by the service bus is a real magical scenerio that a developer can ever have.

The first demo i created was using netTCP binding mechanism. That sure is fast but the requirement was to do with BasicHttpRelayBinding. So let me guide you step by step how to do it.

Steps:

1- Login to Azure portal using the credentials of your subscription.

2- Click on the option from left panel “Service Bus, Access Control & Caching”.

3- Selecting Option “New”, will open a dialog to create a new ServiceBus namespace. Provide a name in namespace. Check for availability of namespace. Select the region. Choose your subscription and click “Create Namespace” button. This will start creatig a namespace for you.

4- Once your Service Bus is active, click on “Default Key” Button on bottom right.

Note down the “Default Issuer” and “Default Key” values. We will use in our code to connect and relay messages with the service bus.

5- Now comes the coding part. We will first create a Server and than we will create a client.

SERVER:

First create a Server app that will be a Console Application.

a- In the console app, add new item that would be a WCF Service.

It will create two classes IService1.cs and Service1.cs, plus some modifications in the web.config file.

Lets see the code of IService1.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;

namespace testServer {

[ServiceContract(Name = “IService1”, Namespace = “https://test.servicebus.windows.net/Service1/“)]

public interface IService1

{

[OperationContract, WebGet]

string GetData();

}

}

 Lets now see the Service Implementation:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.Text;

namespace testServer {

public class Service1 : IService1     {

public string GetData()

{

return “Hello World”;

}

} }

So the service method will just be returning a hello world to the client.

Lets see the code of our program.cs, which will actually host this service and bind with Service Bus relay through basicwebhttprelaybinding

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using Microsoft.ServiceBus;

using System.ServiceModel.Web;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

using System.ServiceModel.Channels;

using System.Xml;

using System.IO;

using System.ServiceModel;

namespace testServer

{

class Program

{

static void Main(string[] args)

{

ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;

// Configure the credentials for the service and client endpoints through an endpoint behavior.

var endPoint = new TransportClientEndpointBehavior();

endPoint.CredentialType =TransportClientCredentialType.SharedSecret;

endPoint.Credentials.SharedSecret.IssuerName =“owner”;

endPoint.Credentials.SharedSecret.IssuerSecret =“[your secret key you copied from Step 4]”;

// Create the binding with custom settings.

var binding = new BasicHttpRelayBinding();

binding.Security.RelayClientAuthenticationType =RelayClientAuthenticationType.RelayAccessToken;

// Get the service URI.       [below testServer is the namespace of Service bus we created in Azure in start]

var address = ServiceBusEnvironment.CreateServiceUri(“https”, “testServer”, “Service1”);

// Create the web service host.

var host = new WebServiceHost(typeof(Service1), address);

// Add the service endpoint with the WebHttpRelayBinding binding.

host.AddServiceEndpoint(typeof(IService1), binding, address);

// Add the credentials through the endpoint behavior.

host.Description.Endpoints[0].Behaviors.Add(endPoint);

//host.Description.Endpoints[0].Behaviors.Add(new MyBehavior());

host.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpsGetEnabled = true });

ServiceRegistrySettings settings = new ServiceRegistrySettings();

settings.DiscoveryMode =DiscoveryType.Public;

foreach (ServiceEndpoint s in host.Description.Endpoints)

s.Behaviors.Add(settings);

ServiceDebugBehavior debug = host.Description.Behaviors.Find<ServiceDebugBehavior>();

// if not found – add behavior with setting turned on 

if (debug == null)

{

host.Description.Behaviors.Add(new ServiceDebugBehavior() { IncludeExceptionDetailInFaults = true });

}

else

{

// make sure setting is turned ON

if (!debug.IncludeExceptionDetailInFaults)

{

debug.IncludeExceptionDetailInFaults =true;

}

}

// Start the service.

host.Open();

    Console.WriteLine(“Copy the following address into a browser to see the data: “);

    Console.WriteLine(address );

    Console.WriteLine();

    Console.WriteLine(“Press [Enter] to exit”);

Console.ReadLine();

host.Close();

}

}

That is all from the Server End, we will just run the project on the Server.

Now comes the client part. We need the Service proxy class on the client to communicate with the WCF Service on the Server.

We can generate on by typing the following command in the comand prompt

svcutil.exe http://localhost:62343/Service/Service1.svc /d :c:\filestosavehere\  [ path could be different based on your settings and parameters ]

Create a project on client with name testClient and copy the Service1.cs file generated in the client project.

Open program.cs on client project and use the following code.

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.ServiceModel;

using System.ServiceModel.Channels;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

using System.ServiceModel.Web;

using System.Text;

using System.Xml;

using Microsoft.ServiceBus;

using Microsoft.ServiceBus.Description;

namespace testClient

{

class Program

{

static void Main(string[] args)

{

ServiceBusEnvironment.SystemConnectivity.Mode = ConnectivityMode.Http;

var relayCredentials = new TransportClientEndpointBehavior

{

CredentialType =TransportClientCredentialType.SharedSecret

};

relayCredentials.Credentials.SharedSecret.IssuerName =“owner”;

relayCredentials.Credentials.SharedSecret.IssuerSecret =“xAWjynZU8AhbjcSyzSgUmRxIk9JNNsQDY6O+CyiXCo0=”;

relayCredentials.Credentials.SimpleWebToken.SimpleWebToken =SharedSecretCredential.ComputeSimpleWebTokenString(“owner”, “xAWjynZU8AhbjcSyzSgUmRxIk9JNNsQDY6O+CyiXCo0=”) ;

var binding = new BasicHttpRelayBinding();

binding.Security.RelayClientAuthenticationType =RelayClientAuthenticationType.RelayAccessToken;

using (var cf = new ChannelFactory<IService1>(binding,new EndpointAddress(ServiceBusEnvironment.CreateServiceUri(“https”, “testServer”, “Service1”))))

{

cf.Endpoint.Behaviors.Add(relayCredentials);

      var ch = cf.CreateChannel();

      Console.WriteLine(ch.GetData());

      Console.ReadKey();

}

}

}

}

}

To run, first run the server on the server machine, that will host it and bind with service bus endpoint, next you run the client code that will communicate with Service bus endpoint and do the magic.

Here it goes, i have shared this code as i made it happen after lot of brain storming, head banging to laptop screen, google surfing, copy pasting, trying this and that.. and at last, it worked. And i was able to call the service behind the firewall through Service Bus Relay.