Apa yang menyebabkan "Panjang tidak valid untuk array karakter Base-64" ini

91

Saya hanya punya sedikit hal untuk dilanjutkan di sini. Saya tidak dapat mereproduksi ini secara lokal, tetapi ketika pengguna mendapatkan kesalahan saya mendapatkan pemberitahuan pengecualian email otomatis:

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

Saya cenderung berpikir ada masalah dengan data yang ditugaskan ke kondisi tampilan. Sebagai contoh:

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

Sulit untuk menebak sumber kesalahan tanpa bisa mereproduksi kesalahan secara lokal.

Jika ada yang pernah mengalami kesalahan ini, saya sangat ingin tahu apa yang Anda temukan.

Ramping
sumber

Jawaban:

36

Saya telah melihat kesalahan ini yang disebabkan oleh kombinasi kondisi tampilan yang baik dan perangkat / firewall pemfilteran konten yang agresif (terutama saat menangani institusi Pendidikan K-12).

Kami mengatasinya dengan menyimpan Kondisi Tampilan di SQL Server. Sebelum pergi ke rute itu, saya akan merekomendasikan mencoba membatasi penggunaan kondisi tampilan dengan tidak menyimpan sesuatu yang besar di dalamnya dan mematikannya untuk semua kontrol yang tidak membutuhkannya.

Referensi untuk menyimpan
Kondisi Tampilan di SQL Server: MSDN - Ikhtisar PageStatePersister
ASP Alliance - Metode sederhana untuk menyimpan kondisi tampilan di Proyek Kode SQL Server - Model Penyedia Kondisi Tampilan

Jimmie R. Houts
sumber
Saya menyalin status veiw dari halaman dan menempelkannya ke Word. Panjangnya lebih dari 86.000 karakter. Sepertinya terlalu berlebihan.
Slim
Astaga, saya mengalami masalah sekarang. Saya telah mematikan Kondisi Tampilan untuk semua kontrol yang saya bisa. Saya menggunakan kontrol Wizard dengan beberapa halaman dan banyak konten. Ada saran?
Mike Cole
@ Mike C., ini adalah masalah yang sangat membuat frustrasi! Anda bisa memecah konten setiap halaman wizard menjadi kontrol pengguna dan memuat konten sesuai permintaan (melalui ajax?). Tentu saja, ini hanya solusi untuk satu halaman tersebut, jika Anda mulai mengalami masalah secara konsisten, Anda mungkin ingin mempertimbangkan untuk menyimpan kondisi tampilan dalam database Anda. Saya telah memperbarui jawaban saya dengan referensi untuk menyimpan kondisi tampilan di SQL Server.
Jimmie R. Houts
1
Masalah lain yang saya hadapi dengan panjang lebih dari 86000 karakter (sebenarnya mungkin mendekati 85K menurut saya, dengan asumsi karakter byte tunggal) adalah bahwa aplikasi .NET Anda juga dapat mulai meletakkan string kondisi tampilan pada tumpukan objek besar yang dapat mengarah ke heap fragmentasi seiring waktu (dan akhirnya OutOfMemoryException) jika kumpulan aplikasi tidak didaur ulang.
nothingisnecessary
Saya mendapat masalah yang sama, bagaimana mengatasi masalah ini, mohon klarifikasi.
Sajith
84

Setelah urlDecode memproses teks, itu menggantikan semua '+' karakter dengan '' ... jadi kesalahan. Anda cukup memanggil pernyataan ini agar basis 64 kompatibel lagi:

        sEncryptedString = sEncryptedString.Replace(' ', '+');
Jalal El-Shaer
sumber
Barang bagus. Terima kasih. Saya menelepon layanan web ASP.NET dari aplikasi C ++ MFC dan bisa bercabang ke banyak arah mencoba menyelesaikan ini dan setelah menghabiskan beberapa jam di atasnya. Anda baru saja menghemat banyak waktu saya.
nspire
3
Pukul saja masalah ini dan seperti yang Anda katakan itu spasi, ganti dengan +memperbaikinya. Pahlawan!
mattytommo
Adakah yang bisa memberi panduan tentang di mana memasukkan kode ini? Saya sering berurusan dengan masalah ini, tetapi dari cuplikan kode, saya tidak dapat menentukan di mana harus menerapkan perbaikan.
dst3p
@ dst3p Gunakan di mana pun dalam pipeline pemrosesan Anda menghadapi kesalahan. Periksa pelacakan tumpukan Anda dan lihat metode mana yang menyebabkan kesalahan.
Jalal El-Shaer
21

Dugaan saya adalah ada sesuatu yang terlalu sering encoding atau decoding - atau Anda memiliki teks dengan banyak baris.

String Base64 harus kelipatan 4 karakter - setiap 4 karakter mewakili 3 byte data input. Entah bagaimana, data status tampilan yang dikirimkan kembali oleh ASP.NET rusak - panjangnya bukan kelipatan 4.

Apakah Anda memasukkan agen pengguna saat ini terjadi? Saya bertanya-tanya apakah itu browser yang berperilaku buruk di suatu tempat ... kemungkinan lain adalah ada proxy yang melakukan hal-hal nakal. Coba juga untuk mencatat panjang konten permintaan, sehingga Anda dapat melihat apakah itu hanya terjadi untuk permintaan besar.

Jon Skeet
sumber
Dalam kasus saya, browser selalu Safari, baik versi seluler atau desktop
cockypup
12

Coba ini:

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));
}
Petr Voborník
sumber
Metode ini membantu menyelesaikan masalah. Meskipun saya tidak menggunakan pengkodean UTF8
Abhishek Shrivastava
11
int len = qs.Length % 4;
            if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');

