以编程方式修改终结点ReaderQuotas

18

我有一个针对服务的动态客户端。如何更改其端点绑定的ReaderQuotas属性?

我尝试像这样,但它不起作用...

 DynamicProxyFactory factory = new DynamicProxyFactory(m_serviceWsdlUri);

 foreach (ServiceEndpoint endpoint in factory.Endpoints)
 {
     Binding binding =  endpoint.Binding;

     binding.GetProperty<XmlDictionaryReaderQuotas>(new BindingParameterCollection()).MaxArrayLength = 2147483647
     binding.GetProperty<XmlDictionaryReaderQuotas>(new BindingParameterCollection()).MaxBytesPerRead =2147483647;
     binding.GetProperty<XmlDictionaryReaderQuotas>(new BindingParameterCollection()).MaxDepth = 2147483647;
     binding.GetProperty<XmlDictionaryReaderQuotas>(new BindingParameterCollection()).MaxNameTableCharCount = 2147483647;
     binding.GetProperty<XmlDictionaryReaderQuotas>(new BindingParameterCollection()).MaxStringContentLength = 2147483647;
   }

即使这样做,ReaderQuotas 值仍然保持默认值。

我也尝试了像这样的方法,但仍然不起作用:

     DynamicProxyFactory factory = new DynamicProxyFactory(m_serviceWsdlUri);

     foreach (ServiceEndpoint endpoint in factory.Endpoints)
     {
         System.ServiceModel.Channels.BindingElementCollection bec = endpoint.Binding.CreateBindingElements();

         System.ServiceModel.Channels.TransportBindingElement tbe = bec.Find<System.ServiceModel.Channels.TransportBindingElement>();

         tbe.MaxReceivedMessageSize = 2147483647;
         tbe.MaxBufferPoolSize = 2147483647;
         TextMessageEncodingBindingElement textBE = bec.Find<TextMessageEncodingBindingElement>();

         if (textBE != null)
         {

             textBE.ReaderQuotas.MaxStringContentLength = 2147483647;
             textBE.ReaderQuotas.MaxArrayLength = 2147483647;
             textBE.ReaderQuotas.MaxBytesPerRead = 2147483647;
             textBE.ReaderQuotas.MaxDepth = 2147483647;
             textBE.ReaderQuotas.MaxNameTableCharCount = 2147483647;

         }
   }

我需要这个功能以便我可以向服务发送超过8kb的数据。

3个回答

34

在创建Binding后,对BindingElement设置配额不会对该绑定产生影响。

编辑(因为您不知道使用的是哪个绑定):

您可以使用反射来设置属性。请注意,在设置之前,应确保Binding实际上具有该属性。并非所有绑定都具有此属性。如果您尝试在不支持该属性的绑定上设置它,则示例将引发异常。

Binding binding = endpoint.Binding;

XmlDictionaryReaderQuotas myReaderQuotas = new XmlDictionaryReaderQuotas();
myReaderQuotas.MaxStringContentLength = _sanebutusablelimit_;
myReaderQuotas.MaxArrayLength = _sanebutusablelimit_;
myReaderQuotas.MaxBytesPerRead = _sanebutusablelimit_;
myReaderQuotas.MaxDepth = _sanebutusablelimit_;
myReaderQuotas.MaxNameTableCharCount = _sanebutusablelimit_;

binding.GetType().GetProperty("ReaderQuotas").SetValue(binding, myReaderQuotas, null);

希望这能对你有所帮助。


5
在提到这些东西必须在客户端代理和/或服务主机创建之前设置时,为你点赞。一旦被创建,它们就是不可变的。 - marc_s
嗨,马克, 谢谢回复,但我不知道是什么类型的绑定,这就是为什么我需要在创建绑定之后进行操作的原因。 还有其他建议吗?谢谢,Adrya - Adrya
你是说你不知道它是什么类型的绑定?在ServiceHostFactory中,只需查看绑定并修改配额(quota)即可。如果你的意思是,在使用绑定之后才知道需要修改配额,那么...也许设置一个标志,然后重新启动主机(或客户端代理)。 - Cheeso
我通过使用反射来编辑我的回复以处理未知绑定。 - Onots
我该如何设置MaxReceivedMessageSize? - Sachin Pakale

11

为什么您要用一种如此复杂的方法来解决这个问题,直接修改 ReaderQuotas 即可:

例如:

WSHttpBinding WebBinding = new WSHttpBinding();

WebBinding.ReaderQuotas.MaxArrayLength = int.MaxValue; WebBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue; WebBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;

这样就可以避免使用奇怪的反射样例了。

祝顺利!


2
因为客户端在到达我的手中时是动态创建的,所以绑定和所有内容都已经创建好了,我只想增加该客户端的消息大小。 - Adrya

1
需要注意的是,为了完整的解决方案,绑定的以下属性也需要更新:
binding2.MaxBufferSize = 2147483647;
binding2.MaxReceivedMessageSize = 2147483647;

为了方便其他人,这里提供一个编程示例,可以在客户端和服务器上以编程方式设置ReaderQuotas以及上述的2个属性:
客户端代码:
        WebHttpBinding binding2 = new WebHttpBinding();
        XmlDictionaryReaderQuotas myReaderQuotas = new XmlDictionaryReaderQuotas();
        myReaderQuotas.MaxStringContentLength = 2147483647;
        myReaderQuotas.MaxArrayLength = 2147483647;
        myReaderQuotas.MaxBytesPerRead = 2147483647;
        myReaderQuotas.MaxDepth = 2147483647;
        myReaderQuotas.MaxNameTableCharCount = 2147483647;

        binding2.GetType().GetProperty("ReaderQuotas").SetValue(binding2, myReaderQuotas, null);
        binding2.MaxBufferSize = 2147483647;
        binding2.MaxReceivedMessageSize = 2147483647;
        ServiceEndpoint ep = new ServiceEndpoint(ContractDescription.GetContract(typeof(IMyService)),
            binding2, new EndpointAddress("http://localhost:9000/MyService"));

        WebChannelFactory<IMyService> cf2 = new WebChannelFactory<IMyService>(ep);

        IMyService serv = cf2.CreateChannel();
        serv.PrintNameDesc("Ram", new string('a', 100*1024*1024));

服务器代码:

        WebHttpBinding binding2 = new WebHttpBinding();
        XmlDictionaryReaderQuotas myReaderQuotas = new XmlDictionaryReaderQuotas();
        myReaderQuotas.MaxStringContentLength = 2147483647;
        myReaderQuotas.MaxArrayLength = 2147483647;
        myReaderQuotas.MaxBytesPerRead = 2147483647;
        myReaderQuotas.MaxDepth = 2147483647;
        myReaderQuotas.MaxNameTableCharCount = 2147483647;

        binding2.GetType().GetProperty("ReaderQuotas").SetValue(binding2, myReaderQuotas, null);
        binding2.MaxBufferSize = 2147483647;
        binding2.MaxReceivedMessageSize = 2147483647;

        WebServiceHost host2 = new WebServiceHost(typeof(MyService));
        host2.AddServiceEndpoint(typeof(IMyService), binding2, new Uri("http://localhost:9000/MyService"));

        host2.Open();

合同在哪里:

[ServiceContract]
public interface IMyService
{
    [WebInvoke(Method = "PUT", 
        UriTemplate = "My/{name}/", 
        BodyStyle = WebMessageBodyStyle.Bare, 
        ResponseFormat = WebMessageFormat.Xml, 
        RequestFormat = WebMessageFormat.Xml)]
    [OperationContract]
    void PrintNameDesc(string name, string desc);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接