NancyFx/Nancy — pull request #1251 by justinvp (2013-10-04 16:35:48+00:00)
Title: Fix the WCF Host so it can be used with Microsoft.ServiceBus.WebHttpRelayBinding (Azure Service Bus Relay)

Microsoft provides [`Microsoft.ServiceBus.WebHttpRelayBinding`](http://msdn.microsoft.com/en-us/library/microsoft.servicebus.webhttprelaybinding.aspx), a replacement for `WebHttpBinding` that can be used to easily expose an on-premise WCF service to the public cloud using the [Windows Azure Service Bus Relay](http://www.windowsazure.com/en-us/develop/net/how-to-guides/service-bus-relay/).

I was trying to use this in conjunction with `Nancy.Hosting.Wcf.NancyWcfGenericService` to expose a Nancy-based REST API via the Service Bus Relay.

For example:

```c#
const string address = "https://**namespace**.servicebus.windows.net/nancy/";
const string issuer = "owner";
const string key = "**secret key**";

var host = new WebServiceHost(new NancyWcfGenericService());

var e = host.AddServiceEndpoint(
typeof(NancyWcfGenericService),
new WebHttpRelayBinding(
EndToEndWebHttpSecurityMode.None,
RelayClientAuthenticationType.None),
new Uri(address));

e.Behaviors.Add(
new TransportClientEndpointBehavior(
TokenProvider.CreateSharedSecretTokenProvider(issuer, key)));

host.Open();
```

However, when using `NancyWcfGenericService` with `WebHttpRelayBinding` an `ArgumentException` is always thrown inside `NancyWcfGenericService` with a message saying *"A property with the name 'System.ServiceModel.Channels.RemoteEndpointMessageProperty' is not present."*

This is the offending code inside `NancyWcfGenericService.CreateNancyRequestFromIncomingWebRequest`:

```c#
var address =
((RemoteEndpointMessageProperty)
OperationContext.Current.IncomingMessageProperties[RemoteEndpointMessageProperty.Name]);
```

This code is used to get the ip address of the request. But it looks like RemoteEndpointMessageProperty isn't included in the IncomingMesageProperties dictionary when using `WebHttpRelayBinding`.

The ArgumentException can be avoided by using `TryGetValue` instead of the dictionary's indexer. For example:

```c#
string ip = null;

object remoteEndpointProperty;
if (OperationContext.Current.IncomingMessageProperties.TryGetValue(RemoteEndpointMessageProperty.Name, out remoteEndpointProperty))
{
ip = ((RemoteEndpointMessageProperty)remoteEndpointProperty).Address;
}
```