[.net] 이 “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;

로컬에서 오류를 재현 할 수 없으면 오류의 원인을 추측하기가 어렵습니다.

이 오류에 대한 경험이있는 사람이 있다면 무엇을 알게되었는지 알고 싶습니다.



답변

이 오류는 적절한 크기의 뷰 상태와 공격적인 콘텐츠 필터링 장치 / 방화벽 (특히 K-12 교육 기관을 처리 할 때)의 조합으로 인해 발생하는 것을 보았습니다.

SQL Server에 Viewstate를 저장하여이 문제를 해결했습니다. 그 경로를 가기 전에 큰 것을 저장하지 않고 필요하지 않은 모든 컨트롤에 대해 꺼서 viewstate의 사용을 제한하는 것이 좋습니다.

SQL Server에 ViewState를 저장하기위한 참조 :
MSDN-PageStatePersister
ASP Alliance 개요 -SQL Server 코드 프로젝트에 viewstate를 저장하는 간단한 방법 -ViewState
공급자 모델


답변

urlDecode가 텍스트를 처리 한 후 모든 ‘+’문자를 ”…로 대체하므로 오류가 발생합니다. 이 명령문을 호출하여 base 64와 다시 호환되도록해야합니다.

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


답변

제 생각에는 무언가가 너무 자주 인코딩 또는 디코딩되거나 여러 줄로 된 텍스트가 있다는 것입니다.

Base64 문자열은 길이가 4 자의 배수 여야합니다. 4 자마다 3 바이트의 입력 데이터를 나타냅니다. 어떻게 든 ASP.NET에 의해 다시 전달되는 뷰 상태 데이터가 손상되었습니다. 길이는 4의 배수가 아닙니다.

이 경우 사용자 에이전트를 기록합니까? 어딘가에서 잘못 작동하는 브라우저인지 궁금합니다. 또 다른 가능성은 장난스러운 일을하는 프록시가 있다는 것입니다. 마찬가지로 요청의 콘텐츠 길이를 기록하여 큰 요청에 대해서만 발생하는지 확인할 수 있습니다.


답변

이 시도:

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


답변

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

qsbase64로 인코딩 된 문자열은 어디에 있습니까?


답변

다른 사람들이 언급했듯이 이는 일부 방화벽과 프록시가 많은 양의 ViewState 데이터를 포함하는 페이지에 대한 액세스를 차단할 때 발생할 수 있습니다.

ASP.NET 2.0에서는 ViewState 를 관리 가능한 청크로 분할하여 ViewState가 문제없이 프록시 / 방화벽을 통과 할 수 있도록 하는 ViewState 청킹 메커니즘 을 도입했습니다 .

이 기능을 사용하려면 web.config 파일에 다음 줄을 추가하면됩니다.

<pages maxPageStateFieldLength="4000">

이것은해야 하지 귀하의 ViewState의 크기를 줄이는 대안으로 사용할 수 있지만, 공격적인 프록시 등으로 인한 오류은 “Base-64 문자 배열의 길이가 잘못”에 대한 효과적인 역전 될 수있다.


답변

슬프게도 이것은 대답이 아닙니다. 한동안 간헐적 인 오류가 발생하고 마침내 그것을 고치려고 충분히 짜증을 냈지만 아직 수정 사항을 찾지 못했습니다. 그러나 다른 사람들에게 도움이 될 수있는 내 문제를 재현하는 방법을 결정했습니다.

제 경우에는 앱의 DB가있는 내 dev 컴퓨터에서 전적으로 localhost 문제입니다. VS2005로 편집중인 .NET 2.0 앱입니다. Win7 64 비트 시스템에는 VS2008 및 .NET 3.5도 설치되어 있습니다.

다양한 형식에서 오류를 생성하는 것은 다음과 같습니다.

  1. 양식의 새 사본을로드하십시오.
  2. 양식의 컨트롤을 사용하여 일부 데이터 및 / 또는 포스트 백을 입력합니다. 상당한 지연이없는 한 원하는대로 반복하면 오류가 발생하지 않습니다.
  3. 잠시 기다렸다가 (1 ~ 2 분 정도, 5 분 이내) 다른 포스트 백을 시도하십시오.

브라우저에서 “localhost를 기다리는 중”1 ~ 2 분 후 “연결이 재설정되었습니다”라는 지연과 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의 SIZE가 아니라 페이지 및 / 또는 viewstate 캐싱과 관련된 것이 나를 물고있는 것처럼 보입니다. <pages>매개 변수를 설정 enableEventValidation="false"하고 viewStateEncryption="Never"에서 Web.config동작을 변경하지 않았습니다. 어느 쪽도 maxPageStateFieldLength겸손한 것으로 설정하지 않았습니다 .