WCF开发之邦定(Binding)
这部分的前期理论知识比较多,所以我们先从Demo入手,然后再来看理论东西。我们这部分只关注WCF关于邦定的技术,对于其他涉及到的技术不做探讨,由于Binding这部分东西要和其他很多相关技术共同使用,而且涉及到很多WCF中的高级操作,在其他的文章中会逐步提到,这里我们只关心邦定就可以了。
Demo1:二进制邦定通过http
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary2
{
[ServiceContract(Namespace="http://cnblogs.com/charlesliu")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo(string inputString);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary2
{
public class HelloIndigoService : IHelloIndigoService
{
public string HelloIndigo(string inputString)
{
return inputString;
}
}
}
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<client />
<services>
<service behaviorConfiguration="WcfServiceLibrary2.Service1Behavior"
name="WcfServiceLibrary2.HelloIndigoService">
<endpoint address="" binding="customBinding" contract="WcfServiceLibrary2.IHelloIndigoService" bindingConfiguration="binaryOverHttp">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary2/Service1/" />
</baseAddresses>
</host>
</service>
</services>
<bindings>
<customBinding>
<binding name="binaryOverHttp">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004"/>
<reliableSession ordered="true"/>
<binaryMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary2.Service1Behavior">
<!-- 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="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
上面这个Demo和以前的Demo的代码没有什么区别,唯一的不同是在config文件里,加亮的位置体现出了自定义邦定的方法。
Demo2:(Stream流的binding)
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary3
{
[ServiceContract]
public interface IMediaManagerService
{
[OperationContract]
string[] GetMediaList();
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
namespace WcfServiceLibrary3
{
[ServiceContract]
public interface IMediaStreaming
{
[OperationContract]
Stream GetMediaStream(string media);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
namespace WcfServiceLibrary3
{
public class MediaMangerService : IMediaStreaming, IMediaManagerService
{
public string[] GetMediaList()
{
string[] mediaList = new string[1];
mediaList[0] = "WebCast20071101_Video.wmv";
return mediaList;
}
public Stream GetMediaStream(string media)
{
string mediaFile = String.Format("{0}\\{1}", System.Configuration.ConfigurationSettings.AppSettings["mediaPath"], media);
FileInfo fi = new FileInfo(mediaFile);
if (!fi.Exists)
throw new FileNotFoundException("File does not exist: {0}. Check host configuration for 'mediaPath' setting.", media);
TraceStream traceStream = null;
FileStream fs = null;
try
{
fs = new FileStream(mediaFile, FileMode.Open, FileAccess.Read, FileShare.Read);
traceStream = new TraceStream(fs);
}
catch
{
if (fs != null)
fs.Close();
}
return traceStream;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace WcfServiceLibrary3
{
public class TraceStream : Stream
{
System.IO.Stream m_in = null;
System.IO.Stream m_out = null;
public override bool CanRead
{
get
{
Trace.WriteLine("TraceStream", String.Format("get_CanRead: {0}", m_in.CanRead));
return m_in.CanRead;
}
}
public override bool CanSeek
{
get
{
Trace.WriteLine("TraceStream", String.Format("get_CanSeek: {0}", m_in.CanSeek));
return m_in.CanSeek;
}
}
public override bool CanWrite
{
get
{
Trace.WriteLine("TraceStream", String.Format("get_CanWrite: {0}", m_in.CanWrite));
return m_in.CanWrite;
}
}
public override long Length
{
get
{
Trace.WriteLine("TraceStream", String.Format("get_Length: {0}", m_in.Length));
return m_in.Length;
}
}
public override void SetLength(
long val
)
{
Trace.WriteLine("TraceStream", String.Format("SetLength({0})", val));
m_in.SetLength(val);
}
public override long Position
{
get
{
Trace.WriteLine("TraceStream", String.Format("get_Position: {0}", m_in.Position));
return m_in.Position;
}
set
{
Trace.WriteLine("TraceStream", String.Format("set_Position: {0}", m_in.Position));
m_in.Position = value;
}
}
public TraceStream(System.IO.Stream stream)
{
Trace.WriteLine("TraceStream", String.Format("TraceStream created."));
m_in = stream;
}
public override IAsyncResult BeginRead(
byte[] buffer,
int offset,
int count,
AsyncCallback callback,
object state
)
{
Trace.WriteLine("TraceStream", String.Format("BeginRead(): offset({0}), count({1})", offset, count));
return m_in.BeginRead(buffer, offset, count, callback, state);
}
public override IAsyncResult BeginWrite(
byte[] buffer,
int offset,
int count,
AsyncCallback callback,
object state
)
{
Trace.WriteLine("TraceStream", String.Format("BeginWrite(): offset({0}), count({1})", offset, count));
return m_in.BeginWrite(buffer, offset, count, callback, state);
}
public override void Close()
{
Trace.WriteLine("TraceStream", String.Format("Close()"));
m_in.Close();
}
public override int EndRead(
IAsyncResult asyncResult
)
{
Trace.WriteLine("TraceStream", "EndRead()");
return m_in.EndRead(asyncResult);
}
public override void EndWrite(
IAsyncResult asyncResult
)
{
Trace.WriteLine("TraceStream", "EndWrite()");
m_in.EndWrite(asyncResult);
}
public override void Flush()
{
Trace.WriteLine("TraceStream", "Flush()");
m_in.Flush();
}
public override long Seek(
long offset,
SeekOrigin origin
)
{
Trace.WriteLine("TraceStream", String.Format("Seek(): offset({0}), origin({1})", offset, origin));
return m_in.Seek(offset, origin);
}
public override int Read(byte[] buffer,
int offset, int count)
{
Trace.WriteLine("TraceStream", String.Format("Read(): offset({0}), count({1})", offset, count));
return m_in.Read(buffer, offset, count);
}
public override void Write(
byte[] buffer,
int offset,
int count
)
{
Trace.WriteLine("TraceStream", String.Format("Write(): offset({0}), count({1})", offset, count));
m_in.Write(buffer, offset, count);
}
}
}
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<appSettings>
<add key="mediaPath" value="D:\omps-liucha-01.Bak\WCF\5\WebCast20071101_Demo\Streaming_WithTrace" />
</appSettings>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service behaviorConfiguration="WcfServiceLibrary3.Service1Behavior"
name="WcfServiceLibrary3.MediaMangerService">
<endpoint address="MediaManager" binding="basicHttpBinding" contract="WcfServiceLibrary3.IMediaManagerService" />
<!--<endpoint address="MediaStream" contract="WcfServiceLibrary3.IMediaStreaming" binding="basicHttpBinding" bindingConfiguration="basicHttpStreaming"/>-->
<endpoint address="MediaStream" contract="WcfServiceLibrary3.IMediaStreaming" binding="netTcpBinding" bindingConfiguration="netTcpStreaming"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary3/Service1/" />
<add baseAddress="net.tcp://localhost:9000"/>
</baseAddresses>
</host>
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcpStreaming" transferMode="StreamedRequest" maxReceivedMessageSize="40000000" maxBufferSize="4096" sendTimeout="00:00:15" >
</binding>
</netTcpBinding>
<basicHttpBinding>
<binding name="basicHttpStreaming" messageEncoding="Mtom" maxReceivedMessageSize="40000000" transferMode="Streamed">
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary3.Service1Behavior">
<!-- 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="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
上面这个Demo主要演示了流的邦定,大家可以重点关注一下Config文件里的highlight内容。
Demo3:WSDual 用于回调callback
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace WcfServiceLibrary4
{
[ServiceContract(Namespace = "http://cnblogs.cn/charlesliu", CallbackContract = typeof(IHelloIndidoServiceCallback))]
public interface IMyService
{
[OperationContract(IsOneWay = true)]
void HelloIndigo(string message);
[OperationContract]
void HelloIndigo2(string message);
}
public interface IHelloIndidoServiceCallback
{
[OperationContract(IsOneWay = true)]
void HelloIndigoCallback(string message);
[OperationContract]
void HelloIndigoCallback2(string message);
}
[ServiceBehavior(ConcurrencyMode=ConcurrencyMode.Reentrant)]
public class MyService : IMyService
{
public void HelloIndigo(string message)
{
IHelloIndidoServiceCallback callback = OperationContext.Current.GetCallbackChannel<IHelloIndidoServiceCallback>();
callback.HelloIndigoCallback(message);
}
public void HelloIndigo2(string message)
{
IHelloIndidoServiceCallback callback = OperationContext.Current.GetCallbackChannel<IHelloIndidoServiceCallback>();
callback.HelloIndigoCallback2(message);
}
}
}
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="WcfServiceLibrary4.MyService" behaviorConfiguration="WcfServiceLibrary4.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/Design_Time_Addresses/WcfServiceLibrary4/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="wsDualHttpBinding" contract="WcfServiceLibrary4.IMyService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<wsDualHttpBinding>
<binding name="wsDualUsername" maxReceivedMessageSize="100000" transactionFlow="true">
<readerQuotas maxArrayLength="100000" maxStringContentLength="100000"/>
<security>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary4.Service1Behavior">
<!-- 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="False" />
<serviceCredentials>
<serviceCertificate findValue="RPKey" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.ServiceModel;
using ConsoleApplication1.MyServiceReference;
namespace ConsoleApplication1
{
class Program : IMyServiceCallback
{
static void Main(string[] args)
{
Console.WriteLine("Client running on thread {0}", Thread.CurrentThread.GetHashCode());
Console.WriteLine();
Program p = new Program();
InstanceContext context = new InstanceContext(p);
using (MyServiceReference.MyServiceClient proxy = new ConsoleApplication1.MyServiceReference.MyServiceClient(context))
{
WSDualHttpBinding b = proxy.Endpoint.Binding as WSDualHttpBinding;
b.ClientBaseAddress = new Uri("http://localhost:8100");
//Enter valid windows credentials here
Console.WriteLine();
Console.Write("Enter username:");
string username = Console.ReadLine();
Console.Write("Enter password:");
Console.ForegroundColor = ConsoleColor.Black;
string password = Console.ReadLine();
Console.ForegroundColor = ConsoleColor.White;
proxy.ClientCredentials.UserName.UserName = username;
proxy.ClientCredentials.UserName.Password = password;
Console.WriteLine();
Console.WriteLine("Calling HelloIndigo() - one-way");
proxy.HelloIndigo("Hello from client.");
Console.WriteLine("Returned from HelloIndigo()");
Console.WriteLine("Calling HelloIndigo2() - not one-way");
proxy.HelloIndigo2("Hello from client.");
Console.WriteLine("Returned from HelloIndigo2()");
Console.ReadLine();
}
}
public void HelloIndigoCallback(string message)
{
Console.WriteLine("HelloIndigoCallback on thread {0} - one-way", Thread.CurrentThread.GetHashCode());
}
public void HelloIndigoCallback2(string message)
{
Console.WriteLine("HelloIndigoCallback2 on thread {0} - not one-way", Thread.CurrentThread.GetHashCode());
}
}
}
对于WSDual邦定,有几点值得注意。CallbackContract的类名称在客户端会变,比如本例中的IHelloIndidoServiceCallback就变成了IMyServiceCallback。要想成功运行本例还要添加X509的证书,可以从http://www.dasblonde.net/downloads/code/CertificatesSetup.zip下载。WSDual的作用就是实现回调,客户端发送一个调用服务的方法的请求,服务器通过回调客户的方法,实际上也就是服务端调用了客户端的方法。同时这个Demo也展示了如何配置证书认证的配置方法。
Demo4:自定义邦定custombinding有配置文件实现
其实Demo1就是用自定义邦定来实现的,对一邦定使用时非常灵活,所以主要是掌握它的方法。
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfServiceLibrary5
{
[ServiceContract]
public interface IMyService
{
[OperationContract]
string Hello(string message);
}
public class MyService : IMyService
{
public string Hello(string message)
{
return message + " Charles";
}
}
}
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="WcfServiceLibrary5.MyService" behaviorConfiguration="WcfServiceLibrary5.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8001" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint address ="" binding="customBinding" contract="WcfServiceLibrary5.IMyService" bindingConfiguration="customHttp">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<customBinding>
<binding name="customHttp">
<transactionFlow transactionProtocol="WSAtomicTransactionOctober2004"/>
<reliableSession ordered="true"/>
<textMessageEncoding messageVersion="Soap12WSAddressing10" writeEncoding="utf-8"/>
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="WcfServiceLibrary5.Service1Behavior">
<!-- 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="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
注意:<httpTransport />不是<httpsTransport />,搞了半天终于发现是这个问题。
Demo5:代码方式实现的邦定
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
namespace Helloindigo
{
[ServiceContract(Namespace="http://cnbolgs.com/charles")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo(string messsage);
}
public class HelloIndigoService : IHelloIndigoService
{
public string HelloIndigo(string messsage)
{
return messsage + " Charles";
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Helloindigo;
namespace Host
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(HelloIndigoService), new Uri("http://localhost:8000")))
{
BindingElementCollection elements = new BindingElementCollection();
elements.Add(new TransactionFlowBindingElement(TransactionProtocol.WSAtomicTransactionOctober2004));
elements.Add(new ReliableSessionBindingElement(true));
elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8));
elements.Add(new HttpTransportBindingElement());
CustomBinding binding = new CustomBinding(elements);
host.AddServiceEndpoint(typeof(IHelloIndigoService), binding, "HelloIndigoService");
host.Open();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate the host application");
Console.Read();
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
namespace Client
{
class Program
{
static void Main(string[] args)
{
BindingElementCollection elements = new BindingElementCollection();
elements.Add(new TransactionFlowBindingElement(TransactionProtocol.WSAtomicTransactionOctober2004));
elements.Add(new ReliableSessionBindingElement(true));
elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8));
elements.Add(new HttpTransportBindingElement());
CustomBinding binding = new CustomBinding(elements);
ChannelFactory<IHelloIndigoService> factory = new ChannelFactory<IHelloIndigoService>(binding, "http://localhost:8000/HelloIndigoService");
IHelloIndigoService proxy = null;
try
{
proxy = factory.CreateChannel();
string s = proxy.HelloIndigo("Hello");
Console.WriteLine(s);
Console.Read();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
finally
{
ICommunicationObject obj = proxy as ICommunicationObject;
if (obj != null)
{
obj.Close();
}
}
}
}
[ServiceContract(Namespace = "http://cnbolgs.com/charles")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo(string messsage);
}
}
这个Demo使用纯代码的方式实现邦定,但是相比之下用config的方式更简单更高效。
好,看了这么多的Demo大家对Binding应该有所了解了,下面把WCF Binding这部分总结讲解一下:
什么是绑定(Binding)?
• 绑定表示通讯信道(communication channel)的配置
• 绑定定义了客户端与服务端之间通讯的协议
– 传输协议
– 消息编码
– 安全性,可靠性消息与事务
1 Message Transmission Optimization Mechanism (MTOM)
2 Transmission Control Protocol (TCP)
3 Microsoft Message Queuing (MSMQ)
传输协议
• HTTP
• TCP
• 命名管道(Named Pipes)
• MSMQ
• 提供自定义协议的支持:UDP 或者 SMTP, 等等
消息编码
• Text
• MTOM
• Binary
• 能够提供自定义消息编码格式
其它的绑定协议
• 安全
–相互认证证书 (用于不同公司之间或是不同部门之间,提供一种相互的认证手段)
• X.509
–消息保护
• 可靠的消息
• 事务支持
• 能够使用自定义绑定协议进行扩展
信道(Channels)
• 信道栈在通讯的每个端点之间发送或者接收消息
– 客户端代理是从客户端绑定配置构建出来的信道
– ServiceHost根据服务绑定的配置,为每个端点暴露出信道的监听器
• 信道栈由绑定的元素组成
绑定元素
• 绑定(Binding)由绑定元素组成
• 每个绑定元素对于信道(channel)栈的某些部分进行配置
• 与端点(endpoint)相关
• 能够通过声明或在代码中对每个端点进行配置
选择绑定
• 标准绑定:
–预定义的绑定元素
– 为在HTTP, TCP, 命名管道或者MSMQ通讯上提供缺省设置
– 能够修改配置
• 自定义绑定:
– 完全自定义的绑定元素的集合
– 当标准绑定无法满足需求时使用
标准绑定
• BasicHttpBinding
• WSHttpBinding
• WSDualHttpBinding
• WSFederationHttpBinding
• NetNamedPipeBinding
• NetTcpBinding
• NetPeerTcpBinding
• NetMsmqBinding
• MsmqIntegrationBinding
Web Service绑定
• BasicHttpBinding与SOAP 1.1兼容
• WSHttpBinding与带有WS*的SOAP 1.2兼容
• WSDualHttpBinding适用于在支持WS*的HTTP协议上的回调(无法进行互操作)
• WSFederationHttpBinding适用于联合安全与单点登陆(SSO)的场景
跨进程/主机绑定
• NetNamedPipeBinding用于进程内或者同主机的调用
• NetTcpBinding用于同主机或者跨主机的调用
• NetPeerTcpBinding用于同主机或者跨主机点对点消息
消息绑定
• NetMsmqBinding用于在MSMQ上可靠的,事务的并且持久的消息
• MsmqIntegrationBinding用于早期技术的MSMQ互操作
自定义标准绑定
<services>
<service name="HelloIndigo.HelloIndigoService" >
<endpoint binding="netTcpBinding" bindingConfiguration="netTcp" contract="HelloIndigo.IHelloIndigoService" />
</service>
</services>
<bindings>
<netTcpBinding>
<binding name="netTcp" maxReceivedMessageSize="5000000">
<security mode="Message">
<message clientCredentialType="Windows"/>
</security>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
创建自定义绑定
<services>
<service name="HelloIndigo.HelloIndigoService" >
<endpoint binding="customBinding"
bindingConfiguration="custom"
contract="HelloIndigo.IHelloIndigoService" />
</service>
</services>
<bindings>
<customBinding>
<binding name="custom">
<security authenticationMode="SspiNegotiated">
<localServiceSettings detectReplays="true" />
</security>
<textMessageEncoding />
<httpTransport maxReceivedMessageSize="5000000" />
</binding>
</customBinding>
</bindings>
</system.serviceModel>
(完)