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.