Điều này gây ra "Độ dài không hợp lệ cho mảng ký tự Base-64"


91

Tôi có rất ít để đi tiếp ở đây. Tôi không thể tái tạo cục bộ điều này, nhưng khi người dùng gặp lỗi, tôi sẽ nhận được thông báo ngoại lệ email tự động:

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

Tôi có xu hướng nghĩ rằng có vấn đề với dữ liệu đang được chỉ định cho dạng xem. Ví dụ:

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

Thật khó để đoán nguồn gốc của lỗi mà không thể tạo lại lỗi cục bộ.

Nếu bất kỳ ai đã có kinh nghiệm với lỗi này, tôi thực sự muốn biết những gì bạn phát hiện ra.

Câu trả lời:


36

Tôi đã thấy lỗi này do sự kết hợp giữa viewstate có kích thước tốt và quá nhiều thiết bị / tường lửa lọc nội dung tích cực (đặc biệt là khi xử lý các cơ sở Giáo dục K-12).

Chúng tôi đã giải quyết vấn đề này bằng cách lưu trữ Viewstate trong SQL Server. Trước khi đi theo lộ trình đó, tôi khuyên bạn nên cố gắng hạn chế việc sử dụng viewstate bằng cách không lưu trữ bất kỳ thứ gì lớn trong đó và tắt nó cho tất cả các điều khiển không cần đến nó.

Tài liệu tham khảo để lưu trữ ViewState trong SQL Server:
MSDN - Tổng quan về PageStatePersister
ASP Alliance - Phương pháp đơn giản để lưu trữ viewstate trong SQL Server
Code Project - ViewState Provider Model


Tôi đã sao chép toàn bộ trang và dán nó vào Word. Nó dài hơn 86000 ký tự. Điều đó dường như là quá nhiều.
Mỏng

Rất tiếc, tôi đang gặp sự cố. Tôi đã tắt ViewState cho tất cả các điều khiển mà tôi có thể. Tôi đang sử dụng điều khiển Wizard với một số trang và nhiều nội dung. Có lời khuyên nào không?
Mike Cole

@Mike C., đây là một vấn đề rất khó chịu! Bạn có thể chia nội dung của từng trang của trình hướng dẫn thành các điều khiển của người dùng và tải nội dung theo yêu cầu (thông qua ajax?). Tất nhiên, đây chỉ là giải pháp cho một trang đó, nếu bạn bắt đầu gặp vấn đề trên cơ sở nhất quán, bạn có thể muốn xem xét lưu trữ trạng thái xem trong cơ sở dữ liệu của mình. Tôi đã cập nhật câu trả lời của mình với các tham chiếu để lưu trữ dạng xem trong SQL Server.
Jimmie R. Houts

1
Một vấn đề khác mà tôi gặp phải với hơn 86000 ký tự dài (tôi nghĩ thực sự có thể gần 85K, giả sử là ký tự byte đơn) là ứng dụng .NET của bạn cũng có thể bắt đầu đặt các chuỗi viewstate trên heap đối tượng lớn có thể dẫn đến heap phân mảnh theo thời gian (và cuối cùng là OutOfMemoryException) nếu nhóm ứng dụng không được tái chế.
nothingisnecessary

Tôi gặp vấn đề tương tự, làm thế nào để giải quyết vấn đề này, vui lòng làm rõ nó.
Sajith

84

Sau khi urlDecode xử lý văn bản, nó thay thế tất cả các ký tự '+' bằng '' ... do đó lỗi. Bạn chỉ cần gọi câu lệnh này để làm cho nó tương thích lại với base 64:

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

Công cụ tuyệt vời. Cảm ơn. Tôi đang gọi một dịch vụ web ASP.NET từ một ứng dụng C ++ MFC và có thể đã phân nhánh theo nhiều hướng để cố gắng giải quyết vấn đề này và sau khi đã dành một vài giờ cho nó. Bạn vừa tiết kiệm cho tôi rất nhiều thời gian.
nspire

