简体   繁体   English

以编程方式修改端点ReaderQuotas

[英]Modify endpoint ReaderQuotas programmatically

I have a dynamic client to a service. 我有一个服务的动态客户端。 How can i change the ReaderQuotas property of it's endpoint binding? 如何更改其端点绑定的ReaderQuotas属性?

I tried like this but it doesn't work ... 我试过这样但它不起作用......

 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;
   }

Even after doing this the ReaderQuotas values remain the default ones. 即使这样做,ReaderQuotas值仍然是默认值。

I also tried like this and still doesn't work: 我也尝试过这样但仍然不起作用:

     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;

         }
   }

I need this so I can send more than 8kb to the service. 我需要这个,所以我可以发送超过8kb的服务。

Setting quotas on a BindingElement after the binding is created has no effect on that binding. 创建绑定后在BindingElement上设置配额对该绑定没有影响。

Edit (since you don't know what binding is used): 编辑(因为您不知道使用了什么绑定):

You can use reflection to set the property. 您可以使用反射来设置属性。 Note you should make sure the Binding actually has the property before setting it. 请注意,在设置之前,应确保Binding实际具有该属性。 Not all bindings have this property. 并非所有绑定都具有此属性。 If you try to set it on a binding that doesn't support it, the example will throw an exception. 如果您尝试在不支持它的绑定上设置它,该示例将引发异常。

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);

Hope this helps you a bit. 希望这对你有所帮助。

Why are you solving that in a such complex way, just alter the ReaderQuotas directly: 为什么要以这种复杂的方式解决这个问题,只需直接改变ReaderQuotas:

ie: 即:

WSHttpBinding WebBinding = new WSHttpBinding(); WSHttpBinding WebBinding = new WSHttpBinding();

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

This will work without that weird reflection sample. 这将在没有奇怪的反射样本的情况下工作。

Cheers 干杯

Also to be noted, is that the following properties of the Binding also need to be updated for the complete solution: 另外需要注意的是,还需要更新Binding的以下属性以获得完整的解决方案:

binding2.MaxBufferSize = 2147483647;
binding2.MaxReceivedMessageSize = 2147483647;

For the benefit of others here is a sample that programmatically sets the ReaderQuotas on both the client and the server along with the 2 properties above: 为了其他人的利益,这里有一个示例,它以编程方式在客户端和服务器上设置ReaderQuotas以及上面的2个属性:

Client code: 客户代码:

        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));

Server code: 服务器代码:

        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();

Where the contract is: 合同是:

[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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM