简体   繁体   English

“在读取XML数据时已超出最大字符串内容长度配额(8192)”将XML字符串发送到WCF时出错

[英]“The maximum string content length quota (8192) has been exceeded while reading XML data” error while sending XML string to WCF

I have trying everything in three days to fix this error in my application in client and server config, but nothing helps, this is my configs: 我在三天内尝试了所有内容来修复我在客户端和服务器配置中的应用程序中的错误,但没有任何帮助,这是我的配置:

Client: 客户:

public class IdBookIssuerIssuedTokenBinding : WS2007HttpBinding
{
    private readonly HttpTransportBindingElement transport;
    private readonly SecurityBindingElement security;

    public IdBookIssuerIssuedTokenBinding(EndpointAddress bindingAddress)
    {
        WS2007HttpBinding ws2007HttpBinding = new WS2007HttpBinding(SecurityMode.TransportWithMessageCredential);
        ws2007HttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
        ws2007HttpBinding.Security.Message.EstablishSecurityContext = false;

        //TODO: expose somewhere to configure this timeouts
        ws2007HttpBinding.SendTimeout = TimeSpan.FromMinutes(5);
        ws2007HttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(5);

        ws2007HttpBinding.MaxReceivedMessageSize = int.MaxValue;
        ws2007HttpBinding.MaxBufferPoolSize = int.MaxValue;
        ws2007HttpBinding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
        ws2007HttpBinding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
        ws2007HttpBinding.ReaderQuotas.MaxDepth = int.MaxValue;
        ws2007HttpBinding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
        ws2007HttpBinding.ReaderQuotas.MaxArrayLength = int.MaxValue;

        this.ReaderQuotas.MaxStringContentLength = int.MaxValue;
        this.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
        this.ReaderQuotas.MaxDepth = int.MaxValue;
        this.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
        this.ReaderQuotas.MaxArrayLength = int.MaxValue;

        IssuedSecurityTokenParameters securityTokenParameters = new System.ServiceModel.Security.Tokens.IssuedSecurityTokenParameters(
            "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1",
                bindingAddress,
                ws2007HttpBinding);

        security = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(securityTokenParameters);
        security.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;

        transport = new HttpsTransportBindingElement();
        transport.MaxReceivedMessageSize = int.MaxValue;
        transport.MaxBufferSize = int.MaxValue;
        transport.MaxBufferPoolSize = int.MaxValue;

        this.MessageEncoding = WSMessageEncoding.Text;
        this.MaxBufferPoolSize = int.MaxValue;
        this.MaxReceivedMessageSize = int.MaxValue;
    }

    public override BindingElementCollection CreateBindingElements()
    {
        BindingElementCollection elements = new BindingElementCollection();

        elements.Add(this.security);
        elements.Add(this.transport);

        return elements;
    }
}

public class ClientFactory
{
    #region static

    private readonly static ClientFactory _current;

    static ClientFactory()
    {
        _current = new ClientFactory();
    }

    public static ClientFactory Current { get { return _current; } }

    #endregion

    private ClientFactory()
    { }

    public TClient Create<TClient, TServiceInterface>(string businessEntityContainerName, string userName, string password) 
            where TClient : ClientBase<TServiceInterface>, new()
            where TServiceInterface : class
    {
        var client = new TClient();
        return this.Create<TClient, TServiceInterface>(client, businessEntityContainerName, userName, password);
    }

    public TClient Create<TClient, TServiceInterface>(string businessEntityContainerName, string userName, string password, Binding stsBinding, EndpointAddress remoteServiceAddress)
            where TClient : ClientBase<TServiceInterface>, new()
            where TServiceInterface : class
    {
        var client = (TClient)Activator.CreateInstance(typeof(TClient), stsBinding, remoteServiceAddress);
        return this.Create<TClient, TServiceInterface>(client, businessEntityContainerName, userName, password);
    }

    public TClient Create<TClient, TServiceInterface>(string businessEntityContainerName, string userName, string password, EndpointAddress stsAddress, EndpointAddress remoteServiceAddress)
            where TClient : ClientBase<TServiceInterface>, new()
            where TServiceInterface : class
    {
        IdBookIssuerIssuedTokenBinding binding = new IdBookIssuerIssuedTokenBinding(stsAddress);

        var client = (TClient)Activator.CreateInstance(typeof(TClient), binding, remoteServiceAddress);
        return this.Create<TClient, TServiceInterface>(client, businessEntityContainerName, userName, password);
    }

