2009-05-13 2 views
85

У меня очень мало возможностей для продолжения. Я не могу воспроизвести это локально, но когда пользователи получают сообщение об ошибке я получаю автоматическое уведомление по электронной почте исключения:Что вызывает «Недопустимая длина для массива символов Base-64»

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; 

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

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

ответ

34

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

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

Ссылки для хранения ViewState в SQL Server:
MSDN - Overview of PageStatePersister
ASP Alliance - Simple method to store viewstate in SQL Server
Code Project - ViewState Provider Model

+0

Я скопировал страницу страницы и вложил ее в Word. Это было более 86000 символов. Это похоже на слишком много. – Slim

+0

Yikes, теперь я сталкиваюсь с проблемой. Я отключил ViewState для всех элементов управления, которые, возможно, могу. Я использую элемент управления Wizard с несколькими страницами и большим количеством контента. Любой совет? –

+0

@Mike C., это очень неприятная проблема! Вы можете разбить содержимое каждой страницы мастера на пользовательские элементы управления и загрузить контент по требованию (через ajax?). Конечно, это только решение для одной страницы, если вы начинаете испытывать проблему на постоянной основе, вы можете захотеть сохранить хранилище в вашей базе данных. Я обновил свой ответ со ссылками на хранилище viewstate в SQL Server. –

21

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

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

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

+0

В моем случае браузерами всегда является Safari, либо мобильная, либо настольная версия. – cockypup

1

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

  • System.Web.HttpException: Не удалось проверить данные.

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

и

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

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

I wrote about this в моем блоге.

+0

Ваш блог не работает. У вас есть другая ссылка или вы можете разместить соответствующую информацию? thx – mga911

+1

http://web.archive.org/web/20111015131130/http://dot-net-sam.blogspot.com/2009/08/random-errors-invalid-length-for-base.html – csm8118

80

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

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

Отличный материал , Благодарю. Я вызывал веб-службу ASP.NET из приложения C++ MFC и мог разветвляться во многих направлениях, пытаясь решить эту проблему, и уже потратил на это несколько часов. Вы только что спасли мне кучу времени. – nspire

+3

Просто нажмите эту проблему, и, как вы сказали, это пробелы, заменив ее на '+' исправленную. Герой! – mattytommo

+1

Этот ответ должен быть помечен как ответ! –

0

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

0

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

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

Вот что будет генерировать ошибку, из различных форм:

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

минуту или две задержки «в ожидании локального хоста», а затем «Соединение сброшено» в браузере, и global.asax «s журналы ошибка приложения ловушку:

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

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

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

qs где любые закодированные base64 строки

9

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

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

Этот метод помог решить проблему. Хотя я не использовал кодировку UTF8 –

0

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

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

0

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

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

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

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

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

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

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

<pages maxPageStateFieldLength="4000"> 

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

+0

, может ли это иметь какой-либо побочный эффект? – MonsterMMORPG

+0

Нет, что я когда-либо наблюдал, [больше информации о viewstate] (https://msdn.microsoft.com/en-us/library/ms178198%28v=vs.85%29.aspx) –

+0

, так какая у вас оптимальная длина ? я установил его 1024 – MonsterMMORPG

0

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

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

Смежные вопросы