Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
Markdown Monster - The Markdown Editor for Windows

Adding a WCF MetaData EndPoint programmatically


:P
On this page:

I’m working on a front end routine that hosts a WCF service in a managed application. Basically I’m using COM interop into a .NET class that acts as a front end for the service so the service can be started and stopped from the managed application (VFP app).

 

It actually was surprisingly easy to get this to work and seems to work fairly reliably. However one problem I ran into was dealing with the host configuration. Most of the documentation shows how to configure most things via Configuration settings which is usually more flexible. But due to the COM interface and issues with where the runtime files actually launch I needed to bypass the .config settings and do manual configuration.

 

Manually starting up a service is easy enough (and described in many places) but manually configuring the MetaData endpoint that provides the WSDL that describes the service is not. I kept looking for a specific binding, but as it turns out the real requirement is the ServiceMetaDataBehavior class as shown below in the COM Interop target method that launches the service:

 

public bool Open(string EndPointAddress)

{

    if (string.IsNullOrEmpty(EndPointAddress))

        EndPointAddress = "http://localhost:8001/WcfFoxService";

 

    Uri BaseAddress = new Uri(EndPointAddress);

 

    this.Host = new ServiceHost(typeof(WcfFoxService), BaseAddress);

 

    if (EndPointAddress.StartsWith("net.tcp"))

        this.Host.AddServiceEndpoint(typeof(IWcfFoxService),

                    new NetTcpBinding(),

                    "WcfFoxServiceTcp");

    else if (EndPointAddress.StartsWith("http") )

        this.Host.AddServiceEndpoint(typeof(IWcfFoxService),

                              new WSHttpBinding(),

                              "WcfFoxServiceHttp");

      

 

    else if (EndPointAddress.StartsWith("net.pipe") )

        this.Host.AddServiceEndpoint(typeof(IWcfFoxService),

                    new NetNamedPipeBinding(),

                    "WcfHostServicePipe");

    else

    {

        ((IDisposable)this.Host).Dispose();

        return false;

    }

 

    ServiceMetadataBehavior smb = new ServiceMetadataBehavior();

    smb.HttpGetEnabled = true;

    smb.HttpGetUrl = new Uri(EndPointAddress);

    Host.Description.Behaviors.Add(smb);

 

    this.Host.Open();

 

    return true;

}

 

public void Close()

{

    if (this.Host != null)

    {

        this.Host.Close();

        this.Host = null;

    }

}

 

Using the ServiceMetadataBehavior did the trick and allowed the service to publish its service data.

 

Incidentally I couldn’t make the .config file settings work to do these equivalent settings over COM interop. The problem in this case is that the the host EXE is a runtime IDE (VFP9.EXE) so I had to rename the .Config file generated for my service client to VFP9.EXE.CONFIG. But even with these settings I still was unable to manage to get the MetaData Exchange endpoint to work:

 

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

    <system.serviceModel>

 

        <services>

            <service behaviorConfiguration="WcfFoxServiceBehaviors" name="WcfFoxService">

              <endpoint address="http://localhost:8000/wcfFoxService"

                        binding="wsHttpBinding"

                        contract="WcfFoxService.IWcfFoxService" />             

              <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

              <host>

                <baseAddresses>

                  <add baseAddress="http://localhost:8000/wcfFoxService"/>

                </baseAddresses>

              </host>

            </service>           

        </services>

      <behaviors>

        <serviceBehaviors>

          <behavior name="WcfFoxServiceBehaviors" >

            <!-- Add the following element to your service behavior configuration. -->

            <serviceMetadata httpGetEnabled="true" />

          </behavior>

        </serviceBehaviors>

      </behaviors>

    </system.serviceModel>

</configuration>

 

It looks like the host is seeing the .Config file because if I misconfigure something it balks at an invalid name or invalid value setting. But the Mex endpoint still doesn’t work with just the configuration settings. Can anybody see what I’m missing? I compared to a pure WCF .NET service where I have it working through Config and it looks the same.

 

Posted in WCF  

The Voices of Reason


 

Eric Dauth
February 23, 2008

# re: Adding a WCF MetaData EndPoint programmatically

Somehow I allways end up on your site whenever WPF/WCF gets intricate.
Thanks for this blurp. just what I was looking for!
Eric

Vinoth Bellie
September 04, 2008

# re: Adding a WCF MetaData EndPoint programmatically

Just replace your service metadata element as below

<serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:8080/Subsystem1/MEX" />

Hope this solves your issue

Nofian Adi
December 25, 2008

# re: Adding a WCF MetaData EndPoint programmatically

can we make custom host factory for workflow service?

Allen
August 28, 2009

# re: Adding a WCF MetaData EndPoint programmatically

Exactly what i was looking for. You are the man! Thanks for posting.

My Dev Notes
April 17, 2010

# Hosting WCF service as a Windows Service

Hosting WCF service as a Windows Service

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024