이 "Base-64 char 배열의 잘못된 길이"의 원인


91

여기에 갈 것이 거의 없습니다. 이것을 로컬로 재현 할 수는 없지만 사용자에게 오류가 발생하면 자동 이메일 예외 알림이 표시됩니다.

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;

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

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

답변:


36

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

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

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


페이지의 veiwstate를 복사하여 Word에 붙여 넣었습니다. 길이가 86,000 자 이상이었습니다. 너무 많은 것 같습니다.
Slim

Yikes, 나는 지금 문제에 직면하고있다. 가능한 모든 컨트롤에 대해 ViewState를 해제했습니다. 여러 페이지와 많은 콘텐츠가있는 마법사 컨트롤을 사용하고 있습니다. 어떤 충고?
Mike Cole

@ Mike C., 이것은 매우 실망스러운 문제입니다! 마법사의 각 페이지의 콘텐츠를 사용자 컨트롤로 나누고 필요에 따라 콘텐츠를로드 할 수 있습니다 (ajax를 통해?). 물론 이것은 한 페이지에 대한 해결책 일뿐입니다. 문제가 지속적으로 발생하기 시작하면 데이터베이스에 viewstate를 저장하는 것이 좋습니다. SQL Server에 viewstate를 저장하기위한 참조로 답변을 업데이트했습니다.
Jimmie R. Houts

1
86000 자 이상 (실제로는 1 바이트 문자로 가정하면 85K에 가까울 수 있음)에 직면 한 또 다른 문제는 .NET 앱이 힙으로 이어질 수있는 큰 개체 힙에 viewstate 문자열을 넣을 수도 있다는 것입니다. 앱 풀이 재활용되지 않은 경우 시간 경과에 따른 조각화 (그리고 결국 OutOfMemoryException).
nothingisnecessary

동일한 문제가 발생했습니다.이 문제를 해결하는 방법을 명확히 해주세요.
Sajith

84

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

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

좋은 물건. 감사. C ++ MFC 응용 프로그램에서 ASP.NET 웹 서비스를 호출하고 있었고이 문제를 해결하기 위해 여러 방향으로 분기 할 수 있었고 이미 몇 시간을 보냈을 수있었습니다. 당신은 저에게 많은 시간을 절약했습니다.
nspire

3
이 문제를 해결하고 공백이라고 말했듯이 +수정하십시오. 영웅!
mattytommo 2013

누구든지이 코드를 포함 할 위치에 대한 지침을 줄 수 있습니까? 이 문제를 자주 다루고 있지만 코드 조각에서 수정 사항을 구현할 위치를 결정할 수 없습니다.
dst3p 19

@ dst3p 처리 파이프 라인에서 오류가 발생할 때마다 사용하십시오. 스택 추적을 확인하고 어떤 방법이 오류를 일으키는 지 확인하십시오.
Jalal El-Shaer

21

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

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

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


제 경우 브라우저는 항상 Safari, 모바일 또는 데스크톱 버전입니다
cockypup

12

이 시도:

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

이 방법은 문제를 해결하는 데 도움이되었습니다. UTF8 인코딩을 사용하지 않았지만
Abhishek Shrivastava 2014

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

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


8

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

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

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

<pages maxPageStateFieldLength="4000">

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


부작용이 있습니까?
MonsterMMORPG

내가 관찰 한 것을 없음, viewstate가에 대한 자세한 내용은
레드 TAZ

그래서 최적의 길이는 얼마입니까? 나는 그것을 설정했다 1024
MonsterMMORPG

1

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

제 경우에는 앱의 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겸손한 것으로 설정하지 않았습니다 .


1

HttpHandlers를 살펴보십시오. 압축 도구 (Telerik의 RadCompression)를 구현 한 후 지난 몇 달 동안 이상하고 완전히 임의적 인 오류를 발견했습니다. 나는 다음과 같은 오류를 발견했습니다.

  • System.Web.HttpException : 데이터의 유효성을 검사 할 수 없습니다.

  • System.Web.HttpException : 클라이언트 연결이 끊겼습니다 .---> System.Web.UI.ViewStateException : 잘못된 viewstate.

  • System.FormatException : Base-64 char 배열의 길이가 잘못되었습니다.

  • System.Web.HttpException : 클라이언트 연결이 끊어졌습니다. ---> System.Web.UI.ViewStateException : 잘못된 viewstate.

나는 이것대해 내 블로그에 썼다 .


블로그가 다운되었습니다. 다른 링크가 있거나 관련 정보를 게시 할 수 있습니까? thx
mga911 2014 년


0

이것은 거대한 뷰 상태 때문입니다. 제 경우에는 뷰 상태를 사용하지 않았기 때문에 운이 좋았습니다. 방금 enableviewstate="false"양식 태그에 추가 하고보기 상태가 35k에서 100 자로 변경되었습니다.


0

SqlMembershipProvider를 사용하여 Membership.ValidateUser에 대한 초기 테스트 중에 솔트와 결합 된 해시 (SHA1) 알고리즘을 사용하고 솔트 길이를 4로 나눌 수없는 길이로 변경하면이 오류가 발생했습니다.

위의 수정 사항 중 어느 것도 시도하지 않았지만 소금이 변경되는 경우 누군가 가이 특정 오류의 원인을 정확히 파악하는 데 도움이 될 수 있습니다.


0

Jon Skeet이 말했듯이 문자열은 4 바이트의 배수 여야합니다. 하지만 여전히 오류가 발생했습니다.

적어도 디버그 모드에서 제거되었습니다. 중단 점을 설정 Convert.FromBase64String()한 다음 코드를 단계별로 실행하십시오. 기적적으로 오류가 사라졌습니다. :) 다른 사람들이보고 한 것처럼 View 상태 및 유사한 다른 문제와 관련이 있습니다.


0

나를 도왔던 @jalchr의 솔루션 외에도 ATL::Base64EncodeC ++ 응용 프로그램에서 호출 하여 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*/);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.