Question

I have a dynamic client to a service. How can i change the ReaderQuotas property of it's endpoint binding?

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.

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.

Was it helpful?

Solution

Setting quotas on a BindingElement after the binding is created has no effect on that binding.

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. 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.

OTHER TIPS

Why are you solving that in a such complex way, just alter the ReaderQuotas directly:

ie:

WSHttpBinding WebBinding = new WSHttpBinding();

WebBinding.ReaderQuotas.MaxArrayLength = int.MaxValue; WebBinding.ReaderQuotas.MaxStringContentLength = 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:

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:

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top