Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 23136|Yanıt: 0

[Kaynak] c# İstek, parametreler için karışık karakterler alır

[Bağlantıyı kopyala]
Yayınlandı 25.12.2015 18:41:49 | | | |


Bu sabah bir meslektaşım bana bir soru sordu: Alınan parametrelerin karıştığını söyledim, sorunu çözmeme yardım edeyim.


Meslektaşımın sorumlu olduğu platform Ext.js çerçeve oluşturulmuş ve web.config yapılandırma dosyası küresel "GB2312" kodlamasıyla yapılandırılmıştır:

<küreselleşme istekliKodlama="gb2312" yanıtıKodlama="gb2312" dosyaKodlama="gb2312" kültür="zh-CN"/>

Ön uç "Çince metni"ni gönderdiğinde, arka uç Request.QueryString["xxx"] ile bozulmuş karakterler alır.

System.Web.HttpUtility.UrlDecode("xxx", "encoding type") ile nasıl çözerseniz alın, bu yöntem işe yaramıyor.

İlke açıklaması:
1: İlk belirlenmesi gereken şey, istemcinin URL parametreleri gönderildiğinde, Ext.js bunları göndermeden önce kodlayacak ve istemcinin kodlaması varsayılan olarak UTF-8 kodlamasıdır


2: O zaman Request.QueryString["xxx"] ile parametreler alındığında neden bozuluyor?

Derlemeyi adım adım geri çeviriyoruz,
2.1: QueryString özelliğinin koduna bakın:

  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. }
Kopya kodu

2.2: FillInQueryStringCollection() yöntemine kesin

  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. }
Kopya kodu

2.3: Kesme: 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. }
Kopya kodu
QueryStringEncoding kodundan sistem, küreselleştirme yapılandırma düğümünün kodlama yöntemine varsayılan olarak geçer ve değilse, varsayılan UTF-8 kodlamasıdır
2.4: FillFromString'e Cut (string s, bool urlencoded, Kodlama kodlama)

  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. }
Kopya kodu
Bu noktadan itibaren tüm parametre girdilerinin bir kez çağrıldığını görüyoruz: HttpUtility.UrlDecode(str2, kodlama);

İstemci js, Çince'yi utf-8 kodlamasında sunucuya gönderdiğinde, Request.QueryString ile aldığında, önce gb2312 ile küreselleştirme ile bir kez kod çözer ve bu da karakterlerin karışıklığına yol açar.

1: JS kodlama yöntemi URT-8'dir

2: Sunucu tarafı varsayılan GB2312 olarak yapılandırıldı

3: Request.QueryString, alınan parametreleri sistem yapılandırma kodlamasıyla çözmek için varsayılan olarak HttpUtility.UrlDecode'u çağırır.

1: Sistem varsayılan kodlamayı şu sırayla seçer: http istek başlığı - >küreselleştirme yapılandırma düğümü - varsayılan UTF-8

2: URL doğrudan Çince'ye girildiğinde, farklı tarayıcılar farklı şekilde işleyebilir, örneğin: IE kodlamaz ve doğrudan gönderir, Firefox GB2312 kodlamasından sonra URL'yi gönderir.

3: Kodlanmamış "Çince karakterler" için, Request.QueryString dahili çağrısı HttpUtility.UrlDecode kullanıldıktan sonra, gb2312->utf-8 tarafından,

Çince karakter bulunmazsa, varsayılan olarak "%ufffd"ye dönüştürülür ve geri döndürülemez bozuk karakterler oluşur.

4: Çözüme giden yol
İlkesi bildiğimde, çözmenin birçok yolu vardır:
1: Küresel birleştirme UTF-8 kodlamasıdır, bu da sorun ve endişeyi azaltır.

2: GB2312 küresel olarak tanımlandığında, URL Çincedir ve js kodlanmalıdır, örneğin ext.js çerçeve gibi.

Bu şekilde, sunucu tarafında kodlama ve çözme sistemini belirleyerek özel olarak yönetebilirsiniz.
Varsayılan sistem HttpUtility.UrlDecode("xxx", sistem yapılandırmasının kodlaması) bir kez çağırdığı için,
Bu yüzden HttpUtility.UrlEncode("xxx", sistem tarafından yapılandırılan kodlama) tekrar çağırarak orijinal urt-8 kodlama parametresine geri dönersiniz

Sonra HttpUtility.UrlDecode("xxx", utf-8) kullanarak kod çözebilirsiniz.
Dizi aaa = istek. Request.QueryString["admin"];    Ev Sahibi
                            string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            dizi a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Önceki:Merhaba
Önümüzdeki:Ne algoritma, birkaç gündür depresyondayım.
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com