.net - Qué causa esta "longitud inválida para una matriz de caracteres Base-64"
asp.net exception (12)
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<int> 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ó.
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*/);
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.
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.
<pages maxPageStateFieldLength="4000">
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.
Después de que urlDecode procesa el texto, reemplaza todos los caracteres ''+'' con '''' ... por lo tanto, el error. Simplemente debe llamar a esta declaración para volverla compatible con la base 64 nuevamente:
sEncryptedString = sEncryptedString.Replace('' '', ''+'');
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.
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.
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:
- Cargue una nueva copia del formulario.
- 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.
- 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 <pages>
enableEventValidation="false"
y viewStateEncryption="Never"
en Web.config
no modificó el comportamiento. Tampoco lo hizo el maxPageStateFieldLength
a algo modesto.
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
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
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));
}
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