WCF - MaxStringContentLength & MaxReceivedMessageSize

一个很经典的 "问题" ~~~~ 先看下面的例子。

[ServiceContract]
public interface IService
{
  [OperationContract]
  void Test(string s);
}

public class Service : IService
{
  public void Test(string s)
  {
    Console.WriteLine(s.Length);
  }
}

public class WcfTest
{
  public static void Test()
  {
    AppDomain.CreateDomain("Server").DoCallBack(delegate
    {
      ServiceHost host = new ServiceHost(typeof(Service), new Uri("net.tcp://localhost:8080/service"));
      host.AddServiceEndpoint(typeof(IService), new NetTcpBinding(), "");
      host.Open();
    });

    IService channel = ChannelFactory<IService>.CreateChannel(new NetTcpBinding(),
      new EndpointAddress("net.tcp://localhost:8080/Service"));
      
    using (channel as IDisposable)
    {
      channel.Test(new String('a', 1024 * 10));
    }
  }
}


运行一下,目标出现~~~ [lol]

未处理 System.ServiceModel.FaultException
  Message="The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'Test'. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader."


既然已经有了详细提示,那么我们就按照提示做。

AppDomain.CreateDomain("Server").DoCallBack(delegate
{
  XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
  quotas.MaxStringContentLength = 6553500;

  NetTcpBinding binding = new NetTcpBinding();
  binding.ReaderQuotas = quotas;

  ServiceHost host = new ServiceHost(typeof(Service), new Uri("net.tcp://localhost:8080/service"));
  host.AddServiceEndpoint(typeof(IService), binding, "");
  host.Open();
});

IService channel = ChannelFactory<IService>.CreateChannel(new NetTcpBinding(),
  new EndpointAddress("net.tcp://localhost:8080/Service"));
  
using (channel as IDisposable)
{
  channel.Test(new String('a', 1024 * 10));
}


OK!可以运行了。我们继续加大传递的字符串。 [wink]

IService channel = ChannelFactory<IService>.CreateChannel(new NetTcpBinding(),
  new EndpointAddress("net.tcp://localhost:8080/Service"));
  
using (channel as IDisposable)
{
  channel.Test(new String('a', 1024 * 100));
}


哎~~ 新的异常出现了。 [sweat]

未处理 System.ServiceModel.CommunicationException
 Message="The maximum message size quota for incoming messages has been exceeded for the remote channel. See the server logs for more details."


看异常提示,这回要改的是 channel 的信息。

AppDomain.CreateDomain("Server").DoCallBack(delegate
{
  XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
  quotas.MaxStringContentLength = 6553500;

  NetTcpBinding binding = new NetTcpBinding();
  binding.ReaderQuotas = quotas;
  binding.MaxReceivedMessageSize = 6553500; // <---- Here!--------------

  ServiceHost host = new ServiceHost(typeof(Service), new Uri("net.tcp://localhost:8080/service"));
  host.AddServiceEndpoint(typeof(IService), binding, "");
  host.Open();
});

IService channel = ChannelFactory<IService>.CreateChannel(new NetTcpBinding(),
  new EndpointAddress("net.tcp://localhost:8080/Service"));
  
using (channel as IDisposable)
{
  channel.Test(new String('a', 1024 * 100));
}


好了,世界清静了。 [smile] 当然,我们也可以直接在配置文件中设置。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors />
      <bindings>
        <netTcpBinding>
          <binding name="NewBinding0" maxReceivedMessageSize="6553600">
            <readerQuotas maxStringContentLength="6553600" />
          </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service name="Learn.Library.WCF.Service">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="NewBinding0"
          contract="Learn.Library.WCF.IService" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://localhost:8080/service" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值