mex binding error in WCF

2019-02-02 01:43发布

问题:

I am using VSTS 2008 + C# + .NET 3.0. I am using a self-hosted WCF service. When executing the following statement, there is the following "binding not found" error. I have posted my whole app.config file, any ideas what is wrong?

ServiceHost host = new ServiceHost(typeof(MyWCFService));

Error message:

Could not find a base address that matches scheme http for the endpoint with binding MetadataExchangeHttpBinding. Registered base address schemes are [https].

Full app.config:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <bindings>
      <wsHttpBinding>
        <binding name="MyBinding"
            closeTimeout="00:00:10"
            openTimeout="00:00:20"
            receiveTimeout="00:00:30"
            sendTimeout="00:00:40"
            bypassProxyOnLocal="false"
            transactionFlow="false"
            hostNameComparisonMode="WeakWildcard"
            maxReceivedMessageSize="100000000"
            messageEncoding="Mtom"
            proxyAddress="http://foo/bar"
            textEncoding="utf-16"
            useDefaultWebProxy="false">
          <reliableSession ordered="false"
               inactivityTimeout="00:02:00"
               enabled="true" />
          <security mode="Transport">
            <transport clientCredentialType="Digest"
               proxyCredentialType="None"
               realm="someRealm" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="MyWCFService"
                behaviorConfiguration="mexServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:9090/MyService"/>
          </baseAddresses>
        </host>
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="MyBinding" contract="IMyService"/>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexServiceBehavior">
          <serviceMetadata httpGetEnabled="True"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

回答1:

The base address for your service defines "HTTPS://" - but your mex address is "HTTP".

If you want your service to use https://, you'll need to use the mexHttpsBinding as well:

<services>
    <service name="MyWCFService" behaviorConfiguration="mexServiceBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="https://localhost:9090/MyService"/>
          </baseAddresses>
        </host>
        <endpoint address="" 
                binding="wsHttpBinding" 
                bindingConfiguration="MyBinding" 
                contract="IMyService" 
        />
        <endpoint address="mex" 
                binding="mexHttpsBinding" 
                contract="IMetadataExchange" 
        />
    </service>
</services>

Marc



回答2:

Can I go for the double score? :)

As you're using WS-Http you are binding to an HTTPS protocol, so you need to use the correct MEX binding;

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


回答3:

I've asked a question in a comment  for Marc_s answer

Is it possible to have IMetadataExchange for both http and https as separate endpoints?

 marc_s answered 

you should be able to define a second base address, for http:// and use that for the http mex endpoint.

So solution is to declare multiple endpoints with the SAME address="mex" and different bindings like the following

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

Recently I found that it's easier to have one configuration switch that can be used to enable MEX on test and disable on Live.

From http://msdn.microsoft.com/en-us/library/aa395224.aspx

It's possible to use the ServiceHostFactory class to create a custom derived from ServiceHost in the Internet Information Services (IIS custom ServiceHost that adds the ServiceMetadataBehavior, (which enables metadata publishing), even if this behavior is not explicitly added in the service’s configuration file.

 Write the imperative code that enables metadata publishing once and then reuse that code across several different services. This is accomplished by creating a new class that derives from ServiceHost and overrides the ApplyConfiguration() method to imperatively add the metadata publishing behavior.

Example code from Custom Service Host MSDN article

//Add a metadata endpoint at each base address
//using the "/mex" addressing convention
foreach (Uri baseAddress in this.BaseAddresses)
{
    if (baseAddress.Scheme == Uri.UriSchemeHttp)
    {
        mexBehavior.HttpGetEnabled = true;
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexHttpBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeHttps)
    {
        mexBehavior.HttpsGetEnabled = true;
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexHttpsBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeNetPipe)
    {
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexNamedPipeBinding(),
                                "mex");
    }
    else if (baseAddress.Scheme == Uri.UriSchemeNetTcp)
    {
        this.AddServiceEndpoint(ServiceMetadataBehavior.MexContractName,
                                MetadataExchangeBindings.CreateMexTcpBinding(),
                                "mex");
    }
}