Introduction

The following illustrates a way to connect to an Azure ServiceBus Queue using a WebClient instead of using the latest APIs supplied in the Azure SDK.  The primary reason for this is to illustrate connectivity from clients that either are not .net based or are limited in their version of .Net.

In this particular situation, we're integrating the Unity 3D game engine which does not support .NET 4.0 as it runs on Mono.  This required us to create a client using  .NET Framework 3.5 and to use a WebClient to post messages to the queue. As well as requiring a change to the client, we also needed to configure my ServiceBus namespace to support ACS.

In August 2014, new namespace's created in the Azure portal stopped supported ACS by default.  As there is no way of adding ACS support, ACS support must be specified when the namespace is created.  More information is supplied in MSDN here.

Sample Project

You will need an Azure subscription and the ability to create a new Service Bus namespace.  Because of this Azure Powershell is also required.

There are not any requirements for additional packages from NuGet.

A sample project is available for download from the MSDN Gallery.

Client

The solution contains two projects: a SBClient project and unity test project.  The SBClient illustrates a simple post of a message to an Azure Service Bus Queue using the WebClient class.  The code snippet below shows the actual post is very straightforward:

public static bool SubmitEvent(string payload)
{
    WebClient webClient = new WebClient();
    webClient.Headers[HttpRequestHeader.Authorization] = GetToken();
 
    var response = webClient.UploadData(ServiceHttpAddress, "POST", System.Text.Encoding.Default.GetBytes(payload));
    string responseString = Encoding.UTF8.GetString(response);
 
    return string.IsNullOrEmpty(responseString);
}
 
 

The GetToken method takes a bit more explaining.  MSDN does a better job here.  In our terms, we again use an instance of WebClient to get a token to from the our ACS endpoint in Azure.

private static string GetToken()
 
{
    var acsEndpoint = "https://" + ServiceNamespace + "-sb." + acsHostName + "/WRAPv0.9/";
 
    // Note that the realm used when requesting a token uses the HTTP scheme, even though
    // calls to the service are always issued over HTTPS
    var realm = "http://" + ServiceNamespace + "." + sbHostName + "/";
 
    NameValueCollection values = new NameValueCollection();
    values.Add("wrap_name", issuerName);
    values.Add("wrap_password", issuerSecret);
    values.Add("wrap_scope", realm);
 
    WebClient webClient = new WebClient();
    byte[] response = webClient.UploadValues(acsEndpoint, values);
 
    string responseString = Encoding.UTF8.GetString(response);
 
    var responseProperties = responseString.Split('&');
    var tokenProperty = responseProperties[0].Split('=');
    var token = Uri.UnescapeDataString(tokenProperty[1]);
 
    return "WRAP access_token=\"" + token + "\"";
}
 
In the class there are several strings that will need to be updated with values from the particular Azure ServiceBus namespace (where to locate the values is explained below when setting up Azure):
static string ServiceNamespace = "<namespace name>";
static string ServiceHttpAddress = "https://<;namespace name>.servicebus.windows.net/<queue name>/messages";
  
const string acsHostName = "accesscontrol.windows.net";
const string sbHostName = "servicebus.windows.net";
  
const string issuerName = "<service identity name>";
const string issuerSecret = "<service identity password>";

Unit Test

The unit test is a bit simple but it does what we need it to do for this sample.

[TestClass]
public class ServiceBusWriterTests
{
    [TestMethod]
    public void PostNewMessage()
    {
        var wasSuccessful = ServiceBusWriter.SubmitEvent("This is a test.");
  
        Assert.IsTrue(wasSuccessful);
    }
}

Setting Up Azure Service Bus

Now for the interesting part.  The first step is to launch Azure PowerShell and add your Azure account using the Add-AzureAccount command:

         Assert.IsTrue(wasSuccessful);