di mana qsada string yang dikodekan base64

Bhuvana
sumber
8

Seperti yang telah disebutkan orang lain, ini dapat terjadi jika beberapa firewall dan proxy mencegah akses ke halaman yang berisi data ViewState dalam jumlah besar.

ASP.NET 2.0 memperkenalkan mekanisme Pemotongan Kondisi Tampilan yang memecah Kondisi Tampilan menjadi bagian yang dapat dikelola, memungkinkan Kondisi Tampilan melewati proxy / firewall tanpa masalah.

Untuk mengaktifkan fitur ini cukup tambahkan baris berikut ke file web.config Anda.

<pages maxPageStateFieldLength="4000">

Ini tidak boleh digunakan sebagai alternatif untuk mengurangi ukuran Kondisi Tampilan Anda, tetapi ini bisa menjadi penghenti yang efektif terhadap kesalahan "Panjang tidak valid untuk array karakter Base-64" yang dihasilkan dari proxy agresif dan sejenisnya.

Red Taz
sumber
mungkinkah ini memiliki efek samping?
MonsterMMORPG
Tidak ada yang pernah saya amati, informasi lebih lanjut tentang kondisi tampilan
Red Taz
jadi berapa panjang optimal Anda? saya mengaturnya 1024
MonsterMMORPG
1

Sayangnya, ini bukanlah jawaban. Setelah mengalami kesalahan intermiten selama beberapa waktu dan akhirnya cukup kesal untuk mencoba memperbaikinya, saya belum menemukan perbaikan. Namun, saya telah menentukan resep untuk mereproduksi masalah saya, yang mungkin dapat membantu orang lain.

Dalam kasus saya, ini HANYA masalah localhost, di mesin dev saya yang juga memiliki DB aplikasi. Ini adalah aplikasi .NET 2.0 yang saya edit dengan VS2005. Mesin Win7 64 bit juga memiliki VS2008 dan .NET 3.5 diinstal.

Inilah yang akan menghasilkan kesalahan, dari berbagai bentuk:

  1. Muat salinan baru formulir.
  2. Masukkan beberapa data, dan / atau postback dengan salah satu kontrol formulir. Selama tidak ada penundaan yang berarti, ulangi sesuka Anda, dan tidak ada kesalahan yang terjadi.
  3. Tunggu sebentar (mungkin 1 atau 2 menit, tidak lebih dari 5), dan coba postingan balik lainnya.

Satu atau dua menit penundaan "menunggu localhost" dan kemudian "Sambungan disetel ulang" oleh browser, dan global.asaxlog perangkap kesalahan aplikasi:

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

Dalam kasus ini, bukan SIZE dari kondisi tampilan, tetapi ada hubungannya dengan cache halaman dan / atau kondisi tampilan yang tampaknya mengganggu saya. Pengaturan <pages>parameter enableEventValidation="false", dan viewStateEncryption="Never"dalam Web.configtidak mengubah perilaku. Juga tidak mengatur maxPageStateFieldLengthke sesuatu yang sederhana.

fortboise
sumber
1

Lihatlah HttpHandlers Anda. Saya telah memperhatikan beberapa kesalahan aneh dan acak sepenuhnya selama beberapa bulan terakhir setelah saya menerapkan alat kompresi (RadCompression dari Telerik). Saya melihat kesalahan seperti:

  • System.Web.HttpException: Tidak dapat memvalidasi data.

  • System.Web.HttpException: Klien terputus .---> System.Web.UI.ViewStateException: Kondisi tampilan tidak valid.

dan

  • System.FormatException: Panjang tidak valid untuk array karakter Base-64.

  • System.Web.HttpException: Klien terputus. ---> System.Web.UI.ViewStateException: Kondisi tampilan tidak valid.

Saya menulis tentang ini di blog saya.

Michael
sumber
Blog Anda sedang down. Apakah Anda memiliki link lain atau dapatkah Anda memposting info yang relevan? thx
mga911
0

Ini karena status tampilan yang sangat besar, Dalam kasus saya, saya beruntung karena saya tidak menggunakan kondisi tampilan. Saya baru saja menambahkan enableviewstate="false"pada tag formulir dan status tampilan berubah dari 35k menjadi 100 karakter

coderman
sumber
0

Selama pengujian awal untuk Membership.ValidateUser dengan SqlMembershipProvider, saya menggunakan algoritme hash (SHA1) yang digabungkan dengan salt, dan, jika saya mengubah panjang salt menjadi panjang yang tidak habis dibagi empat, saya menerima error ini.

Saya belum mencoba salah satu perbaikan di atas, tetapi jika garam diubah, ini dapat membantu seseorang menunjukkan itu sebagai sumber kesalahan khusus ini.

John
sumber
0

Seperti yang dikatakan Jon Skeet, string harus kelipatan 4 byte. Tapi saya masih mendapatkan kesalahannya.

Setidaknya itu dihapus dalam mode debug. Letakkan titik istirahat Convert.FromBase64String()lalu lewati kode. Ajaibnya, kesalahan tersebut menghilang untuk saya :) Ini mungkin terkait dengan status View dan masalah serupa lainnya seperti yang dilaporkan orang lain.

Hammad Khan
sumber
0

Selain solusi @ jalchr yang membantu saya, saya menemukan bahwa saat memanggil ATL::Base64Encodedari aplikasi c ++ untuk menyandikan konten yang Anda berikan ke layanan web ASP.NET, Anda juga memerlukan sesuatu yang lain. Sebagai tambahannya

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

dari solusi @ jalchr, Anda juga perlu memastikan bahwa Anda tidak menggunakanATL_BASE64_FLAG_NOPAD flag pada ATL::Base64Encode:

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