1
votes

I'm struggling to get a basic WCF service working over net.tcp protocol. I've created a new WCF project with VS2017 and have not changed the template code at all. Having set the bindings in the web.config to use netTcpBinding and mexTcpBinding respectively, I'm getting the following error:

Error: Cannot obtain Metadata from net.tcp://localhost/WcfSecurityTest/Service1.svc If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address. For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error URI: net.tcp://localhost/WcfSecurityTest/Service1.svc Metadata contains a reference that cannot be resolved: 'net.tcp://localhost/WcfSecurityTest/Service1.svc'. The message could not be dispatched because the service at the endpoint address 'net.tcp://localhost/WcfSecurityTest/Service1.svc' is unavailable for the protocol of the address.

Boilerplate service code:

namespace WcfSecurityTest.Service
{
    [ServiceContract]
    public interface IService1
    {
        [OperationContract]
        string GetData(int value);
        [OperationContract]
        CompositeType GetDataUsingDataContract(CompositeType composite);
    }

    public class Service1 : IService1
    {
        public string GetData(int value) {...}
        public CompositeType GetDataUsingDataContract(CompositeType composite) {...}
    }
}

Service1.svc:

<%@ ServiceHost Language="C#"
    Debug="true"
    Service="WcfSecurityTest.Service.Service1"
    CodeBehind="Service1.svc.cs" %>

web.config:

<system.serviceModel>

  <behaviors>
    <serviceBehaviors>
      <behavior name="behaviourConfig">
        <serviceMetadata />
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <bindings>
    <netTcpBinding>
      <binding name="netTcpBindingConfig">
        <security mode="None" />
      </binding>
    </netTcpBinding>
  </bindings>

  <services>
    <service name="WcfSecurityTest.Service.Service1"
             behaviorConfiguration="behaviourConfig">
      <endpoint address=""
                contract="WcfSecurityTest.Service.IService1"
                binding="netTcpBinding"
                bindingConfiguration="netTcpBindingConfig" />
      <endpoint address="mex"
                contract="IMetadataExchange"
                binding="mexTcpBinding" />
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:808/WcfSecurityTest/Service1.svc" />
        </baseAddresses>
      </host>
    </service>
  </services>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
                             multipleSiteBindingsEnabled="true" />
</system.serviceModel>

I'm testing using WCF Test Client, which gives the error when I try to add the endpoint: net.tcp://localhost:808/WcfSecurityTest/Service1.svc.

net.tcp is enabled within IIS on port 808 and non-HTTP activation is installed.

enter image description here

Obviously I'm doing something wrong here, but every related question on SO and web article I can find suggests this should work.

3
Your binding says "net.tcp://localhost:808/WcfSecurityTest/Service1.svc" but the error says "net.tcp://localhost/WcfSecurityTest/Service1.sv" note the missing port - are you sure you specified the port? is it listening (netstat should answer that)BugFinder
@BugFinder - TCP 0.0.0.0:808 0.0.0.0:0 LISTENING - definitely listening on port 808Chris Pickford

3 Answers

1
votes

I also had problems with mexTcpBinding. I got it working by just using a netTcpBinding.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <protocolMapping>
      <clear/>
    </protocolMapping>
    <bindings>
      <netTcpBinding>
        <binding name="MyNetTcpBinding"
                 receiveTimeout="00:15:00" sendTimeout="00:15:00" closeTimeout="00:15:00" openTimeout="00:01:00"
                 maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"
                 listenBacklog="10">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MyDefaultServiceBehaviour">
          <serviceDebug includeExceptionDetailInFaults="true" />
          <serviceMetadata/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="MyDefaultServiceBehaviour" name="MyWcfService.Contract.MyWcfServiceExternal">
        <clear />
        <!-- SOAP Endpoints-->
        <endpoint address="net.tcp://host/{path}/"
          binding="netTcpBinding" bindingConfiguration="MyNetTcpBinding"
          name="MyNetTcp" contract="MyWcfService.Contract.IMyWcfServiceSoap"
          listenUriMode="Explicit">
        </endpoint>
        <endpoint address="net.tcp://host/{path}/mex"
          binding="netTcpBinding" bindingConfiguration="MyNetTcpBinding"
          name="MyMexNetTcp" contract="IMetadataExchange" />
        <host>
          <timeouts closeTimeout="23:59:59" />
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>

I didn't use baseAddress as I needed to expose multiple endpoints with finer control, hence the {path} placeholder. This whould work with baseAdress as well.

1
votes

You are not implementing the Metadata endpoint.

<behaviors>
    <serviceBehaviors>
      <behavior name="behaviourConfig">
        <serviceMetadata />
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

It should be

<behaviors>
    <serviceBehaviors>
      <behavior name="behaviourConfig">
        <serviceMetadata httpGetEnabled="false" >
        <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

If you want to check whether the tcp metadata is exposed,launch wcftestclient.exe from Visual studio command prompt and add the proxy,you should be good to go with the above changes.

1
votes

Turns out this was an IIS configurational problem.

I hadn't enabled net.tcp at the IIS application level only at the site level.

enter image description here

Setting Advanced Settings > Behaviour > Enabled Protocols to http,net.tcp at the application level resolved the issue.

enter image description here