tags:

views:

1199

answers:

2

I have an IIS hosted WCF service (configured as described in this blog post ... I need to know what the configured endpoint's URL is. For example, given this configuration:

  <system.serviceModel>
    <services>
      <service behaviorConfiguration="mexBehavior" name="Sc.Neo.Bus.Server.MessageProxy">
        <endpoint address="http://localhost:9000/MessageProxy.svc" binding="basicHttpBinding"
          contract="Sc.Neo.Bus.IMessageProxy" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="BusWeb.Service1Behavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
        <behavior name="mexBehavior">
          <serviceMetadata httpGetEnabled="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

I'd like to be able to get the value 'http://localhost:9000/MessageProxy.svc' into a string variable in the web application's onstart event.

+3  A: 

OK so the short answer is "you can't". The longer answer is you can, kind of, with a bit of work.

If you're hosting this outside of IIS it's actually reasonable to load the configuration section itself and parse it, as you can cast it to the WCF configuration class:

ServiceModelSectionGroup serviceModelGroup =
      cfg.GetSectionGroup("system.serviceModel") 
            as ServiceModelSectionGroup;

Somewhat messy but it does work. The problem comes with IIS - IIS hosted services inherit their address from IIS and will ignore fully qualified addresses in any configuration file.

But you can cheat, you could use a custom service host factory. This does mean changing your service startup code, in either code or the .svc file for IIS. A custom service host factory deriveds from ServiceHostFactory and overrides

protected override ServiceHost CreateServiceHost(Type serviceType, 
                                                 Uri[] baseAddresses)

As you can see you're getting one or more URI objects containing the (potential) addresses of your service. At this point you can store them somewhere (singleton lookup table perhaps) against the service type and then query that elsewhere.

Then in your .svc file you need to change it just a little; for example

<%@ServiceHost Service="MyService.ServiceName" 
               Factory="MyService.ServiceHostFactory" %>
<%@Assembly Name="MyService" %>
blowdart
A: 

If you are already have an instance of your service proxy created, you can use the following:

    public static Uri GetServiceUri(this IMyService proxy)
    {
        var channel = proxy as IContextChannel;
        return 
              channel != null && channel.RemoteAddress != null ? 
                 channel.RemoteAddress.Uri : null;
    }
Dmitry Frenkel