Что вызвало это «Неверная длина для массива Base-64 char» - PullRequest
88 голосов
/ 13 мая 2009

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

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

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

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

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

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

Ответы [ 12 ]

82 голосов
/ 16 марта 2010

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

        sEncryptedString = sEncryptedString.Replace(' ', '+');
36 голосов
/ 13 мая 2009

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

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

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

21 голосов
/ 13 мая 2009

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

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

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

12 голосов
/ 16 февраля 2012

Попробуйте это:

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));
}
10 голосов
/ 18 октября 2011
int len = qs.Length % 4;
            if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');

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

8 голосов
/ 27 января 2014

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

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

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

<pages maxPageStateFieldLength="4000">

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

1 голос
/ 30 сентября 2010

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

В моем случае это единственная проблема на локальном хосте, на моей машине разработчика, на которой также есть база данных приложения. Это приложение .NET 2.0, которое я редактирую с помощью VS2005. На 64-битной машине Win7 также установлены VS2008 и .NET 3.5.

Вот что генерирует ошибку из множества форм:

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

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

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

1 голос
/ 04 августа 2009

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

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

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

и

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

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

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

0 голосов
/ 26 сентября 2014

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

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

0 голосов
/ 08 июля 2012

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

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*/);
...