HowTo: netTcpBinding on IIS and things to remember

 

Configuring netTcpBinding on IIS requires IIS7. You can refer the article for more information on platform dependencies.

Requirements to get netTcpBinding on IIS7 work.

 

Make sure the following service in the services snap-in are started

image

Here is the configuration on the IIS –> Website –> Site Bindings

We need to add a net.tcp binding for 808:*

image

Here is the settings required on the application under IIS. The name of my sample application is NTLMWCFService. The EnabledProtocols needs to be set to net.tcp.

*****NOTE***** net.tcp must be in lower case as shown here. *****

image

Application pool settings on IIS7.

image

NOTE: If you are using netTcpBinding along with wsHttpBinding on IIS7 with application pool running in Classic Mode, you may notice the “Server Application Unavailable” errors. This happens if the first request to the application pool is served for a request coming over netTcpBinding. However if the first request for the application pool comes for a http resource served by .net framework, you will not notice this issue.

 

Here is system.serviceModel section for the web.config

<system.serviceModel>
  <bindings>
    <netTcpBinding>
      <binding name="NewBinding1" />
    </netTcpBinding>
    <wsHttpBinding>
      <binding name="NTLMWCF_wsHTTPBinding">
        <security mode="Transport">
          <transport clientCredentialType="Windows" />
        </security>
      </binding>
    </wsHttpBinding>
  </bindings>
  <services>
    <service behaviorConfiguration="NTLMWCFBehavior" name="NTLMWCF">
      <endpoint binding="netTcpBinding" bindingConfiguration="NewBinding1"
        contract="INTLMWCF" />
      <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
        contract="IMetadataExchange" />
      <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NTLMWCF_wsHTTPBinding"
        contract="INTLMWCF">
      </endpoint>
    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="NTLMWCFBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>

 

Here is the NTLMWCF.svc file

<%@ ServiceHost Language="VB" Service="NTLMWCF" %>

Imports System.ServiceModel

' NOTE: If you change the class name "INTLMWCF" here, you must also update the reference to "INTLMWCF" in Web.config.
<ServiceContract()> _
Public Interface INTLMWCF

    <OperationContract()> _
    Function DoWork() As String

End Interface

' NOTE: If you change the class name "NTLMWCF" here, you must also update the reference to "NTLMWCF" in Web.config and in the associated .svc file.
Public Class NTLMWCF
    Implements INTLMWCF

    Public Function DoWork() As String Implements INTLMWCF.DoWork
        Return "I am @work"
    End Function

End Class

 

Here is the client file Module1.vb

Imports System.Security.Cryptography.X509Certificates

Module Module1

    Sub Main()

        System.Net.ServicePointManager.ServerCertificateValidationCallback = DirectCast([Delegate].Combine(System.Net.ServicePointManager.ServerCertificateValidationCallback, New System.Net.Security.RemoteCertificateValidationCallback(AddressOf RemoteCertValidate)), System.Net.Security.RemoteCertificateValidationCallback)

‘if you change the application pool to run under classic pipeline mode in IIS7, the following call to the WSHttpBinding will fail.

        callService("NetTcpBinding_INTLMWCF")

        callService("WSHttpBinding_INTLMWCF")

    End Sub

    Function RemoteCertValidate(ByVal sender As Object, ByVal cert As X509Certificate, ByVal chain As X509Chain, ByVal error1 As System.Net.Security.SslPolicyErrors) As Boolean

        Return True

    End Function

    Function callService(ByVal binding As String) As Boolean

        Dim client As New ServiceReference1.NTLMWCFClient(binding)

        Console.WriteLine(client.DoWork())

        client.Close()

        Console.ReadLine()

    End Function

End Module

 

Here is the client’s app.config

<system.serviceModel>

    <bindings>

        <netTcpBinding>

            <binding name="NetTcpBinding_INTLMWCF" closeTimeout="00:01:00"

                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

                transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"

                hostNameComparisonMode="StrongWildcard" listenBacklog="10"

                maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"

                maxReceivedMessageSize="65536">

                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />

                <reliableSession ordered="true" inactivityTimeout="00:10:00"

                    enabled="false" />

                <security mode="Transport">

                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />

                    <message clientCredentialType="Windows" />

                </security>

            </binding>

        </netTcpBinding>

        <wsHttpBinding>

            <binding name="WSHttpBinding_INTLMWCF" closeTimeout="00:01:00"

                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"

                bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"

                maxBufferPoolSize="524288" maxReceivedMessageSize="65536"

                messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"

                allowCookies="false">

                <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"

                    maxBytesPerRead="4096" maxNameTableCharCount="16384" />

                <reliableSession ordered="true" inactivityTimeout="00:10:00"

                    enabled="false" />

                <security mode="Transport">

                    <transport clientCredentialType="Windows" proxyCredentialType="None"

                        realm="" />

                    <message clientCredentialType="Windows" negotiateServiceCredential="true"

                        establishSecurityContext="true" />

                </security>

            </binding>

        </wsHttpBinding>

    </bindings>

    <client>

        <endpoint address="net.tcp://myIISServer.myDomain.com/NTLMWCFService/NTLMWCF.svc"

            binding="netTcpBinding" bindingConfiguration="NetTcpBinding_INTLMWCF"

            contract="ServiceReference1.INTLMWCF" name="NetTcpBinding_INTLMWCF">

            <identity>

                <servicePrincipalName value="host/myIISServer.myDomain.com" />

            </identity>

        </endpoint>

        <endpoint address="https://myIISServer.myDomain.com/NTLMWCFService/NTLMWCF.svc"

            binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_INTLMWCF"

            contract="ServiceReference1.INTLMWCF" name="WSHttpBinding_INTLMWCF">

            <identity>

                <servicePrincipalName value="host/myIISServer.myDomain.com" />

            </identity>

        </endpoint>

    </client>

</system.serviceModel>