Domanda

Sto scrivendo un servizio WCF per caricare file ma lancia eccezioni quando l'array di byte ha più di 16384 elementi.

Questo è il dettaglio delle eccezioni:

Il formatter ha lanciato un'eccezione durante il tentativo di deserializzare il messaggio: errore nella deseriazione del corpo del messaggio di richiesta per il funzionamento "Createdocument". La quota di lunghezza dell'array massima (16384) è stata superata durante la lettura dei dati XML. Questa quota può essere aumentata modificando la proprietà MaxArrayLength sull'oggetto XMLDictionaryReaderquotas utilizzato durante la creazione del lettore XML. Linea 1, posizione 22862.

La configurazione sia per client che server imposta la quota di lunghezza dell'array massima su 2147483647.

Configurazione client:

<system.serviceModel>
  <bindings>
   <basicHttpBinding>
    <binding name="BasicHttpBinding_IDocumentLibraryService" closeTimeout="00:01:00"
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
     maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
     useDefaultWebProxy="true">
     <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
      maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
     <security mode="None">
      <transport clientCredentialType="None" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
  <client>
   <endpoint address="http://localhost:50764/DocumentLibraryService.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"
    contract="DocumentLibrary.IDocumentLibraryService" name="BasicHttpBinding_IDocumentLibraryService" />
  </client>

Configurazione del server:

<bindings>

            <basicHttpBinding>
                <binding name="BasicHttpBinding_IDocumentLibraryService" closeTimeout="00:01:00"
                 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                 messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                 useDefaultWebProxy="true">
                    <readerQuotas maxDepth="2147483647"
                maxStringContentLength="2147483647"
                maxArrayLength="2147483647"
                maxBytesPerRead="2147483647"
                maxNameTableCharCount="2147483647" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                         realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <services>

            <service name="BasicHttpBinding_IDocumentLibraryService">

                <clear />
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" />
                <endpoint binding="basicHttpBinding" name="DocumentLibraryService" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" address=""
                          bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"/>
            </service>
        </services>
È stato utile?

Soluzione

Tutto quello che dovevo fare era modificare il nome del servizio nel file Web.config in nome del servizio completo con spazio dei nomi:

<service name="SampleNameSpace.DocumentLibraryService">

                <clear />
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" />
                <endpoint binding="basicHttpBinding" name="DocumentLibraryService" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" address=""
                          bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"/>
            </service>

Altri suggerimenti

Questa non è proprio una risposta poiché la tua configurazione sembra OK. Penso che tu debba solo controllare questi valori nel codice (output su traccia o debug) sul Host di servizio e il proxy Per assicurarsi che gli stessi valori nella configurazione siano caricati nei canali.

Sulla possibilità è che venga raggiunta un'altra soglia e l'errore è fuorviante

Adesso io Consiglio vivamente di utilizzare l'uso di byte per caricare file Soprattutto se usi XML. Questi saranno rappresentati come array XML e la struttura sarà enormemente gonfio XML che richiederà 10 volte di più rispetto al file originale.

Io userei:

  • Streaming WCF che funziona anche con l'associazione di base ed è super veloce
  • in alternativa rappresentare l'array di byte come base64 corda. Questo richiederà il 33% in più di spazio ma non il 1000%

AGGIORNARE

È possibile tracciare il nome vincolante utilizzato per configurare il servizio (usalo all'interno di una qualsiasi delle operazioni WCF):

public int MyServiceOperation()
{
     Trace.WriteLine(OperationContext.Current.EndpointDispatcher.ChannelDispatcher.BindingName)
....
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top