Modificar ReaderQuotas endpoint programaticamente
-
13-09-2019 - |
Pergunta
Eu tenho um cliente dinâmico para um serviço. Como posso alterar a propriedade ReaderQuotas dele é obrigatório endpoint?
Eu tentei como este, mas ele não funciona ...
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;
}
Mesmo depois de fazer isso, o ReaderQuotas valores permanecem os default.
Eu também tentei como este e ainda não funciona:
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;
}
}
Eu preciso disso para que eu possa enviar mais de 8 KB para o serviço.
Solução
Definir quotas em um BindingElement após a ligação é criado não tem efeito sobre essa ligação.
Edit (desde que você não sabe o que a ligação é usado):
Você pode usar o reflexo para definir a propriedade. Observe que você deve certificar-se da ligação realmente tem a propriedade antes de defini-lo. Nem todas as ligações têm essa propriedade. Se você tentar defini-lo em uma ligação que não apoiá-lo, o exemplo irá lançar uma exceção.
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);
Espero que isso ajude você um pouco.
Outras dicas
Por que você está resolvendo isso de tal forma complexa, apenas alterar as ReaderQuotas diretamente:
ou seja:
WSHttpBinding WebBinding = new WSHttpBinding ();
WebBinding.ReaderQuotas.MaxArrayLength = int.MaxValue; WebBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue; WebBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
Isto irá funcionar sem que a amostra reflexão estranho.
Felicidades
Também de notar, é que as seguintes propriedades da ligação também precisam ser atualizados para a solução completa:
binding2.MaxBufferSize = 2147483647;
binding2.MaxReceivedMessageSize = 2147483647;
Para o benefício de outros aqui é um exemplo que programaticamente define os ReaderQuotas em ambos o cliente eo servidor, juntamente com as 2 propriedades acima:
O código do cliente:
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));
código do servidor:
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();
Quando o contrato é:
[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);
}