I have a set of WCF web services connected to dynamically by a desktop application.
My problem is the really detailed config settings that WCF requires to work. Getting SSL to work involves custom settings. Getting MTOM or anything else to work requires more. You want compression? Here we go again...
WCF is really powerful - you can use a host of different ways to connect, but all seem to involve lots of detailed config. If host and client don't match perfectly you get hard to decipher errors.
I want to make the desktop app far easier to configure - ideally some kind of auto-discovery. The users of the desktop app should just be able to enter the URL and it do the rest.
Does anyone know a good way to do this?
I know Visual Studio can set the config up for you, but I want the desktop app to be able to do it based on a wide variety of different server set-ups.
I know that VS's tools can be used externally, but I'm looking for users of the desktop apps to not have to be WCF experts. I know MS made this intentionally over complicated.
Is there any way, mechanism, 3rd party library or anything to make auto-discovery of WCF settings possible?
Thanks, that was useful code (+1).
It's more than a little bit messy though, has some bugs (case sensitive checks that shouldn't be, for instance), has a load of UI functionality that I don't need and repeats a lot of code.
I've taken from it the actual discovery mechanism, re-wrote it and almost got it working (connects, but needs some finessing).
First some util functions used by the main method:
/// <summary>If the url doesn't end with a WSDL query string append it</summary>
static string AddWsdlQueryStringIfMissing( string input )
{
return input.EndsWith( "?wsdl", StringComparison.OrdinalIgnoreCase ) ?
input : input + "?wsdl";
}
/// <summary>Imports the meta data from the specified location</summary>
static ServiceEndpointCollection GetEndpoints( BindingElement bindingElement, Uri address, MetadataExchangeClientMode mode )
{
CustomBinding binding = new CustomBinding( bindingElement );
MetadataSet metadata = new MetadataExchangeClient( binding ).GetMetadata( address, mode );
return new WsdlImporter( metadata ).ImportAllEndpoints();
}
Then a method that tries different way to connect and returns the endpoints:
public static ServiceEndpointCollection Discover( string url )
{
Uri address = new Uri( url );
ServiceEndpointCollection endpoints = null;
if ( string.Equals( address.Scheme, "http", StringComparison.OrdinalIgnoreCase ) )
{
var httpBindingElement = new HttpTransportBindingElement();
//Try the HTTP MEX Endpoint
try { endpoints = GetEndpoints( httpBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
catch { }
//Try over HTTP-GET
if ( endpoints == null )
endpoints = GetEndpoints( httpBindingElement,
new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
}
else if ( string.Equals( address.Scheme, "https", StringComparison.OrdinalIgnoreCase ) )
{
var httpsBindingElement = new HttpsTransportBindingElement();
//Try the HTTPS MEX Endpoint
try { endpoints = GetEndpoints( httpsBindingElement, address, MetadataExchangeClientMode.MetadataExchange ); }
catch { }
//Try over HTTP-GET
if ( endpoints == null )
endpoints = GetEndpoints( httpsBindingElement,
new Uri( AddWsdlQueryStringIfMissing( url ) ), MetadataExchangeClientMode.HttpGet );
}
else if ( string.Equals( address.Scheme, "net.tcp", StringComparison.OrdinalIgnoreCase ) )
endpoints = GetEndpoints( new TcpTransportBindingElement(),
address, MetadataExchangeClientMode.MetadataExchange );
else if ( string.Equals( address.Scheme, "net.pipe", StringComparison.OrdinalIgnoreCase ) )
endpoints = GetEndpoints( new NamedPipeTransportBindingElement(),
address, MetadataExchangeClientMode.MetadataExchange );
return endpoints;
}
All information about the endpoint is available in metadata of a service, you can write a client what will explore the meta data of the service and will configure the client. For a code example you can look into this excellent Mex Explorer from Juval Lowy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With