Qué causa esta “longitud inválida para una matriz de caracteres Base-64”

Tengo muy poco para seguir aquí. No puedo reproducir esto localmente, pero cuando los usuarios reciben el error, recibo una notificación automática de excepción de correo electrónico:

Invalid length for a Base-64 char array. at System.Convert.FromBase64String(String s) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) at System.Web.UI.HiddenFieldPageStatePersister.Load() 

Me inclino a pensar que hay un problema con los datos que se asignan a viewstate. Por ejemplo:

 List SelectedActionIDList = GetSelectedActionIDList(); ViewState["_SelectedActionIDList"] = SelectedActionIDList; 

Es difícil adivinar el origen del error sin poder reproducir el error localmente.

Si alguien ha tenido alguna experiencia con este error, realmente me gustaría saber lo que descubrió.

He visto este error causado por la combinación de viewstate de buen tamaño y de dispositivos / firewalls de filtrado de contenido agresivo (especialmente cuando se trata de instituciones educativas K-12).

Lo solucionamos almacenando Viewstate en SQL Server. Antes de seguir esa ruta, recomendaría intentar limitar el uso de viewstate al no almacenar nada grande en él y desactivarlo para todos los controles que no lo necesiten.

Referencias para almacenar ViewState en SQL Server:
MSDN: descripción general de PageStatePersister
ASP Alliance: método simple para almacenar viewstate en SQL Server
Proyecto de código – Modelo de proveedor ViewState

Después de que urlDecode procesa el texto, reemplaza todos los caracteres ‘+’ con ” … por lo tanto, el error. Simplemente debe llamar a esta statement para volverla compatible con la base 64 nuevamente:

  sEncryptedString = sEncryptedString.Replace(' ', '+'); 

Supongo que algo es codificar o decodificar con demasiada frecuencia, o que tienes texto con varias líneas.

Las cadenas de Base64 tienen que tener un múltiplo de 4 caracteres de longitud, cada 4 caracteres representa 3 bytes de datos de entrada. De alguna manera, los datos de estado de vista que ASP.NET está transmitiendo están corruptos: la longitud no es un múltiplo de 4.

¿Registra el agente de usuario cuando esto ocurre? Me pregunto si es un navegador de mal comportamiento en alguna parte … otra posibilidad es que haya un proxy haciendo cosas malas. Asimismo, intente registrar la duración del contenido de la solicitud, para que pueda ver si solo sucede para solicitudes grandes.

 int len = qs.Length % 4; if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '='); 

donde qs es cualquier cadena codificada en base64

Prueba esto:

 public string EncodeBase64(string data) { string s = data.Trim().Replace(" ", "+"); if (s.Length % 4 > 0) s = s.PadRight(s.Length + 4 - s.Length % 4, '='); return Encoding.UTF8.GetString(Convert.FromBase64String(s)); } 

Como otros han mencionado, esto puede deberse a que algunos firewalls y proxies impiden el acceso a las páginas que contienen una gran cantidad de datos de ViewState.

ASP.NET 2.0 introdujo el mecanismo ViewState Chunking que divide el ViewState en fragmentos manejables, permitiendo que el ViewState pase sin problemas por el proxy / firewall.

Para habilitar esta característica, simplemente agregue la siguiente línea a su archivo web.config.

  

Esto no debe usarse como una alternativa para reducir el tamaño de su ViewState, pero puede ser un respaldo eficaz contra el error “Invalid length for a Base-64 char array” que resulta de proxies agresivos y similares.

Esta no es una respuesta, por desgracia. Después de encontrar el error intermitente por un tiempo y, finalmente, me molesta lo suficiente como para tratar de solucionarlo, todavía tengo que encontrar una solución. Sin embargo, he determinado una receta para reproducir mi problema, que podría ayudar a otros.

En mi caso, es SOLAMENTE un problema de servidor local, en mi máquina de desarrollo que también tiene la base de datos de la aplicación. Es una aplicación .NET 2.0 que estoy editando con VS2005. La máquina Win7 de 64 bits también tiene instalados VS2008 y .NET 3.5.

Esto es lo que generará el error, desde una variedad de formas:

  1. Cargue una nueva copia del formulario.
  2. Ingrese algunos datos y / o devolución de datos con cualquiera de los controles del formulario. Siempre que no haya un retraso significativo, repita todo lo que quiera y no se produzcan errores.
  3. Espere un momento (1 o 2 minutos tal vez, no más de 5) y pruebe otra devolución de datos.

Uno o dos minutos tardan en “esperar al servidor local” y luego “el global.asax restableció la conexión” y los global.asax de global.asax error de la aplicación de global.asax :

 Application_Error event: Invalid length for a Base-64 char array. Stack Trace: at System.Convert.FromBase64String(String s) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) at System.Web.UI.HiddenFieldPageStatePersister.Load() 

En este caso, no es el TAMAÑO del viewstate, sino algo relacionado con la página y / o el almacenamiento en caché del estado de visualización que parece estar mordiéndome. Establecer los parámetros enableEventValidation="false" y viewStateEncryption="Never" en Web.config no modificó el comportamiento. Tampoco lo hizo el maxPageStateFieldLength a algo modesto.

Eche un vistazo a sus HttpHandlers. He notado algunos errores extraños y completamente aleatorios en los últimos meses después de implementar una herramienta de compresión (RadCompression de Telerik). Estaba notando errores como:

  • System.Web.HttpException: no se pueden validar los datos.

  • System.Web.HttpException: el cliente desconectado .—> System.Web.UI.ViewStateException: viewstate no válido.

y

  • System.FormatException: longitud no válida para una matriz char Base-64.

  • System.Web.HttpException: el cliente desconectado. —> System.Web.UI.ViewStateException: viewstate no válido.

Escribí sobre esto en mi blog.

Esto se debe a un gran estado de visualización, en mi caso tuve suerte ya que no estaba usando ViewState. Acabo de agregar enableviewstate="false" en la etiqueta del formulario y el estado de visualización pasó de 35k a 100 caracteres

Durante la prueba inicial de Membership.ValidateUser con un SqlMembershipProvider, utilizo un algoritmo hash (SHA1) combinado con un salt, y, si cambié la longitud de sal a una longitud no divisible por cuatro, recibí este error.

No he probado ninguna de las soluciones anteriores, pero si la sal está siendo alterada, esto puede ayudar a que alguien identifique que ese es el origen de este error en particular.

Como dijo Jon Skeet, la cadena debe ser múltiple de 4 bytes. Pero todavía estaba recibiendo el error.

Al menos se eliminó en modo de depuración. Coloque un punto de interrupción en Convert.FromBase64String() luego Convert.FromBase64String() el código. Milagrosamente, el error desapareció para mí 🙂 Probablemente esté relacionado con los estados de View y otros problemas similares a los que otros han informado.

Además de la solución de @jalchr que me ayudó, descubrí que cuando se llama a ATL::Base64Encode desde una aplicación de C ++ para codificar el contenido que se pasa a un servicio web de ASP.NET, también se necesita algo más. Además de

 sEncryptedString = sEncryptedString.Replace(' ', '+'); 

de la solución de @ jalchr, también debe asegurarse de no utilizar el indicador ATL_BASE64_FLAG_NOPAD en ATL::Base64Encode :

  BOOL bEncoded = Base64Encode(lpBuffer, nBufferSizeInBytes, strBase64Encoded.GetBufferSetLength(base64Length), &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);