WCF use netTcpBinding in IIS - wcf

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.

Related

Service Reference Error - netTcpBinding

I was working on WCF service with an endpoint binding of netTcpBinding, hosted in a console application.
These are the configuration settings:
<system.serviceModel>
<services>
<service name="FullTimePartTime_EmpWCFServiceAppl.EmployeeService"
behaviorConfiguration="mexBehaviour" >
<endpoint
address="EmployeeService"
binding="netTcpBinding"
contract="FullTimePartTime_EmpWCFServiceAppl.IEmployeeService">
</endpoint>
<endpoint
address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange">
</endpoint>
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:7090/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="mexBehaviour">
<serviceMetadata httpGetEnabled="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
The console application executes fine. WPF is client app which should consume the WCF service, but when I tried to add a service reference, this error occurred:
Service Reference Error
Can anyone help me to fix this issue & let me know the mistake I made?
Thanks in advance.
Always the metadata discovery is through http.So you need to have one more base address for the http which publishes the metdata via http.
<host>
<baseAddresses>
<add baseAddress="http://localhost:7091/"/>
<add baseAddress="net.tcp://localhost:7090/"/>
</baseAddresses>
</host>
First try to browse the metadata through http://localhost:7091/?wsdl. Now try to generate proxy class using the service reference address http://localhost:7091/.

How is the Binding done when specifying multiple Base Address

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>

Can't host tcp based wcf service on IIS, Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService error pops up

I have a simple test purpose WCF service. I'm trying to host it under IIS 7.5 ( Windows 7 ) but no luck so far. I'm getting error
Cannot obtain Metadata from net.tcp://localhost/TestApp2/MyService
I have a web site TestApp2 under Default Web Site, I enabled tcp on Default Web Site and TestApp2. Here is my web.config file, while I realize that this error simply states that I didn't have endpoint for metadata exchange, I can't see what's the problem because I included endpoint for metadata exchange.
<system.serviceModel>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyService">
<endpoint address="net.tcp://localhost/TestApp2/MyService"
binding="netTcpBinding"
bindingConfiguration="PortSharingBinding"
contract="II7WcfService.IService1" />
<endpoint address="MEX"
binding="mexTcpBinding"
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost/TestApp2/MyService" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="PortSharingBinding" portSharingEnabled="true">
<security mode="None"/>
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="False" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
Thanks.
My guess is your service isn't actually called MyService but rather it is in a namespace. This means your declared endpoints are not getting picked up, and the default ones (which doesn't include IMetadataExchange) are being used instead.
Add the name of your namespace to the attribute in the config and it should work.

WCF cannot configure WSDL publishing

I want to enable WSDL retrieval for a webservice that I created. I can 'call' the webservice through the .svc file that I made:
http://localhost/test.svc
<%# ServiceHost Language="C#" Debug="true" Service="Project.MyService" CodeBehind="MyService.svc.cs" %>
Calling the page gives the standard .NET message saying "Metadata publishing for this service is currently disabled." with instructions to enable publishing.
I followed instructions and added the web.config entries, however calling http://localhost/test.svc?wsdl produces the same result... How can I enable WSDL publishing for my webservice?
web.config entries
<service name="Project.IMyService" behaviorConfiguration="MyServiceTypeBehaviors" >
<endpoint contract="IMetadataExchange" binding="mexHttpBinding"
address="mex"
/>
<host>
<baseAddresses>
<add baseAddress="http://localhost/test.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors">
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Sounds crazy but just remove behaviorConfiguration="MyServiceTypeBehaviors" from the service definition andlet the behavior anonymous (with no name). It will remain
<services>
<service name="WcfServiceLibrary1.IMyService" >
<endpoint contract="IMetadataExchange" binding="mexHttpBinding"
address="mex"
/>
<host>
<baseAddresses>
<add baseAddress="http://localhost/test.svc"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior >
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
The mex endpoint and httpGetEnabled look ok. This link covers the topic in some more detail and may be of use.
http://msdn.microsoft.com/en-us/library/ms788760.aspx

WCF error : A registration already exists for URI

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.