WCF relative endpoint address exposed over all base addresses no matter binding used
I have this self hosted service. In the app.config I have two base addresses defined. One for http and one for net.tcp.
One contract is exposed through two endpoints, one with a basicHttpBinding and the other with a netTcpBinding.
Now, the strange thing is that both endpoints are available at both baseaddresses. If I connect to either endpoint with the wcfclient.exe application both endpoints show up. Ie basicHttpBinding over net.tcp and the other way around.
Why is this and can I do anything about it?
The config for reference.
<configuration>
<system.serviceModel>
<services>
<service name="FileServer.BookService" behaviorConfiguration="serviceMetadata">
<host>
<baseAddresses>
<add baseAddress="http://localhost"/>
<add baseAddress="net.tcp://localhos开发者_开发技巧t"/>
</baseAddresses>
</host>
<endpoint address="BookService"
binding="netTcpBinding"
contract="FileServer.IBookService">
</endpoint>
<endpoint address="BookService/mex"
binding="mexTcpBinding"
contract="IMetadataExchange">
</endpoint>
<endpoint address="BookService"
binding="basicHttpBinding"
contract="FileServer.IBookService">
</endpoint>
<endpoint address="BookService/mex"
binding="mexHttpBinding"
contract="IMetadataExchange">
</endpoint>
<endpoint address="basic"
binding ="basicHttpBinding"
contract="FileServer.ITest">
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="serviceMetadata">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The WcfTestClient application will download the metadata information from the service, and the service itself has three endpoints - so the client is showing three endpoints, not two services. Even if you expose the metadata via two different places, the metadata is not relative to an endpoint or to a base address, but to the service host itself.
If you want a client getting the metadata from the HTTP address to get only the HTTP endpoint (and the same for TCP), you can use two hosts, like in the example below.
public class Post_09851985_ee54_4627_9af7_6a9505c2067f
{
[DataContract]
public class Person
{
[DataMember]
public string name;
[DataMember]
public string address;
}
[ServiceContract]
public interface ITest
{
[OperationContract]
Person Echo(Person person);
}
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class Service : ITest
{
public Person Echo(Person person)
{
return person;
}
}
public static void SingleHost()
{
string baseAddressHttp = "http://" + Environment.MachineName + ":8000/Service";
string baseAddressTcp = "net.tcp://" + Environment.MachineName + ":8008/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddressHttp), new Uri(baseAddressTcp));
host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic");
host.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(SecurityMode.None), "tcp");
host.Description.Behaviors.Add(new ServiceMetadataBehavior());
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
host.Open();
Console.WriteLine("Host opened");
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
host.Close();
}
public static void TwoHosts()
{
string baseAddressHttp = "http://" + Environment.MachineName + ":8000/Service";
string baseAddressTcp = "net.tcp://" + Environment.MachineName + ":8008/Service";
ServiceHost httpHost = new ServiceHost(typeof(Service), new Uri(baseAddressHttp));
ServiceHost tcpHost = new ServiceHost(typeof(Service), new Uri(baseAddressTcp));
httpHost.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic");
tcpHost.AddServiceEndpoint(typeof(ITest), new NetTcpBinding(SecurityMode.None), "tcp");
httpHost.Description.Behaviors.Add(new ServiceMetadataBehavior());
tcpHost.Description.Behaviors.Add(new ServiceMetadataBehavior());
httpHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
tcpHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexTcpBinding(), "mex");
httpHost.Open();
tcpHost.Open();
Console.WriteLine("Host opened");
Console.WriteLine("Press ENTER to close");
Console.ReadLine();
httpHost.Close();
tcpHost.Close();
}
public static void Test()
{
TwoHosts();
}
}
精彩评论