3
Chỉ cần giải quyết vấn đề này và như bạn đã nói đó là khoảng trắng, thay thế bằng +sửa chữa nó. Anh hùng!
mattytommo

Bất cứ ai có thể cho hướng dẫn về nơi để bao gồm mã này? Tôi đang giải quyết vấn đề này thường xuyên, nhưng từ đoạn mã, tôi không thể xác định nơi triển khai bản sửa lỗi.
dst3p

@ dst3p Sử dụng nó ở bất kỳ đâu trong quy trình xử lý mà bạn gặp lỗi. Kiểm tra dấu vết ngăn xếp của bạn và xem phương pháp nào đang gây ra lỗi.
Jalal El-Shaer

21

Tôi đoán là có điều gì đó đang mã hóa hoặc giải mã quá thường xuyên - hoặc bạn có văn bản với nhiều dòng.

Chuỗi Base64 phải là bội số của 4 ký tự - cứ 4 ký tự đại diện cho 3 byte dữ liệu đầu vào. Bằng cách nào đó, dữ liệu trạng thái xem đang được ASP.NET chuyển lại bị hỏng - độ dài không phải là bội số của 4.

Bạn có đăng nhập tác nhân người dùng khi điều này xảy ra không? Tôi tự hỏi liệu đó có phải là một trình duyệt hoạt động kém ở đâu đó không ... một khả năng khác là có một proxy đang làm những việc nghịch ngợm. Tương tự như vậy, hãy thử ghi lại độ dài nội dung của yêu cầu, vì vậy bạn có thể xem liệu nó có chỉ xảy ra với các yêu cầu lớn hay không.


Trong trường hợp của tôi các trình duyệt luôn luôn là Safari, hoặc điện thoại di động hoặc máy tính để bàn phiên bản
cockypup

12

Thử cái này:

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

Phương pháp này đã giúp giải quyết vấn đề. Mặc dù tôi không sử dụng mã hóa UTF8
Abhishek Shrivastava

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

đâu qslà chuỗi được mã hóa base64


8

Như những người khác đã đề cập, điều này có thể xảy ra khi một số tường lửa và proxy ngăn chặn quyền truy cập vào các trang chứa một lượng lớn dữ liệu ViewState.

ASP.NET 2.0 đã giới thiệu cơ chế ViewState Chunking giúp chia nhỏ ViewState thành các phần có thể quản lý được, cho phép ViewState đi qua proxy / tường lửa mà không gặp vấn đề gì.

Để bật tính năng này, chỉ cần thêm dòng sau vào tệp web.config của bạn.

<pages maxPageStateFieldLength="4000">

Điều này không nên được sử dụng như một giải pháp thay thế để giảm kích thước ViewState của bạn nhưng nó có thể là một biện pháp hỗ trợ hiệu quả chống lại lỗi "Độ dài không hợp lệ cho mảng ký tự Base-64" do các proxy tích cực và những thứ tương tự.


điều này có thể có bất kỳ tác dụng phụ?
MonsterMMORPG

Không mà tôi đã từng quan sát, thêm thông tin về ViewState
Red Taz

vậy chiều dài tối ưu của bạn là bao nhiêu? tôi đã thiết lập nó 1024
MonsterMMORPG

1

Đây không phải là một câu trả lời, thật đáng buồn. Sau khi gặp lỗi gián đoạn một thời gian và cuối cùng đã đủ khó chịu để cố gắng sửa nó, tôi vẫn chưa tìm ra cách khắc phục. Tuy nhiên, tôi đã xác định được một công thức để tái tạo vấn đề của mình, có thể giúp ích cho những người khác.

Trong trường hợp của tôi, đây là một vấn đề hoàn toàn có thể xảy ra với localhost, trên máy dev của tôi cũng có DB của ứng dụng. Đó là ứng dụng .NET 2.0 mà tôi đang chỉnh sửa với VS2005. Máy Win7 64 bit cũng đã cài đặt VS2008 và .NET 3.5.

