Artikel ini adalah artikel cermin dari terjemahan mesin, silakan klik di sini untuk melompat ke artikel aslinya.

Melihat: 23136|Jawab: 0

[Sumber] c# Permintaan menerima karakter kacau untuk parameter

[Salin tautan]
Diposting pada 25/12/2015 18.41.49 | | | |


Pagi ini saya ditanyai pertanyaan oleh seorang kolega: Saya mengatakan bahwa parameter yang diterima kacau, izinkan saya membantu menyelesaikannya.


Platform yang menjadi tanggung jawab kolega saya dibuat Ext.js kerangka kerja, dan file konfigurasi web.config dikonfigurasi dengan pengkodean "GB2312" global:

<globalization requestEncoding="gb2312" responseEncoding="gb2312" fileEncoding="gb2312" culture="zh-CN"/>

Saat frontend mengirimkan "teks Cina", backend menerima karakter kacau dengan Request.QueryString["xxx"].

Tidak peduli bagaimana Anda memecahkan kode dengan System.Web.HttpUtility.UrlDecode("xxx", "jenis pengkodean"), itu tidak berfungsi.

Deskripsi prinsip:
1: Hal pertama yang harus ditentukan adalah ketika parameter URL klien dikirimkan, Ext.js akan mengkodekannya sebelum mengirimkannya, dan pengkodean klien adalah pengkodean UTF-8 secara default


2: Lalu mengapa kacau saat menerima parameter dengan Request.QueryString["xxx"]?

Kami membalikkan kompilasi selangkah demi selangkah,
2.1: Lihat kode untuk properti QueryString:

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->public NameValueCollection QueryString
  2. {
  3.     get
  4.     {
  5.         if (this._queryString == null)
  6.         {
  7.             this._queryString = new HttpValueCollection();
  8.             if (this._wr != null)
  9.             {
  10.                 this.FillInQueryStringCollection();//重点代码切入点
  11.             }
  12.             this._queryString.MakeReadOnly();
  13.         }
  14.         if (this._flags[1])
  15.         {
  16.             this._flags.Clear(1);
  17.             ValidateNameValueCollection(this._queryString, "Request.QueryString");
  18.         }
  19.         return this._queryString;
  20.     }
  21. }
Salin kode

2.2: Potong ke dalam metode FillInQueryStringCollection()

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->private void FillInQueryStringCollection()
  2. {
  3.     byte[] queryStringBytes = this.QueryStringBytes;
  4.     if (queryStringBytes != null)
  5.     {
  6.         if (queryStringBytes.Length != 0)
  7.         {
  8.             this._queryString.FillFromEncodedBytes(queryStringBytes, this.QueryStringEncoding);
  9.         }
  10.     }//上面是对流字节的处理,即文件上传之类的。
  11.     else if (!string.IsNullOrEmpty(this.QueryStringText))
  12.     {
  13.         //下面这句是对普通文件提交的处理:FillFromString是个切入点,编码切入点是:this.QueryStringEncoding
  14.         this._queryString.FillFromString(this.QueryStringText, true, this.QueryStringEncoding);
  15.         
  16.     }
  17. }
Salin kode

2.3: Potong: QueryStringEncoding

  1. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal Encoding QueryStringEncoding
  2. {
  3.     get
  4.     {
  5.         Encoding contentEncoding = this.ContentEncoding;
  6.         if (!contentEncoding.Equals(Encoding.Unicode))
  7.         {
  8.             return contentEncoding;
  9.         }
  10.         return Encoding.UTF8;
  11.     }
  12. }
  13. //点击进入this.ContentEncoding则为:
  14. public Encoding ContentEncoding
  15. {
  16.     get
  17.     {
  18.         if (!this._flags[0x20] || (this._encoding == null))
  19.         {
  20.             this._encoding = this.GetEncodingFromHeaders();
  21.             if (this._encoding == null)
  22.             {
  23.                 GlobalizationSection globalization = RuntimeConfig.GetLKGConfig(this._context).Globalization;
  24.                 this._encoding = globalization.RequestEncoding;
  25.             }
  26.             this._flags.Set(0x20);
  27.         }
  28.         return this._encoding;
  29.     }
  30.     set
  31.     {
  32.         this._encoding = value;
  33.         this._flags.Set(0x20);
  34.     }
  35. }
