简体   繁体   English

通过反射WSHttpBinding在WCF中设置ReaderQuotas.MaxStringContentLength

[英]Set ReaderQuotas.MaxStringContentLength, in WCF via reflection WSHttpBinding

I need to consume WCF when I don't know the type of binding, it could be BasicHttpBinding or WSHttpBinding. 当我不知道绑定类型时,我需要使用WCF,它可能是BasicHttpBinding或WSHttpBinding。 I created a simple solution to test without reflection and it works. 我创建了一个简单的解决方案来进行无反射测试,并且可以正常工作。 But when I try use it in another project via reflection, when I use WSHttpBinding, I get this exception (Spanish): 但是,当我尝试通过反射在另一个项目中使用它时,当我使用WSHttpBinding时,会收到此异常(西班牙语):

{System.Xml.XmlException: Se superó la cuota de longitud del contenido de cadena (8192) al leer los datos XML. Esta cuota se puede aumentar cambiando la propiedad MaxStringContentLength en el objeto XmlDictionaryReaderQuotas que se usa para crear el lector XML. Línea 1, posición 10572.
   en System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3)
   en System.Xml.XmlDictionaryReader.ReadContentAsString(Int32 maxStringContentLength)
   en System.Xml.XmlBaseReader.ReadContentAsString()
   en System.Xml.XmlBaseReader.ReadElementContentAsString()
   en System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.PartInfo.ReadValue(XmlDictionaryReader reader)
   en System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeParameter(XmlDictionaryReader reader, PartInfo part)
   en System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeResponse(XmlDictionaryReader reader, Object[] parameters)
   en System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeReply(Message message, Object[] parameters)}

in BasicHttpBinding it works ok, (when I configure WCF with this binding) 在BasicHttpBinding中可以正常工作(当我使用此绑定配置WCF时)

I put in the web.config this code in WsHttpBinding server 我将这段代码放在WsHttpBinding服务器中的web.config中

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors >
        <behavior name="ServiceBehaviors"  >
          <!-- To avoid disclosing metadata information, 
          set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
          <serviceCredentials>
            <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName"
                             storeLocation="LocalMachine" storeName="My" />
            <userNameAuthentication userNamePasswordValidationMode="Custom"
             customUserNamePasswordValidatorType="TestService.CustomValidator, TestService" />
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"
          maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
            maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          <security mode="Message">
            <transport clientCredentialType="None" />
            <message clientCredentialType="None" />
          </security>
        </binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="ServiceBehaviors" name="TestService.Service1">
        <endpoint binding="wsHttpBinding" contract="TestService.IService1" />
        <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

This works without reflection, to test this server I put in app.config client this simple code: 这工作无需反思,为了测试此服务器,我在app.config客户端中放置了以下简单代码:

<bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IService1">
                    <readerQuotas maxStringContentLength="2147483647" />
                    <security>
                        <message clientCredentialType="None" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>

but I can't put this in my other project because the WCF could change. 但是我不能将其放在其他项目中,因为WCF可能会更改。 I have this code in C# to configure the dynamic web service, but it doesn't work: 我在C#中具有以下代码来配置动态Web服务,但是它不起作用:

            PropertyInfo channelFactoryProperty = proxyInstance.GetType().GetProperty("ChannelFactory");

            if (channelFactoryProperty == null)
            {
                throw new InvalidOperationException("There is no ''ChannelFactory'' property on the DomainClient.");
            }
            ChannelFactory factory = (ChannelFactory)channelFactoryProperty.GetValue(proxyInstance, null);

            factory.Endpoint.Binding.SendTimeout = new TimeSpan(0, 10, 0);
            factory.Endpoint.Binding.OpenTimeout = new TimeSpan(0, 10, 0);
            factory.Endpoint.Binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            factory.Endpoint.Binding.CloseTimeout = new TimeSpan(0, 10, 0);

            PropertyInfo channelFactoryPropert = proxyInstance.GetType().GetProperty("InnerChannel");
            System.ServiceModel.IClientChannel factor = (System.ServiceModel.IClientChannel)channelFactoryPropert.GetValue(proxyInstance, null);
            factor.OperationTimeout.Add(new TimeSpan(0, 10, 0));
            factor.OperationTimeout = new TimeSpan(0, 10, 0);

            switch ((factory.Endpoint.Binding).GetType().ToString())
            {
                case "System.ServiceModel.BasicHttpBinding":
                    BasicHttpBinding _basicBinding = (BasicHttpBinding)factory.Endpoint.Binding;
                    _basicBinding.MaxBufferPoolSize = 2147483647;
                    _basicBinding.MaxBufferSize = 2147483647;
                    _basicBinding.MaxReceivedMessageSize = 2147483647;
                    _basicBinding.OpenTimeout = new TimeSpan(0, 10, 0);
                    break;

                case "System.ServiceModel.WSHttpBinding":
                    WSHttpBinding _wsBinding = (WSHttpBinding)factory.Endpoint.Binding;                     
                    _wsBinding.MaxBufferPoolSize = 2147483647;
                    _wsBinding.MaxReceivedMessageSize = 2147483647;
                    _wsBinding.OpenTimeout = new TimeSpan(0, 10, 0);
                    _wsBinding.ReaderQuotas.MaxStringContentLength = 2147483647;


                    XmlDictionaryReaderQuotas _wsBindingRQ = (XmlDictionaryReaderQuotas)_wsBinding.ReaderQuotas;
                    _wsBindingRQ.MaxArrayLength = 2147483647;
                    _wsBindingRQ.MaxBytesPerRead = 2147483647;

                    _wsBindingRQ.MaxNameTableCharCount = 2147483647;
                    _wsBindingRQ.MaxStringContentLength = 2147483647;
                    break;
            } 

I don't know what code to configure in C# in the app.config in this project, it is empty. 我不知道在此项目的app.config中的C#中配置什么代码,它为空。

I only needed put this code before create the instance of object. 我只需要在创建对象实例之前放入此代码。 The code above (in my question) it's ok. 上面的代码(在我的问题中)可以。 proxyInstance = compilerResults.CompiledAssembly.CreateInstance(proxyType.Name, false, System.Reflection.BindingFlags.CreateInstance, null, new object[] { serviceEndpoint.Binding, serviceEndpoint.Address }, System.Globalization.CultureInfo.CurrentCulture, null); proxyInstance = editorResults.CompiledAssembly.CreateInstance(proxyType.Name,false,System.Reflection.BindingFlags.CreateInstance,null,新对象[] {serviceEndpoint.Binding,serviceEndpoint.Address},System.Globalization.CultureInfo.CurrentCulture,null);

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

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