Đây là những gì sẽ tạo ra lỗi, từ nhiều dạng khác nhau:

  1. Tải một bản sao mới của biểu mẫu.
  2. Nhập một số dữ liệu và / hoặc đăng lại bằng bất kỳ điều khiển nào của biểu mẫu. Miễn là không có sự chậm trễ đáng kể, hãy lặp lại tất cả những gì bạn thích và không xảy ra lỗi.
  3. Chờ một chút (có thể là 1 hoặc 2 phút, không quá 5 phút) và thử đăng lại một lần nữa.

Một hoặc hai phút trì hoãn "chờ máy chủ cục bộ" và sau đó trình duyệt "Đặt lại kết nối" và global.asaxnhật ký bẫy lỗi ứng dụng của:

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

Trong trường hợp này, nó không phải là KÍCH THƯỚC của viewstate, mà là điều gì đó liên quan đến bộ nhớ đệm của trang và / hoặc viewstate dường như đang khiến tôi khó chịu. Cài đặt <pages>các thông số enableEventValidation="false"viewStateEncryption="Never"trong Web.configkhông thay đổi hành vi. Cũng không đặt maxPageStateFieldLengthđiều gì đó khiêm tốn.


1

Hãy xem HttpHandlers của bạn. Tôi đã nhận thấy một số lỗi kỳ lạ và hoàn toàn ngẫu nhiên trong vài tháng qua sau khi tôi triển khai một công cụ nén (RadCompression của Telerik). Tôi đã nhận thấy các lỗi như:

  • System.Web.HttpException: Không thể xác thực dữ liệu.

  • System.Web.HttpException: Máy khách đã ngắt kết nối .---> System.Web.UI.ViewStateException: Viewstate không hợp lệ.

  • System.FormatException: Độ dài không hợp lệ cho mảng ký tự Base-64.

  • System.Web.HttpException: Máy khách bị ngắt kết nối. ---> System.Web.UI.ViewStateException: Viewstate không hợp lệ.

Tôi đã viết về điều này trên blog của tôi.


Blog của bạn đã ngừng hoạt động. Bạn có một liên kết khác hoặc bạn có thể đăng thông tin liên quan? thx
mga911


0

Điều này là do trạng thái chế độ xem rất lớn, Trong trường hợp của tôi, tôi đã gặp may vì tôi không sử dụng chế độ xem. Tôi vừa thêm enableviewstate="false"vào thẻ biểu mẫu và trạng thái xem đã tăng từ 35k lên 100 ký tự


0

Trong quá trình thử nghiệm ban đầu cho Membership.ValidateUser với SqlMembershipProvider, tôi sử dụng thuật toán băm (SHA1) kết hợp với một muối và nếu tôi thay đổi độ dài của muối thành độ dài không chia hết cho bốn, tôi đã nhận được lỗi này.

Tôi chưa thử bất kỳ bản sửa lỗi nào ở trên, nhưng nếu muối đang bị thay đổi, điều này có thể giúp ai đó xác định đó là nguồn gốc của lỗi cụ thể này.


0

Như Jon Skeet đã nói, chuỗi phải là bội số của 4 byte. Nhưng tôi vẫn nhận được lỗi.

Ít nhất nó đã bị loại bỏ trong chế độ gỡ lỗi. Đặt điểm ngắt Convert.FromBase64String()sau đó bước qua mã. Thật kỳ diệu, lỗi đã biến mất đối với tôi :) Nó có thể liên quan đến trạng thái Xem và các vấn đề tương tự khác như những người khác đã báo cáo.


0

Ngoài giải pháp của @ jalchr đã giúp tôi, tôi nhận thấy rằng khi gọi ATL::Base64Encodetừ một ứng dụng c ++ để mã hóa nội dung bạn chuyển đến một dịch vụ web ASP.NET, bạn cũng cần một thứ khác. Ngoài

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

từ giải pháp của @ jalchr, bạn cũng cần đảm bảo rằng bạn không sử dụngATL_BASE64_FLAG_NOPAD cờ trên ATL::Base64Encode:

 BOOL bEncoded = Base64Encode(lpBuffer,
                    nBufferSizeInBytes,
                    strBase64Encoded.GetBufferSetLength(base64Length),
                    &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.