Salin kode
Dari kode QueryStringEncoding, sistem default ke metode pengodean simpul konfigurasi globalisasi, dan jika tidak, defaultnya adalah pengodean UTF-8
2.4: Potong menjadi FillFromString (string s, bool urlencoded, Pengkodean pengkodean)

  1. 代码有点长,就折叠起来了

  2. Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->internal void FillFromString(string s, bool urlencoded, Encoding encoding)
  3. {
  4.     int num = (s != null) ? s.Length : 0;
  5.     for (int i = 0; i < num; i++)
  6.     {
  7.         int startIndex = i;
  8.         int num4 = -1;
  9.         while (i < num)
  10.         {
  11.             char ch = s[i];
  12.             if (ch == '=')
  13.             {
  14.                 if (num4 < 0)
  15.                 {
  16.                     num4 = i;
  17.                 }
  18.             }
  19.             else if (ch == '&')
  20.             {
  21.                 break;
  22.             }
  23.             i++;
  24.         }
  25.         string str = null;
  26.         string str2 = null;
  27.         if (num4 >= 0)
  28.         {
  29.             str = s.Substring(startIndex, num4 - startIndex);
  30.             str2 = s.Substring(num4 + 1, (i - num4) - 1);
  31.         }
  32.         else
  33.         {
  34.             str2 = s.Substring(startIndex, i - startIndex);
  35.         }
  36.         if (urlencoded)//外面的传值默认是true,所以会执行以下语句
  37.         {
  38.             base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));
  39.         }
  40.         else
  41.         {
  42.             base.Add(str, str2);
  43.         }
  44.         if ((i == (num - 1)) && (s[i] == '&'))
  45.         {
  46.             base.Add(null, string.Empty);
  47.         }
  48.     }
  49. }
Salin kode
Dari titik ini kita menemukan bahwa semua input parameter dipanggil sekali: HttpUtility.UrlDecode(str2, pengkodean);

Ketika klien js mengirimkan bahasa Cina ke server dalam pengkodean utf-8, saat menerimanya dengan Request.QueryString, pertama-tama akan memecahkan kodenya sekali dengan gb2312 yang dikonfigurasi oleh globalisasi, menghasilkan karakter yang kacau.

1: Metode pengkodean JS adalah URT-8

2: Sisi server telah mengonfigurasi default ke GB2312

3: Request.QueryString akan memanggil HttpUtility.UrlDecode secara default untuk memecahkan kode parameter yang diterima dengan pengkodean konfigurasi sistem.

1: Sistem memilih pengkodean default dalam urutan berikut: header permintaan http - >node konfigurasi globalisasi - UTF-8 default

2: Saat memasukkan URL langsung ke bahasa Cina, browser yang berbeda dapat menanganinya secara berbeda, misalnya: IE tidak mengkodekan dan mengirimkan secara langsung, Firefox mengirimkan URL setelah pengkodean GB2312.

3: Untuk "karakter Cina" yang tidak dikodekan, setelah menggunakan panggilan internal Request.QueryString HttpUtility.UrlDecode, oleh gb2312->utf-8,

Jika karakter Cina tidak ditemukan, itu akan diubah menjadi "%ufffd" secara default, menghasilkan karakter kacau yang tidak dapat diubah.

4: Jalan menuju resolusi
Mengetahui prinsipnya, ada banyak cara untuk menyelesaikannya:
1: Penyatuan global adalah pengkodean UTF-8, yang menghemat masalah dan kekhawatiran.

2: Ketika GB2312 ditentukan secara global, urlnya adalah bahasa Cina, dan js harus dikodekan, seperti kerangka kerja ext.js.

Dengan cara ini, Anda hanya dapat menanganinya secara khusus, menentukan pengkodean dan decoding di sisi server.
Karena sistem default memanggil HttpUtility.UrlDecode("xxx", pengkodean konfigurasi sistem) sekali,
Jadi Anda memanggil HttpUtility.UrlEncode("xxx", pengkodean yang dikonfigurasi oleh sistem) lagi untuk kembali ke parameter pengkodean urt-8 asli

Kemudian gunakan HttpUtility.UrlDecode("xxx", utf-8) untuk memecahkan kodenya.
string aaa = permintaan. Request.QueryString["admin"];    Pemilik rumah
                            string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Mantan:Hai
Depan:Sungguh algoritma, saya telah tertekan selama beberapa hari.
Sanggahan:
Semua perangkat lunak, materi pemrograman, atau artikel yang diterbitkan oleh Code Farmer Network hanya untuk tujuan pembelajaran dan penelitian; Konten di atas tidak boleh digunakan untuk tujuan komersial atau ilegal, jika tidak, pengguna akan menanggung semua konsekuensi. Informasi di situs ini berasal dari Internet, dan sengketa hak cipta tidak ada hubungannya dengan situs ini. Anda harus sepenuhnya menghapus konten di atas dari komputer Anda dalam waktu 24 jam setelah pengunduhan. Jika Anda menyukai program ini, harap dukung perangkat lunak asli, pembelian pendaftaran, dan dapatkan layanan asli yang lebih baik. Jika ada pelanggaran, silakan hubungi kami melalui email.

Mail To:help@itsvse.com