views:

37

answers:

2

I'm creating a custom behaviour for WCF which can (for interoperability reasons) only function correctly when a service exposes a single application endpoint.

I would like to be able to use the IServiceBehavior.Validate method to check that only one application endpoint is exposed by the service. Currently I'm doing the following:

public void Validate(
    ServiceDescription serviceDescription, 
    ServiceHostBase serviceHostBase)
{
    if (serviceDescription.Endpoints.Count > 1)
    {
        throw new InvalidOperationException();
    }
}

serviceDescription.Endpoints unfortunately contains all the endpoints, including the IMetadataExchange endpoint. This causes the validation to fail on perfectly valid services.

What I need is a way to only count the application (non-infrastructure) endpoints, but I cannot find how WCF itself determines which are which.

+1  A: 

I've done this in the past like I outlined in this article.

tomasr
Your implementation actually seems to go a trick further than WCF, checking for the WSDL namespace as well as the Mex endpoint.
Programming Hero
+1  A: 

Whilst working around this problem, I managed to reproduce the infamous:

Service 'Service' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.

The exceptions shows a method EnsureThereAreNonMexEndpoints is called on a System.ServiceModel.Description.DispatchBuilder object which causes the exception to be thrown.

Digging into this method with Reflector, I've reverse-engineered the following implementation that expresses the equivalent functionality:

private void EnsureThereAreNonMexEndpoints(ServiceDescription description)
{
    foreach (ServiceEndpoint endpoint in description.Endpoints)
    {
        if (endpoint.Contract.ContractType != typeof(IMetadataExchange))
        {
            return;
        }
    }

    throw InvalidOperationException();
}

It would appear that the only endpoint considered infrastructure by WCF is IMetadataExchange. Huh.

The more you know.

Programming Hero