Pregunta

Estoy escribiendo un servicio WCF para cargar archivos, pero arroja una excepción cuando la matriz de bytes tiene más de 16384 elementos.

Este es el detalle de excepción:

El formateador lanzó una excepción al intentar deserializar el mensaje: Error en la deserialización del mensaje de la solicitud de la operación 'CreatedOcument'. La cuota de longitud de matriz máxima (16384) se ha excedido mientras se lee los datos XML. Esta cuota puede aumentarse cambiando la propiedad MaxArrayLength en el objeto XMLDICCIONARYReRequotas utilizado al crear el lector XML. Línea 1, posición 22862.

La configuración para el cliente y el servidor establece la cuota de longitud de matriz máxima en 2147483647.

Configuración del cliente:

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

Configuración del servidor:

<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>
¿Fue útil?

Solución

Todo lo que tenía que hacer era cambiar el nombre del servicio en el archivo web.config al nombre completo del servicio con el espacio de nombres:

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

Otros consejos

Esta no es realmente una respuesta ya que su configuración parece estar bien. Creo que solo necesita verificar estos valores en el código (salida para rastrear o depurar) en el host de servicio y el apoderado Para asegurarse de que los mismos valores en config se carguen en sus canales.

Sobre la posibilidad es que se alcanza otro umbral y el error es engañoso

Ahora yo Aconsejar encarecidamente contra el uso de la matriz de bytes para cargar archivos Especialmente si usa XML. Estos se representarán como matrices XML y la estructura será enormemente hinchada XML, que tomará 10 veces más que el archivo original.

Yo usaría:

  • Transmisión de WCF que también funciona con vinculación básica y es súper rápido
  • alternativamente representar la matriz de bytes como base64 cuerda. Esto tomará un 33% más de espacio pero no del 1000%

ACTUALIZAR

Puede rastrear el nombre de enlace que se utilizó para configurar el servicio (úselo dentro de cualquiera de sus operaciones WCF):

public int MyServiceOperation()
{
     Trace.WriteLine(OperationContext.Current.EndpointDispatcher.ChannelDispatcher.BindingName)
....
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top