Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using WCF on Localhost on Azure

In summary
How do I acces a WCF service on localhost when hosted in IIS on Azure? Azure does not bind localhost or 127.0.0.1 to my website.

Details
I have an ASP.Net application hosted on Azure. I have added a .svc and some workflows that I want to use via WCF. To keep matters simple, my web app simply calls the service on localhost, so I have endpoints like these in web.config;

<client>
  <endpoint address="http://localhost:8080/Router.svc/Case" binding="basicHttpBinding" contract="NewOrbit.ExVerifier.Model.Workflow.Case.ICaseWorkflow" name="Case" />
  <endpoint address="http://localhost:8080/Workflow/Case/Case_default1.xamlx" binding="basicHttpBinding" contract="*" name="Case_default1" />
</client>

This works just fine on my local machine. The problem is that when I publish this to Azure, the Website in IIS does not get a binding to localhost, instead the bindings are always to the actual IP address of the server. It ends up looking like this in applicationHost.config:

<bindings>
   <binding protocol="http" bindingInformation="10.61.90.44:80:" />
   <binding protocol="https" bindingInformation="10.61.90.44:443:" />
   <binding protocol="http" bindingInformation="10.61.90.44:8081:" />
</bindings>

So, as soon as my web app tries to call the service on localhost (or 127.0.0.1 for that matter) it fails instantly. Needless to say, if I rdp on to the server and change the binding then all is fine.

What I find really odd is that there are tons of examples out there where people are accessing WCF services on localhost on Azure so I can't figure out why this is so. I have set the osFamily to 2 and in order to debug this I have enabled web publishing and remote desktop access which I guess, in theory, could mess things up.

What I have already looked at

  • I can rewrite the end-point address in my code at runtime to substitute localhost for the actual address or create the endpoint dynamically as described by Ron in the answers. Unfortunately I am using the WCF Routing service so I can version workflows. This means that my code calls the Router endpoint and the WCF Router in turns calls the actual service/workflow using an endpoint specified in web.config. I don't have control over the Routing services endpoint resolution without, I think, writing a whole set of routing logic which just seems to be a lot of work when all I want is to call localhost :)
  • Switching to using named pipes; Alas, it causes some strange issues with workflows, probably due to duplexing, and I am on a deadline so haven't got time to get to the bottom of that at the minute.
like image 915
flytzen Avatar asked Dec 02 '11 07:12

flytzen


People also ask

How do I create a WCF service in Windows Azure?

To start with, create a new Windows Azure Project (under the installed templates -> Visual C# -> cloud). Call the project WindowsAzureWCFDemo. Click OK. On the “New Windows Azure Project dialog”, select WCF Service Web Role and add it to the solution.

Why Azure relay for WCF?

Many internal services aren't built or hosted in a way that they can be easily exposed at the corporate network edge. Azure Relay takes existing WCF web services and makes those services securely accessible to solutions that are outside the corporate perimeter without requiring intrusive changes to the corporate network infrastructure.

How do I secure a service when using WCF?

To help secure a service when you're using a WCF-based communication stack, follow these steps: For the service, you need to help secure the WCF communication listener ( WcfCommunicationListener) that you create. To do this, modify the CreateServiceReplicaListeners method.

How to add a service reference to a WCF service?

Now add a Service Reference to the project as shown below. You need to right click on Reference and select “Add service reference…”. Next, enter the URI of the service in the Address field and click GO. Here you can also enter the cloud URI of your service if you have already packaged and deployed your WCF service to the Azure cloud.


Video Answer


2 Answers

You have to build the endpoint address dynamically.

Step 1: In your ServiceDefinition.csdef you need to declare an Endpoint.

<ServiceDefinition name="MyFirstAzureWorkflow" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="WorkflowWeb" vmsize="ExtraSmall">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="WorkflowService" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="WorkflowService" protocol="http" port="80" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
  </WebRole>
</ServiceDefinition>

Step 2: When you want to call the service

var endpoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["WorkflowService"].IPEndpoint;
var uri = new Uri(string.Format(
    "http://{0}:{1}/MyService.xamlx",
    endpoint.Address,
    endpoint.Port));
var proxy = new ServiceClient(
    new BasicHttpBinding(),
    new EndpointAddress(uri));
like image 140
Ron Jacobs Avatar answered Sep 25 '22 02:09

Ron Jacobs


Okay, so this is how I solved it. IMHO it's a hack but at least it works.

Basically, I need to add a "*" binding, so I can do this in Powershell. The general recipe is here: http://blogs.msdn.com/b/tomholl/archive/2011/06/28/hosting-services-with-was-and-iis-on-windows-azure.aspx

That deals with adding Named Pipes support, but the principle is the same. I just changed the Powershell script to:

import-module WebAdministration
# Set up a binding to 8080 for the services 
Get-WebSite "*Web*" | Foreach-Object { 
  $site = $_;
  $siteref = "IIS:/Sites/" + $site.Name;
  New-ItemProperty $siteref -name bindings -value @{protocol="http";bindingInformation="*:8080:"}
}

This now allows me to use http://127.0.0.1:8080/service.svc to access my service.

Note: You do need to follow the rest of the recipe to set elevated execution context and change the powershell execution mode, so do follow it carefully

like image 26
flytzen Avatar answered Sep 27 '22 02:09

flytzen