Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

Adding a WCF MetaData EndPoint programmatically


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.

 

Make Donation
Posted in WCF  


Feedback for this Post

 
# re: Adding a WCF MetaData EndPoint programmatically
by Eric Dauth February 23, 2008 @ 2:39pm
Somehow I allways end up on your site whenever WPF/WCF gets intricate.
Thanks for this blurp. just what I was looking for!
Eric
# re: Adding a WCF MetaData EndPoint programmatically
by Vinoth Bellie September 04, 2008 @ 6:23am
Just replace your service metadata element as below

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

Hope this solves your issue
# re: Adding a WCF MetaData EndPoint programmatically
by Nofian Adi December 25, 2008 @ 9:31am
can we make custom host factory for workflow service?
# re: Adding a WCF MetaData EndPoint programmatically
by Allen August 28, 2009 @ 2:39pm
Exactly what i was looking for. You are the man! Thanks for posting.
# Hosting WCF service as a Windows Service
by My Dev Notes April 17, 2010 @ 9:27pm
Hosting WCF service as a Windows Service
 


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