如何确保 WCF ChannelFactory 使用 xml 配置中的 Binding 设置(忽略 MaxArrayLength)
嗨,我是 Wcf 新手,正在编写我的第一个 Wcf 服务和客户端。我不喜欢使用工具来生成配置;我宁愿自己编写配置。我要解决的问题是客户端通过 netTcp 与服务通信。该服务可能会返回非常大的有效负载(大于默认的 readerQuotas.maxArrayLength)。我最初开发的组件在字节流有效负载相对较低(即小于它认为的默认值约 16K)时工作正常。我可以通过创建绑定并将 MaxArrayLength 设置为足够大的值以编程方式解决此问题。但是,我需要能够在 xml 配置中执行等效操作。
我的 app.config(客户端)是:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<client>
<endpoint address="net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/"
binding="netTcpBinding" bindingConfiguration="unsecureNetTcpBinding"
contract="WcfDataServiceLib.IRemoteDataRequester"
name="DataRequesterEndpoint" />
</client>
<bindings>
<netTcpBinding>
<binding name="unsecureNetTcpBinding" maxReceivedMessageSize="2147483647">
<readerQuotas maxArrayLength="1000000" />
<security mode="None" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
创建客户端代理的代码如下:
private void Init()
{
var address = new EndpointAddress(@"net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService/");
const string endpointName = "DataRequesterEndpoint";
ChannelFactory<IRemoteDataRequester> factory = new ChannelFactory<IRemoteDataRequester>(
endpointName);
IRemoteDataRequester proxy = factory.CreateChannel(address);
// call business methods on proxy ...
}
请注意,代码通过变量“endpointName”链接到配置。
服务端配置(我认为这无关紧要,但为了完整性而包含在内):
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="WcfDataServiceLib.RemoteDataRequesterService" behaviorConfiguration="WcfDataServiceLib.RemoteDataRequesterServiceBehavior">
<host>
<baseAddresses>
<add baseAddress = "net.tcp://localhost:9000/WcfDataService/RemoteDataRequesterService" />
<add baseAddress="http://localhost:8731/Design_Time_Addresses/WcfDataService/RemoteDataRequesterService/"/>
</baseAddresses>
</host>
<endpoint address ="" binding="netTcpBinding" bindingConfiguration="netTcpBindingConfig" contract="WcfDataServiceLib.IRemoteDataRequester">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="WcfDataServiceLib.RemoteDataRequesterServiceBehavior">
<serviceMetadata httpGetEnabled="False"/>
<serviceDebug includeExceptionDetailInFaults="True" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="netTcpBindingConfig" receiveTimeout="00:00:30">
<readerQuotas maxArrayLength="1000000"/>
</binding>
<binding name="netTcpReliableSession" receiveTimeout="00:00:30" >
<reliableSession enabled="true"/>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
</configuration>
当我在服务返回大字节流的场景中运行客户端时,会抛出异常,异常内部的消息是:
发生通信错误:套接字连接被中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或者是潜在的网络资源问题造成的。本地套接字超时为 '00:00:59.9687494'
(这不是超时,因为错误会立即发生。)
如前所述,我可以通过编程方式解决此问题,如下所示:
var binding = new NetTcpBinding
{
ReaderQuotas = { MaxArrayLength = 10000000 }
};
return new ChannelFactory<IRemoteDataRequester>(binding);
这工作正常,但我需要通过配置来进行测试。
我还尝试了以下方法:
var binding = new NetTcpBinding("unsecureNetTcpBinding");
return new ChannelFactory<IRemoteDataRequester>(binding);
但这没有什么区别。
所以我的问题是,为什么当我从包含 MaxArrayLength 设置为合适值的绑定的端点配置创建通道时,会忽略该值?
许多问候。
好的,我找到了解决方案。配置一直在工作。但是,我提供的配置(“unsecureNetTcpBinding”)是我从说明 http 服务的代码示例中找到的(不是我正在设计的 net tcp 服务)。配置的流氓部分是 'security mode="None"' 当我把它拿出来时,它起作用了。如果我更改 readerQuotas maxArrayLength 这将根据我的需要应用。我的代码工作的原因是因为我没有将安全模式设置为无。感谢您的意见和帮助。