向WCF发送XML字符串时出现“读取XML数据时超出最大字符串内容长度配额(8192)"错误 [英] “The maximum string content length quota (8192) has been exceeded while reading XML data” error while sending XML string to WCF

查看:107
本文介绍了向WCF发送XML字符串时出现“读取XML数据时超出最大字符串内容长度配额(8192)"错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了三天的时间来修复客户端和服务器配置中应用程序中的此错误,但是没有帮助,这是我的配置:

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:

客户:

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

服务:

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

推荐答案

我发现了问题! :D

I found the problem! :D

问题出在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;
}

现在我正在这样做:

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

它就像一种魅力!

我无法解释为什么我需要打基础.如果有人可以在评论中解释,那就太好了!

I can't explain why I need to call base. If someone could explain in the comments, that would be great!

这篇关于向WCF发送XML字符串时出现“读取XML数据时超出最大字符串内容长度配额(8192)"错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