WCF - Come aumentare la quota delle dimensioni dei messaggi


454

Ho un servizio WCF che restituisce 1000 record dal database al client. Ho un client ASP.NET WCF (ho aggiunto il riferimento al servizio nel progetto di applicazione Web asp.net per utilizzare WCF).

Ricevo il seguente messaggio quando eseguo l'applicazione client:

La quota massima delle dimensioni dei messaggi in arrivo (65536) è stata superata. Per aumentare la quota, utilizzare la proprietà MaxReceivedMessageSize sull'elemento di associazione appropriato.

Qualsiasi aiuto? Come aumentare la quota delle dimensioni del messaggio?


Ho avuto lo stesso problema, ma ho appena ricevuto un errore di rete 400 ostile, ma la soluzione è stata la cosa della dimensione del messaggio ..
Mr W

2
Ho risolto il problema usando i passaggi menzionati in [il link] [1] [1]: stackoverflow.com/questions/7476853/…
Ram,

Perché è impostato così in basso per impostazione predefinita? Sicurezza?
Coop il

@Coops per sicurezza davvero. Impostando una quota sui messaggi, ad esempio, gli attacchi DDOS sono (almeno un po ') più difficili da eseguire.
Peter van Kekem,

Risposte:


608

Ti consigliamo qualcosa del genere per aumentare le quote delle dimensioni del messaggio, nel file App.config o Web.config :

<bindings>
    <basicHttpBinding>
        <binding name="basicHttp" allowCookies="true"
                 maxReceivedMessageSize="20000000" 
                 maxBufferSize="20000000"
                 maxBufferPoolSize="20000000">
            <readerQuotas maxDepth="32" 
                 maxArrayLength="200000000"
                 maxStringContentLength="200000000"/>
        </binding>
    </basicHttpBinding>
</bindings>

E utilizzare il nome dell'associazione nella configurazione dell'endpoint, ad es

...
bindingConfiguration="basicHttp"
...

La giustificazione per i valori è semplice, sono sufficientemente grandi da contenere la maggior parte dei messaggi. Puoi sintonizzare quel numero in base alle tue esigenze. Il valore predefinito basso è praticamente lì per prevenire attacchi di tipo DOS. Rendendolo 20000000 consentirebbe un attacco DOS distribuito per essere efficace, la dimensione predefinita di 64k richiederebbe un numero molto elevato di client per sovraccaricare la maggior parte dei server in questi giorni.


20
Grazie ... Questa modifica deve essere effettuata nel file web.config dell'applicazione client.
bugBurger

8
Potrebbe anche essere necessario modificarlo sul server, nel caso in cui sia necessario inviare un set di dati di grandi dimensioni come parametro a un metodo WCF.
Nate,

9
È sufficientemente grande per accogliere la maggior parte dei messaggi. Puoi sintonizzare quel numero in base alle tue esigenze. È praticamente lì per prevenire attacchi di tipo DOS. Rendendolo 20000000 consentirebbe un attacco DOS distribuito per essere efficace, la dimensione predefinita di 64k richiederebbe un numero molto elevato di client per sopraffare la maggior parte dei server al giorno d'oggi.
Nate

18
Per gli altri interessati, ho letto su un altro blog che la dimensione massima è 2147483647. 20000000 è un po 'più piccola di questo numero, quindi ha senso usare il numero più piccolo con cui puoi cavartela senza interrompere il servizio.
proudgeekdad,

5
@Slauma Dovrebbe essere modificato sul server se quel parametro in entrata fosse troppo grande; altrimenti (e più probabilmente) la modifica deve essere effettuata nel file di configurazione del client, poiché è la risposta del servizio (non il suo parametro) che è troppo grande.
Nate

155

Se ricevi ancora questo messaggio di errore mentre usi WCF Test Client, è perché il client ha un'impostazione MaxBufferSize separata .

Per correggere il problema:

  1. Fare clic con il tasto destro del mouse sul nodo File di configurazione nella parte inferiore della struttura
  2. Seleziona Modifica con SvcConfigEditor

Apparirà un elenco di impostazioni modificabili, incluso MaxBufferSize.

Nota: i client proxy generati automaticamente impostano anche MaxBufferSize su 65536 per impostazione predefinita.


8
Perché oh perché me ne dimentico sempre? +1
James Skemp

9
Su vs2013 SvcConfigEditor viene sostituito con Modifica configurazione WCF se le persone lo stanno cercando.
ZoomVirus

Non riesci a trovare SVCconfigEditor?
Arul Sidthan,

Lo troverai nella cartella Bindings, fai clic sull'associazione per il servizio ed è lì.
Sameer Alibhai,

Se il tuo file di configurazione viene generato automaticamente, dovresti assolutamente farlo in questo modo. Ogni volta che aggiorni il tuo riferimento, rigenererà app.config e dovrai cambiarlo di nuovo manualmente. Se lo cambi VS, tuttavia, le nuove modifiche si adegueranno alle impostazioni che hai scelto.
kingfrito_5005,

104

Se stai creando i collegamenti WCF in modo dinamico, ecco il codice da utilizzare:

BasicHttpBinding httpBinding = new BasicHttpBinding();
httpBinding.MaxReceivedMessageSize = Int32.MaxValue;
httpBinding.MaxBufferSize = Int32.MaxValue;
// Commented next statement since it is not required
// httpBinding.MaxBufferPoolSize = Int32.MaxValue;

Puoi usarlo inizializzare. Chiaramente puoi usarlo come metodo di costruzione.
aemre

45

Il client di test WCF ha la propria configurazione client.

Esegui il client di prova e scorri verso il basso. Se si fa doppio clic sul nodo File di configurazione, verrà visualizzata la rappresentazione XML. Come puoi vedere maxReceivedMessageSizeè 65536.

Per modificarlo, fare clic con il pulsante destro del mouse sul nodo dell'albero File di configurazione e selezionare Modifica con SvcConfigEditor. Quando l'editor si apre, espandi Associazioni e fai doppio clic sull'associazione che è stata generata automaticamente.

Puoi modificare tutte le proprietà qui, incluso maxReceivedMessageSize. Al termine, fare clic su File - Salva .

Infine, quando torni alla finestra WCF Test Client, fai clic su Strumenti - Opzioni .

NOTA : deselezionare la configurazione di rigenerazione sempre all'avvio dei servizi .


2
Probabilmente la migliore risposta qui!
Haris,

3
voto a causa della nota per deselezionare l' Always regenerate configopzione.
furioso il

La soluzione più semplice secondo me. Mi ha salvato un po 'di mal di testa.
Jared Beach,

Su vs2013 SvcConfigEditor viene sostituito con Modifica configurazione WCF se le persone lo stanno cercando.
ZoomVirus

Grazie. Mi sono rotto la testa per un po ', cambiando la configurazione del server ancora e ancora, quando il problema era con la configurazione del Test Client!
Fahad,

24

Ho trovato il modo semplice

--- fai clic con il pulsante destro del mouse sul file webconfig o config app e fai clic su MODIFICA CONFIGURAZIONE WCF e arriva a bingdigs e seleziona il servizio in corso e mostra a destra maxReciveMessageSize dare un numero elevato ---


2
È stata un'ottima risposta, non sapevo di poterlo modificare da qui, grazie
albert sh

8

Risolvo il problema ... come segue

    <bindings>
  <netTcpBinding>
    <binding name="ECMSBindingConfig" closeTimeout="00:10:00" openTimeout="00:10:00"
      sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
      maxReceivedMessageSize="2147483647" portSharingEnabled="true">
      <readerQuotas maxArrayLength="2147483647" maxNameTableCharCount="2147483647"
          maxStringContentLength="2147483647" maxDepth="2147483647"
          maxBytesPerRead="2147483647" />
      <security mode="None" />
    </binding>
  </netTcpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ECMSServiceBehavior">
      <dataContractSerializer ignoreExtensionDataObject="true" maxItemsInObjectGraph="2147483647" />
      <serviceDebug includeExceptionDetailInFaults="true" />
      <serviceTimeouts transactionTimeout="00:10:00" />
      <serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="100"
        maxConcurrentInstances="100" />
    </behavior>
  </serviceBehaviors>
</behaviors>

20
In cosa differisce dalla mia soluzione? A parte te, hai incluso tutte le parti irrilevanti della tua configurazione, nonché le parti pertinenti e hai scelto il valore massimo possibile invece dei 200m che ho scelto?
Nate,

3
Anche il contesto è buono ... forse queste due risposte potrebbero essere unite?
Jeff,

1
tale impostazione deve essere configurata nel server o nel client?
John Kenedy,

8

Ho risolto il mio problema su Bing Maps WPF sul mio progetto utilizzando CalculateRoute (). Nel mio caso la soluzione era impostare maxReceivedMessageSize e maxReceivedMessageSize sull'attributo "httpTransport" per la sezione "customBinding".

Ho impostato nel file application.config (es. MyApp.config) questa configurazione:

<system.serviceModel>
    <bindings>
        <basicHttpBinding>
            <binding name="BasicHttpBinding_IGeocodeService" />
            <binding name="BasicHttpBinding_IRouteService" />
        </basicHttpBinding>
        <customBinding>
            <binding name="CustomBinding_IGeocodeService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
            <binding name="CustomBinding_IRouteService">
                <binaryMessageEncoding />
              <httpTransport manualAddressing="false" maxBufferPoolSize="524288"
                                maxReceivedMessageSize="2147483647" allowCookies="false" authenticationScheme="Anonymous"
                                bypassProxyOnLocal="false" decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
                                keepAliveEnabled="true" maxBufferSize="2147483647" proxyAuthenticationScheme="Anonymous"
                                realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
                                useDefaultWebProxy="true" />
            </binding>
        </customBinding>
    </bindings>
    <client>
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="BasicHttpBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/geocodeservice/GeocodeService.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IGeocodeService"
            contract="BingServices.IGeocodeService" name="CustomBinding_IGeocodeService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc"
            binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IRouteService"
            contract="BingServices.IRouteService" name="BasicHttpBinding_IRouteService" />
        <endpoint address="http://dev.virtualearth.net/webservices/v1/routeservice/routeservice.svc/binaryHttp"
            binding="customBinding" bindingConfiguration="CustomBinding_IRouteService"
            contract="BingServices.IRouteService" name="CustomBinding_IRouteService" />
    </client>
</system.serviceModel>

6

<bindings>
  <wsHttpBinding>
    <binding name="wsHttpBinding_Username" maxReceivedMessageSize="20000000"          maxBufferPoolSize="20000000">
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="UserName" establishSecurityContext="false"/>
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<client>
  <endpoint
            binding="wsHttpBinding"
            bindingConfiguration="wsHttpBinding_Username"
            contract="Exchange.Exweb.ExchangeServices.ExchangeServicesGenericProxy.ExchangeServicesType"
            name="ServicesFacadeEndpoint" />
</client>


Ottimo per pubblicare la tua risposta. È importante che il valore "bindingConfiguration" corrisponda al nome dell'associazione. Nel tuo esempio "wsHttpBinding_Username".
Bruno Bieri,

6

Per HTTP:

<bindings>
  <basicHttpBinding>
    <binding name="basicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000" 
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="200" 
             maxArrayLength="200000000"
             maxBytesPerRead="4096"
             maxStringContentLength="200000000"
             maxNameTableCharCount="16384"/>
    </binding>
  </basicHttpBinding>
</bindings>

Per TCP:

<bindings>
  <netTcpBinding>
    <binding name="tcpBinding"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
      <readerQuotas maxDepth="200"
           maxArrayLength="200000000"
           maxStringContentLength="200000000"
           maxBytesPerRead="4096"
           maxNameTableCharCount="16384"/>
    </binding>
  </netTcpBinding>
</bindings>

IMPORTANTE:

Se si tenta di passare un oggetto complesso che ha molti oggetti connessi (ad esempio: una struttura di dati ad albero, un elenco che ha molti oggetti ...), la comunicazione fallirà indipendentemente da come sono state aumentate le quote. In tali casi, è necessario aumentare il conteggio degli oggetti contenenti:

<behaviors>
  <serviceBehaviors>
    <behavior name="NewBehavior">
      ...
      <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

È maxItemsInObjectGraphstata la (rapida) soluzione per me. Ma quando aumenti questo, dovresti pensare se la soluzione migliore è che la tua applicazione richieda dati in blocchi, al contrario di un enorme grafico a oggetti che può mettere a dura prova le risorse.
Paolo

6

Per me, tutto quello che dovevo fare è aggiungere maxReceivedMessageSize="2147483647"al client app.config. Il server non è stato toccato.


5

Un'altra cosa importante da considerare dalla mia esperienza ..

Consiglio vivamente di NON massimizzare maxBufferPoolSize, poiché i buffer del pool non vengono mai rilasciati fino a quando il dominio dell'app (ovvero il pool di applicazioni) non ricicla.

Un periodo di traffico intenso potrebbe causare l'utilizzo e la liberazione di molta memoria.

Maggiori dettagli qui:


3

Non dimenticare che verrà preso in considerazione l'app.config del punto di entrata dell'esecuzione, non quello del progetto della libreria di classi che gestisce le chiamate del servizio Web se ce n'è uno.

Ad esempio, se viene visualizzato l'errore durante l'esecuzione di unit test, è necessario impostare la configurazione appropriata nel progetto di test.


0

ho riscontrato questo errore durante l'utilizzo di queste impostazioni su web.config

System.ServiceModel.ServiceActivationException

ho impostato le impostazioni in questo modo:

      <service name="idst.Controllers.wcf.Service_Talks">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_TalksAspNetAjaxBehavior"
      binding="webHttpBinding" contract="idst.Controllers.wcf.Service_Talks" />
  </service>
  <service name="idst.Controllers.wcf.Service_Project">
    <endpoint address="" behaviorConfiguration="idst.Controllers.wcf.Service_ProjectAspNetAjaxBehavior"
      binding="basicHttpBinding" bindingConfiguration="" bindingName="largBasicHttp"
      contract="idst.Controllers.wcf.Service_Project" />
  </service>
</services>

<bindings>
<basicHttpBinding>
    <binding name="largBasicHttp" allowCookies="true"
             maxReceivedMessageSize="20000000"
             maxBufferSize="20000000"
             maxBufferPoolSize="20000000">
        <readerQuotas maxDepth="32"
             maxArrayLength="200000000"
             maxStringContentLength="200000000"/>
    </binding>
</basicHttpBinding>


4
Quindi, hai risolto il tuo problema usando la risposta di Nate e poi postandola come tua. Non fico.
Arcain,

La risposta di @arcain Nates è stata molto generica, usando nomi e numeri di titoli che si possono prevedere frequentemente. Questa risposta non è stata rubata, è semplicemente la risposta giusta. Dato che esiste una sola risposta corretta, doveva essere ripetuta.
kingfrito_5005,

@ kingfrito_5005 La risposta "corretta" era già qui quando il risponditore ha pubblicato questo. Sollevò abbastanza chiaramente l' bindingselemento di Nate e lo ripubblicò come parte della sua risposta. Quei 2000000valori sono piuttosto distinti.
Arcain,

@arcain, non sono d'accordo che siano valori molto standard, la mia azienda li usa anche nei nostri elementi vincolanti.
kingfrito_5005,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.