I have a WCF Service which has it's configuration file as specified below:
<system.serviceModel>
<services>
<service name="WCFService.ServiceClass" behaviorConfiguration="metaDataSupport">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/WCFService"/>
<add baseAddress="net.tcp://localhost:8100/WCFService"/>
<add baseAddress="http://localhost:8101/WCFService"/>
</baseAddresses>
</host>
<endpoint address="tcpmex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<endpoint address="namedpipemex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange" />
<endpoint address=""
binding="wsHttpBinding"
contract="WCFService.IServiceClass" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metaDataSupport">
<serviceMetadata httpGetEnabled="false" httpGetUrl="" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
I have 3 types of binding here: NamedPipeBinding, TcpBinding and wsHttpBinding.
I can add a reference with metadata at the following location
net.tcp://localhost:8100/WCFService/tcpmex
net.pipe://localhost/WCFService/namedpipemex
I have disabled the httpGet for the service in behavior.
The service reference is added but with the following configuration at client:
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSHttpBinding_IServiceClass" />
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8101/WCFService" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IServiceClass" contract="TCP.IServiceClass"
name="WSHttpBinding_IServiceClass">
</endpoint>
</client>
</system.serviceModel>
But since I added a reference using TCP Binding endpoint,
I expected :
address=net.tcp://localhost:8100/WCFService
and binding="mexTcpBinding"
The Service is working but I would like to know, What's going on here.
What is the reason for this. Is it due to the baseAddress or some preference is given to wsHttpBinding?
Thoughts are appreciated.
Thanks.
The mex binding (short for Metadata EXchange) is not an endpoint which can be used to consume your service. Instead, it's used only used to expose information (or meta information) about all the "real" endpoints of your service - notice that your service class doesn't implement the IMetadataExchange contract which you defined in your TCP/Pipe endpoints.
In your case, your service has only one "real" endpoint - the one using wsHttpBinding, which implements the WCFService.IServiceClass interface. That's why there's only one endpoint in your client configuration.
Now, if you had another endpoint using a non-metadata binding (and not the IMetadataExchange contract), they would show up in the client config as well:
<system.serviceModel>
<services>
<service name="WCFService.ServiceClass" behaviorConfiguration="metaDataSupport">
<host>
<baseAddresses>
<add baseAddress="net.pipe://localhost/WCFService"/>
<add baseAddress="net.tcp://localhost:8100/WCFService"/>
<add baseAddress="http://localhost:8101/WCFService"/>
</baseAddresses>
</host>
<endpoint address="tcpmex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<endpoint address="namedpipemex"
binding="mexNamedPipeBinding"
contract="IMetadataExchange" />
<endpoint address=""
binding="netNamedPipeBinding"
contract="WCFService.IServiceClass" />
<endpoint address=""
binding="netTcpBinding"
contract="WCFService.IServiceClass" />
<endpoint address=""
binding="wsHttpBinding"
contract="WCFService.IServiceClass" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metaDataSupport">
<serviceMetadata httpGetEnabled="false" httpGetUrl="" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Related
I follow this blog CONFIGURING WCF SERVICE WITH NETTCPBINDING step by step, when I add service reference from VS 2013, I got below error.
The URI prefix is not recognized.
Metadata contains a reference that cannot be resolved: 'net.tcp://localhost/WCFNetTcp/WCFNetTcpService.svc/mex'.
You have tried to create a channel to a service that does not support .Net Framing. It is possible that you are encountering an HTTP endpoint.
Expected record type 'PreambleAck', found '72'.
My Service configure file is below:
<system.serviceModel>
<services>
<service behaviorConfiguration="netTcpb" name="WCFNetTcp.WCFNetTcpService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="portSharingBinding" contract="WCFNetTcp.IWCFNetTcpService" />
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" contract="IMetadataExchange" />
<!--<endpoint address="mexHttp" binding="mexHttpBinding" contract="IMetadataExchange" />-->
<host>
<baseAddresses>
<!--<add baseAddress="net.tcp://localhost:6666/WCFNetTcpService/"/>-->
<add baseAddress="net.tcp://localhost:808/WCFNetTcp/WCFNetTcpService.svc" />
<!--<add baseAddress="http://local/WCFNetTcp"/>-->
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="netTcpb">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="portSharingBinding" portSharingEnabled="true"/>
</netTcpBinding>
</bindings>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true">
<baseAddressPrefixFilters>
<add prefix="net.tcp://localhost:808"/>
</baseAddressPrefixFilters>
</serviceHostingEnvironment>
</system.serviceModel>
I tried any net.tcp URL what I could think out, but all of them do not work. It seems that basic address did not work when the service is hosted in IIS, it depends on the url in IIS. If I create a service which is hosted in console application with below configuration file, it works.
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WCFNETTCP.Service1">
<endpoint address="" binding="netTcpBinding" contract="WCFNETTCP.IService1">
</endpoint>
<!--comment out after you add service reference-->
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://xxx:6666/WCFNETTCP/" />
<add baseAddress="http://xxx:6667/WCFNETTCIP"/>
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
It would be appreciated if you could share us how to make it work under IIS.
It seems there is something wrong in my IIS. I resolved this issue by below steps.
reinstall IIS
reinstall WCF Non-HTTP Activation in Windows features
reregister asp.net in iis by this command
C:\Windows\Microsoft.NET\Framework64\v4.0.30319>dism /online /enable-feature /featurename:IIS-ASPNET45
Check the settings in IIS which there is no change at my side.
Rebuild my WCF Service, and add service reference successfully.
Hope it will be work for you.
i am new in wcf.i have simple wcf service for like calculator for add,substract,muliply,division etc. i have two endpoint in my service config file. one is basicHttpBinding and another one is netTcpBinding. when i am hitting f5 then wcf test client appear and showing the error wcf failed to add a service. service metadata may not be accessible but if i off the netTcpBinding and mex for netTcpBinding and hit f5 then wcf test client can invoke the service. here is my config entry. so please have a look and tell me why i am getting error for netTcpBinding and how to fix it.
<?xml version="1.0"?>
<!--Copyright (c) Microsoft Corporation. All Rights Reserved.-->
<configuration>
<system.serviceModel>
<services>
<service name="MyTcpActivation.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="PortSharingBinding"
contract="MyTcpActivation.ICalculator"/>
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<endpoint address="" binding="basicHttpBinding" contract="MyTcpActivation.ICalculator" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<!--For debugging purposes set the includeExceptionDetailInFaults attribute to true-->
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<system.web>
<compilation debug="true"/></system.web></configuration>
please guide me where to fix in config file as a result there should no issue whatever binding i use. thanks
I think ... if you have two "IMetadataExchange" endpoints, then you need to provide different addresses. For example:
<service name="MyTcpActivation.CalculatorService" behaviorConfiguration="CalculatorServiceBehavior">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="PortSharingBinding" contract="MyTcpActivation.ICalculator"/>
<endpoint address="mex1" binding="mexTcpBinding" contract="IMetadataExchange"/>
<endpoint address="" binding="basicHttpBinding" contract="MyTcpActivation.ICalculator" />
<endpoint address="mex2" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
I have created a service host with following configuration.
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="MathServiceLib.MathService" behaviorConfiguration="myMathServiceBehave">
<host>
<baseAddresses>
<add baseAddress="http://localhost:9001/MathService"/>
<add baseAddress="net.tcp://localhost:9002/MathService"/>
</baseAddresses>
</host>
<endpoint address="http://localhost:9001/MathService" binding="basicHttpBinding" contract="MathServiceLib.IMathService"/>
<endpoint address ="net.tcp://localhost:9002/MathService" binding ="netTcpBinding" contract="MathServiceLib.IMathService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<!--<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>-->
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="myMathServiceBehave">
<!--<serviceMetadata httpGetEnabled="true"/>-->
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
I don't want to use serviceMetadata httpGetEnabled="true" property instead I want to use MEX binding for proxy creation.
Now when I start my service using
svcHost = new ServiceHost(typeof(MathServiceLib.MathService));
svcHost.Open();
I get following error, please help.
The contract name 'IMetadataExchange' could not be found in the list of contracts implemented by the service MathService. Add a ServiceMetadataBehavior to the configuration file or to the ServiceHost directly to enable support for this contract.
Based on my experience, you need to specify
<serviceMetadata httpGetEnabled="true"/>
if you want to use
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
The following articles provide comprehensive information and examples:
http://msdn.microsoft.com/en-us/library/ms734765(v=vs.110).aspx
http://www.c-sharpcorner.com/UploadFile/81a718/wcf-service-faqs-part-2/
I have a standalone WCF service running on a server behind a firewall. It currently uses wsDualHttpBinding as the service utilizes callbacks. The client works fine in a LAN environment. We have opened the firewall to allow traffic on a custom port and so the discovery of the service now works from outside LAN.
Due to the nature of wsDualHttpBinding this obviously cannot work if the client is behind a firewall of its own. So naturally, netTcpBinding comes to mind which should solve the bidirectional problem. But the strange thing is that when service configuration XML is updated to include netTcpBinding on the same port (and/or exclude wsDualHttpBinding), then even the service discovery no longer works.
I am wondering if there is anything else that I am missing. I have followed the exact advice for configuration from How to: Use netTcpBinding with Windows Authentication and Message Security in WCF Calling from Windows Forms and from Windows Communication Foundation QuickStart - Multiple Binding VS2010.
The configuration:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingEndpointConfig">
<security mode="Message" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Service1.Service1.Service">
<endpoint address="Service1" binding="wsDualHttpBinding" contract="Service1.IService1">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="NetTcpBindingEndpointConfig"
name="NetTcpBindingEndpoint" contract="Service1.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:9999/Service1.Service1/"/>
<add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
If you can use only single port and you must use netTcpBinding try to configure your service this way:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBindingEndpointConfig">
<security mode="Message" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Service1.Service1.Service">
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>
<endpoint address="" binding="netTcpBinding"
bindingConfiguration="NetTcpBindingEndpointConfig"
name="NetTcpBindingEndpoint" contract="Service1.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:9999/Service1.Service1/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="True"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
When adding service reference try to use this address:
net.tcp://localhost:9999/Service1.Service1/mex
Below is my WCF service configuration. I use 2 ServiceHost to host 2 service types. They use the same base address, but they use different relative addresses for their endpoints.
But I got this error, why?
Service cannot be started. System.InvalidOperationException: The ChannelDispatcher at 'http://earth:1111/' with contract(s) '"IHttpGetHelpPageAndMetadataContract"' is unable to open its IChannelListener. ---> System.InvalidOperationException: A registration already exists for URI 'http://earth:1111/'.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.IIS.IISServiceType">
<endpoint address="iis" binding="basicHttpBinding" name="iis"
contract="Distributed.Troubleshooting.System.IIS.IISServiceContract" />
<endpoint address="iismex" binding="mexHttpBinding" bindingConfiguration=""
name="iismex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.SQL.SQLServiceType">
<endpoint address="sql" binding="basicHttpBinding" name="sql"
contract="Distributed.Troubleshooting.System.SQL.SQLServiceContract" />
<endpoint address="sqlmex" binding="mexHttpBinding" bindingConfiguration=""
name="sqlmex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Some even more ridiculous findings:
I changed my configuration to this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.IIS.IISServiceType">
<endpoint address="http://Earth:1111/iis" binding="basicHttpBinding" name="iis"
contract="Distributed.Troubleshooting.System.IIS.IISServiceContract" />
<endpoint address="http://Earth:1111/iismex" binding="mexHttpBinding" bindingConfiguration=""
name="iismex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/iis" />
</baseAddresses>
</host>
</service>
<service behaviorConfiguration="serviceBehavior" name="Distributed.Troubleshooting.System.SQL.SQLServiceType">
<endpoint address="http://Earth:1111/sql" binding="basicHttpBinding" name="sql"
contract="Distributed.Troubleshooting.System.SQL.SQLServiceContract" />
<endpoint address="http://Earth:1111/sqlmex" binding="mexHttpBinding" bindingConfiguration=""
name="sqlmex" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://Earth:1111/sql" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
Then I found I can use "Add Service Reference" in Visual Studio with the following addresses:
http://Earth:1111/iis
http://Earth:1111/iismex
http://Earth:1111/sql
http://Earth:1111/sqlmex
It is possible to host more than one Service with the same base address. Set the HttpHelpPageEnabled and the HttpsHelpPageEnabled properties of all ServiceDebugBehaviors to false, then it should work.
Atention: By default, there's always a ServiceDebugBehavior registered in the behavior's description collection of a host even if it is not specified explicitely (I tried it only with programatic configration and the ServiceHost class, not via XML config). So, you should add an explicit ServiceDebugBehavior and set the mentioned properties. The IncludeExceptionDetailInFaults property can be true.
Have you tried removing one of the Service blocks and combining the endpoints into one?
I cant see any reason why you have them seperated.
Make sure the baseaddress + endpoint address are unique.
You can't host two services with the same base address.
You need to host the other one on a different port or address.
Something like
http://Earth:1111/Service1
and
http://Earth:1111/Service2
I don't really know why this is the case but one solution is to leave the service with no base address and to specify the full address for the endpoints. This doesn't change the address of the different endpoints, nor the addresses unicity. I could not find any relevant reference for this on MSDN.
From my own experience, the problem appears with http and not with net.tcp. I am not using service metadata. I thought the "IHttpGetHelpPageAndMetadataContract" has to do with metadata but found no way to disable it.
You'll also get this error if you accidentally start the same service twice rather than start the two different services.