C# 以编程方式修改端点 ReaderQuotas

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/969479/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:30:39  来源:igfitidea点击:

Modify endpoint ReaderQuotas programmatically

c#wcfreaderquotas

提问by Adrya

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 的数据。

采纳答案by Onots

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

希望这对你有所帮助。

回答by No hay Problema

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

为什么要以如此复杂的方式解决这个问题,只需直接更改 ReaderQuotas:

ie:

IE:

WSHttpBinding WebBinding = new WSHttpBinding();

WSHttpBinding WebBinding = new WSHttpBinding();

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

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

This will work without that weird reflection sample.

这将在没有那个奇怪的反射样本的情况下工作。

Cheers

干杯

回答by whywhywhy

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