    private TClient Create<TClient, TServiceInterface>(TClient client, string businessEntityContainerName, string userName, string password)
            where TClient : ClientBase<TServiceInterface>, new()
            where TServiceInterface : class
    {
        client.ClientCredentials.UserName.UserName = userName;
        client.ClientCredentials.UserName.Password = password;

        //TODO: expose somewhere to configure this timeouts
        var binding = (IdBookIssuerIssuedTokenBinding)client.Endpoint.Binding;
        binding.SendTimeout = TimeSpan.FromMinutes(2);
        binding.ReceiveTimeout = TimeSpan.FromMinutes(5);

        binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
        binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
        binding.ReaderQuotas.MaxDepth = int.MaxValue;
        binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
        binding.ReaderQuotas.MaxArrayLength = int.MaxValue;

        client.Endpoint.Behaviors.Add(new HeaderInfoBehavior(businessEntityContainerName));

        foreach (var operation in client.ChannelFactory.Endpoint.Contract.Operations)
        {
            var dtSerializerOp = operation.Behaviors.Find<DataContractSerializerOperationBehavior>();

            dtSerializerOp.DataContractResolver =
                    new DynamicTypeResolver(typeof(TClient).Assembly, typeof(TClient).Namespace);

            dtSerializerOp.MaxItemsInObjectGraph = int.MaxValue;
        }

        return client;
    }
}

Service: 服务:

<?xml version="1.0"?>
<configuration>
  <location path="Services">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
      <httpRuntime executionTimeout="4800" maxRequestLength="2097150"/>
    </system.web>
  </location>
  <system.serviceModel>
    <extensions>
      <behaviorExtensions>
        <add name="errorHandler" type="GILabs.MetaFx.Application.Service.Commom.ErrorHandlerBehavior, GILabs.MetaFx.Application.Service.Commom" />
        <add name="federatedServiceHostConfiguration" type="Microsoft.IdentityModel.Configuration.ConfigureServiceHostBehaviorExtensionElement, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
      </behaviorExtensions>
    </extensions>
    <behaviors>
      <serviceBehaviors>
        <behavior name="WsServiceBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="false" />
          <errorHandler />
          <federatedServiceHostConfiguration />
        </behavior>
      </serviceBehaviors>

      <endpointBehaviors>
        <behavior name="WsServiceBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <wsHttpBinding>
        <binding name="WsHttpEndpointBinding">
        </binding>
      </wsHttpBinding>
      <ws2007FederationHttpBinding>
        <binding name="IDBookIssuerIssuedTokenFederation" closeTimeout="00:10:00" openTimeout="00:10:00"
          receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false"
          transactionFlow="false" hostNameComparisonMode="StrongWildcard"
          maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text"
          textEncoding="utf-8" useDefaultWebProxy="true">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
            maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />

          <security mode="TransportWithMessageCredential">
            <message establishSecurityContext="false">
              <issuer address="https://localhost/idbook/Services/SecurityToken.svc" binding="customBinding" bindingConfiguration="IDBookIssuerIssuedToken" />
            </message>
          </security>
        </binding>
      </ws2007FederationHttpBinding>
      <ws2007HttpBinding>
        <binding name="IDBookIssuerUsernameMixed">
          <security mode="TransportWithMessageCredential">
            <message clientCredentialType="UserName" establishSecurityContext="false" />
          </security>
        </binding>
      </ws2007HttpBinding>
      <customBinding>
        <binding name="IDBookIssuerIssuedToken">
          <security authenticationMode="IssuedTokenOverTransport"
                    messageSecurityVersion="WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10">
            <issuedTokenParameters>
              <issuer address="https://localhost/idbook/Services/SecurityToken.svc"
                      binding="ws2007HttpBinding" bindingConfiguration="IDBookIssuerUsernameMixed">
              </issuer>
            </issuedTokenParameters>
          </security>
          <textMessageEncoding maxReadPoolSize="2147483647" maxWritePoolSize="2147483647">
            <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
              maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
          </textMessageEncoding>
          <httpTransport maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
            maxBufferSize="2147483647" />
        </binding>
      </customBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="WsServiceBehavior" name="GILabs.MetaFx.Application.MetadataService.MetaService">
        <endpoint address="" binding="ws2007FederationHttpBinding"
          bindingConfiguration="IDBookIssuerIssuedTokenFederation"
          name="MetadataWsHttpEndpoint" contract="GILabs.MetaFx.Application.MetadataService.IMetadataService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
      <service behaviorConfiguration="WsServiceBehavior" name="GILabs.MetaFx.Application.Service.AppService">
        <endpoint address="" binding="ws2007FederationHttpBinding"
          bindingConfiguration="IDBookIssuerIssuedTokenFederation"
          name="ApplicationWsHttpEndpoint" contract="GILabs.MetaFx.Application.Service.IAppService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
      <service behaviorConfiguration="WsServiceBehavior" name="GILabs.MetaFx.Application.Service.SyncChangeService">
        <endpoint address="" binding="ws2007FederationHttpBinding"
          bindingConfiguration="IDBookIssuerIssuedTokenFederation"
          name="ApplicationWsHttpEndpoint" contract="GILabs.MetaFx.Application.Service.ISyncChangeService">
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>

    <diagnostics>
      <messageLogging logEntireMessage="true"
                      logMessagesAtServiceLevel="true"
                      logMessagesAtTransportLevel="true"
                      logMalformedMessages="true"
                      maxMessagesToLog="5000"
                      maxSizeOfMessageToLog="2000">
      </messageLogging>
    </diagnostics>
  </system.serviceModel>

  <system.webServer>

    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="500000000"></requestLimits>
      </requestFiltering>
    </security>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

  <system.diagnostics>
    <sources>
      <source name="System.ServiceModel" switchValue="All" propagateActivity="true">
        <listeners>
          <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\temp\Traces.svclog"/>
        </listeners>
      </source>
    </sources>
    <trace autoflush ="true" />
  </system.diagnostics>
