簡體   English   中英

通過反射WSHttpBinding在WCF中設置ReaderQuotas.MaxStringContentLength

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

當我不知道綁定類型時,我需要使用WCF,它可能是BasicHttpBinding或WSHttpBinding。 我創建了一個簡單的解決方案來進行無反射測試,並且可以正常工作。 但是,當我嘗試通過反射在另一個項目中使用它時,當我使用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)}

在BasicHttpBinding中可以正常工作(當我使用此綁定配置WCF時)

我將這段代碼放在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>

這工作無需反思,為了測試此服務器,我在app.config客戶端中放置了以下簡單代碼:

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

但是我不能將其放在其他項目中,因為WCF可能會更改。 我在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;
            } 

我不知道在此項目的app.config中的C#中配置什么代碼,它為空。

我只需要在創建對象實例之前放入此代碼。 上面的代碼(在我的問題中)可以。 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