See artikkel on masintõlke peegelartikkel, palun klõpsake siia, et hüpata algse artikli juurde.

Vaade: 23136|Vastuse: 0

[Allikas] c# Päring võtab vastu segased märgid parameetrite jaoks

[Kopeeri link]
Postitatud 25.12.2015 18:41:49 | | | |


Täna hommikul küsis kolleeg minult küsimuse: ütlesin, et saadud parameetrid olid segased, las ma aitan selle lahendada.


Platvorm, mille eest mu kolleeg vastutab, on ehitatud Ext.js raamistik ning web.config konfiguratsioonifail on konfigureeritud globaalse "GB2312" kodeeringuga:

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

Kui esiosa esitab "hiina teksti", saab taustsüsteem segased märgid Request.QueryString["xxx"].

Ükskõik kuidas sa dekodeerid System.Web.HttpUtility.UrlDecode("xxx", "kodeerimistüüp"), see ei tööta.

Põhimõtte kirjeldus:
1: Esimene asi, mida määrata, on see, et kui kliendi URL-i parameetrid esitatakse, kodeerib Ext.js need enne esitamist ning kliendi kodeeringuks on vaikimisi UTF-8 kodeerimine


2: Miks siis on see segane, kui saab parameetreid Request.QueryString["xxx"]?

Pöörame kompilatsiooni samm-sammult ümber,
2.1: Vaata QueryStringi omaduse koodi:

  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. }
Kopeeri kood

2.2: Lõika FillInQueryStringCollection() meetodi sisse

  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. }
Kopeeri kood

2.3: Lõikamine: 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. }
Kopeeri kood
QueryStringEncoding koodist lähtudes valib süsteem vaikimisi globaliseerimise konfiguratsioonisõlme kodeerimismeetodi, ja kui mitte, siis vaikimisi on UTF-8 kodeerimine
2.4: Lõika FillFromStringi (string s, bool urlencoded, kodeerimine)

  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. }
Kopeeri kood
Sellest punktist leiame, et kõik parameetrisisendid kutsutakse ühe korra: HttpUtility.UrlDecode(str2, kodeerimine);

Kui klient js esitab serverile hiina keele utf-8 kodeeringus, siis Request.QueryStringiga saades dekodeeritakse see esmalt gb2312-ga, mis on globaliseerimise poolt seadistatud, põhjustades segased märgid.

1: JS kodeerimismeetod on URT-8

2: Serveri pool on vaikimisi seadistanud GB2312-ks

3: Request.QueryString kutsub vaikimisi HttpUtility.UrlDecode, et dekodeerida vastuvõetud parameetreid süsteemikonfiguratsiooniga.

1: Süsteem valib vaikimisi kodeeringu järgmises järjekorras: http päringu päis - >globaliseerimise konfiguratsioonisõlm - vaikimisi UTF-8

2: Kui URL sisestatakse otse hiina keelde, võivad erinevad brauserid seda erinevalt käsitleda, näiteks: IE ei kodeeri ja esitab otse, Firefox esitab URL-i pärast GB2312 kodeerimist.

3: Kodeerimata "hiina märkide" puhul, pärast Request.QueryStringi sisemise kutse HttpUtility.UrlDecode kasutamist, autorilt gb2312->utf-8,

Kui hiina märki ei leita, teisendatakse see vaikimisi "%ufffd"-ks, mille tulemusena on pöördumatud segased märgid.

4: Tee lahenduseni
Põhimõtet teades on palju võimalusi selle lahendamiseks:
1: Globaalne ühtlustamine on UTF-8 kodeerimine, mis säästab probleeme ja muret.

2: Kui GB2312 on globaalselt määratletud, on URL hiina keeles ja js tuleb kodeerida, näiteks ext.js raamistik.

Nii saad seda teha ainult spetsiaalselt, määrates kodeerimise ja dekodeerimise serveri poolel.
Kuna vaikimisi süsteem kutsub HttpUtility.UrlDecode'i ("xxx", süsteemi konfiguratsiooni kodeerimine) korra,
Seega kutsud uuesti HttpUtility.UrlEncode'i ("xxx", süsteemi poolt seadistatud kodeeringu), et naasta algse urt-8 kodeerimisparameetri juurde

Seejärel kasuta HttpUtility.UrlDecode("xxx", utf-8) selle dekodeerimiseks.
string aaa = taotlus. Request.QueryString["admin"];    Koduomanik
                            string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Eelmine:Hei
Järgmine:Milline algoritm, olen olnud mitu päeva masenduses.
Disclaimer:
Kõik Code Farmer Networki poolt avaldatud tarkvara, programmeerimismaterjalid või artiklid on mõeldud ainult õppimiseks ja uurimistööks; Ülaltoodud sisu ei tohi kasutada ärilistel ega ebaseaduslikel eesmärkidel, vastasel juhul kannavad kasutajad kõik tagajärjed. Selle saidi info pärineb internetist ning autoriõiguste vaidlused ei ole selle saidiga seotud. Ülaltoodud sisu tuleb oma arvutist täielikult kustutada 24 tunni jooksul pärast allalaadimist. Kui sulle programm meeldib, palun toeta originaaltarkvara, osta registreerimist ja saa paremaid ehtsaid teenuseid. Kui esineb rikkumist, palun võtke meiega ühendust e-posti teel.

Mail To:help@itsvse.com