Что вызывает эту недопустимую длину для массива Base-64 char

У меня очень мало шансов пойти сюда. Я не могу воспроизвести это локально, но когда пользователи получают ошибку, я получаю автоматическое уведомление об исключении электронной почты:

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

Я склонен думать, что есть проблема с данными, которые назначаются viewstate. Например:

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

Невозможно угадать источник ошибки, не имея возможности локально воспроизвести ошибку.

Если у кого-то был опыт с этой ошибкой, мне бы очень хотелось узнать, что вы узнали.

Ответ 1

Я видел эту ошибку, вызванную сочетанием хорошего размера viewstate и агрессивных контент-фильтрующих устройств/брандмауэров (особенно при работе с учебными заведениями K-12).

Мы работали над этим, сохраняя Viewstate в SQL Server. Прежде чем идти по этому маршруту, я бы рекомендовал попытаться ограничить использование вами viewstate, не сохраняя в нем ничего большого и отключая его для всех элементов управления, которые ему не нужны.

Ссылки для хранения ViewState в SQL Server:
MSDN - Обзор pageStatePersister
ASP Alliance - простой способ хранения viewstate в SQL Server
Код проекта - Модель поставщика ViewState

Ответ 2

После того, как urlDecode обрабатывает текст, он заменяет все символы "+" на ""... таким образом, ошибку. Вы должны просто вызвать этот оператор, чтобы он снова совместился с базой 64:

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

Ответ 3

Я предполагаю, что что-то слишком часто кодируется или декодируется - или что у вас есть текст с несколькими строками.

Строки Base64 должны быть кратны 4 символам в длину - каждые 4 символа представляют 3 байта входных данных. Каким-то образом данные состояния представления, передаваемые ASP.NET, повреждены - длина не кратна 4.

Вы регистрируете пользовательский агент, когда это происходит? Интересно, где-то плохой браузер? Другая возможность заключается в том, что прокси-сервер делает непослушные вещи. Аналогичным образом попробуйте записать длину содержимого запроса, чтобы вы могли видеть, происходит ли это только при больших запросах.

Ответ 4

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

где qs - любая строка с кодировкой base64

Ответ 5

Попробуйте следующее:

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));
}

Ответ 6

Как упоминалось выше, это может быть вызвано тем, что некоторые брандмауэры и прокси-серверы предотвращают доступ к страницам, содержащим большое количество данных ViewState.

ASP.NET 2.0 представил механизм ViewState Chunking, который разбивает ViewState на управляемые куски, позволяя ViewState проходить через прокси-сервер/брандмауэр без проблем.

Чтобы включить эту функцию, просто добавьте следующую строку в файл web.config.

<pages maxPageStateFieldLength="4000">

Это должно быть не использоваться как альтернатива уменьшению размера ViewState, но может быть эффективным обратным затвором в отношении ошибки "Недопустимая длина для массива Base-64 char", вызванного агрессивными прокси-серверами и т.п.

Ответ 7

Взгляните на своих HttpHandlers. За последние несколько месяцев после внедрения инструмента сжатия (RadCompression от Telerik) я заметил некоторые странные и полностью случайные ошибки. Я заметил такие ошибки, как:

  • System.Web.HttpException: невозможно проверить данные.

  • System.Web.HttpException: клиент отключен.--- > System.Web.UI.ViewStateException: недопустимое состояние просмотра.

и

  • System.FormatException: недопустимая длина массива Base-64 char.

  • System.Web.HttpException: клиент отключен. --- > System.Web.UI.ViewStateException: недопустимое состояние просмотра.

I написал об этом в своем блоге.

Ответ 8

Это из-за огромного состояния представления. В моем случае мне повезло, так как я не использовал viewstate. Я просто добавил enableviewstate="false" в тег формы, и состояние представления перешло от 35k до 100 символов

Ответ 9

Это не ответ, к сожалению. После некоторого перерыва в прерывистой ошибке и, наконец, достаточно раздраженной, чтобы попытаться ее исправить, мне еще предстоит найти исправление. Однако я определил рецепт для воспроизведения моей проблемы, который может помочь другим.

В моем случае это ПОЛНОСТЬЮ проблема локального хоста, на моей машине dev, которая также имеет БД приложения. Это приложение .NET 2.0, которое я редактирую с помощью VS2005. На 64-битной машине Win7 также установлены VS2008 и .NET 3.5.

Здесь будет генерироваться ошибка из множества форм:

  • Загрузите новую копию формы.
  • Введите некоторые данные и/или обратную передачу с помощью любого из элементов управления формы. Пока нет существенной задержки, повторите все, что вам нравится, и ошибок не будет.
  • Подождите немного (1 или 2 минуты, может быть, не более 5), и попробуйте еще одну обратную передачу.

Минута или две задержки "Ожидание локального хоста", а затем "Соединение было reset" браузером и 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()

В этом случае это не РАЗМЕР viewstate, а что-то вроде кеширования страницы и/или viewstate, которое, кажется, кусает меня. Установка параметров <pages> enableEventValidation="false", а viewStateEncryption="Never" в Web.config не изменила поведение. Также не установили maxPageStateFieldLength что-то скромное.

Ответ 10

Во время первоначального тестирования для Memberhip.ValidateUser с SqlMembershipProvider я использую алгоритм хеша (SHA1) в сочетании с солью, и, если бы я изменил длину соли на длину, не делящуюся на четыре, я получил эту ошибку.

Я не пробовал никаких исправлений выше, но если соль изменяется, это может помочь кому-то определить это как источник этой конкретной ошибки.

Ответ 11

В дополнение к @jalchr решению, который помог мне, я обнаружил, что при вызове ATL::Base64Encode из приложения С++ для кодирования содержимого, которое вы передаете ASP.NET webservice, вам тоже нужно что-то другое. В дополнение к

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

из @jalchr, вам также необходимо убедиться, что вы не используете флаг ATL_BASE64_FLAG_NOPAD на ATL::Base64Encode:

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

Ответ 12

Как сказал Джон Скит, строка должна быть кратной 4 байтам. Но я все еще получал ошибку.

По крайней мере, он удалился в режиме отладки. Поместите точку останова на Convert.FromBase64String(), затем выполните код. Чудесно ошибка исчезла для меня:) Вероятно, это связано с состояниями просмотра и аналогичными другими проблемами, о которых сообщали другие.