</configuration>

Creating my service in Client: 在客户端创建我的服务:

_syncChangeService = ClientFactory.Current.Create<SyncChangeServiceClient, ISyncChangeService>(
                         ConfigurationManager.Instance.OrganizationName,
                         ConfigurationManager.Instance.ServiceManagerUserName,
                         ConfigurationManager.Instance.ServiceManagerUserPassword,
                         new EndpointAddress(ConfigurationManager.Instance.IdBookWSUrl),
                         new EndpointAddress(string.Format("{0}/Services/SyncChange.svc", ConfigurationManager.Instance.ServiceManagerUrl))
                     );

I found the problem! 我发现了问题! :D :d

The problem is in IdBookIssuerIssuedTokenBinding.CreateBindingElements() . 问题出在IdBookIssuerIssuedTokenBinding.CreateBindingElements()

I had overridden and not called the base: 我已经被覆盖而没有被称为基地:

public override BindingElementCollection CreateBindingElements()
{
    BindingElementCollection elements = new BindingElementCollection();

    elements.Add(this.security);
    elements.Add(this.transport);

    return elements;
}

Now I am doing this: 现在我这样做:

public override BindingElementCollection CreateBindingElements()
{
    BindingElementCollection elements = base.CreateBindingElements();

    var securityBindingElement = elements.Find<SecurityBindingElement>();
    elements.Remove(securityBindingElement);
    elements.Add(this.security);

    var transportBindingElement = elements.Find<HttpTransportBindingElement>();
    elements.Remove(transportBindingElement);
    elements.Add(this.transport);

    return elements;
}

And it works like a charm! 它就像一个魅力!

I can't explain why I need to call base. 我无法解释为什么我需要打电话给基地。 If someone could explain in the comments, that would be great! 如果有人可以在评论中解释,那就太好了!

I've run into problems similar to this before. 我之前遇到过类似的问题。 In your config file, try increasing the size for all instances of your following line (there were at least two): 在配置文件中,尝试增加以下行的所有实例的大小(至少有两个):

ws2007HttpBinding.MaxBufferPoolSize = int.MaxValue;

Also, in your service, do the same here: 另外,在您的服务中,请执行以下操作:

<ws2007FederationHttpBinding>
    <binding name="IDBookIssuerIssuedTokenFederation" closeTimeout="00:10:00" openTimeout="00:10:00" 
... **maxBufferPoolSize="2147483647"**

It's a wee bit counter-intuitive, but the service will barf if it receives a response that is larger than it is configured to accept. 这有点违反直觉,但如果收到的响应大于配置为接受的响应,则该服务将进行barf。

Hope that helps! 希望有所帮助!

暂无
暂无

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

相关问题 将 XML 字符串发送到 WCF 时出现“读取 XML 数据时已超出最大字符串内容长度配额 (8192)”错误 - "The maximum string content length quota (8192) has been exceeded while reading XML data" error while sending XML string to WCF WCF-读取XML数据时超出了最大字符串内容长度配额(8192) - WCF - The maximum string content length quota (8192) has been exceeded while reading XML data 反序列化类型的对象时发生错误...读取XML数据时超出了最大字符串内容长度配额(8192) - There was an error deserializing the object of type … The maximum string content length quota (8192) has been exceeded while reading XML data WCF:读取XML数据时已超出最大数组长度配额(16384) - WCF: The maximum array length quota (16384) has been exceeded while reading XML data WCF Config修复最大字符串内容长度配额(8192) - WCF Config to fix The maximum string content length quota (8192) has been exceeded WCF - 读取XML数据时已超出最大名称表字符计数配额(16384) - WCF - The maximum nametable character count quota (16384) has been exceeded while reading XML data 读取XML数据时超出了最大字符串内容长度 - The maximum string content length exceeded while reading XML data ServiceStack:读取XML数据时已超出最大数组长度配额(16384) - ServiceStack: The maximum array length quota (16384) has been exceeded while reading XML data 已超过最大字符串内容长度配额(8192)。增加XmlDictionaryReaderQuotas的MaxStringContentLength属性 - The maximum string content length quota (8192) has been exceeded.Increase the MaxStringContentLength property on the XmlDictionaryReaderQuotas 使用Delphi使用WCF - 最大字符串内容长度配额(8192)错误 - Consuming WCF with Delphi - Maximum string content length quota (8192) error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM