Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 23136|Svare: 0

[Kilde] c# Forespørsel mottar forvrengte tegn for parametere

[Kopier lenke]
Publisert på 25.12.2015 18:41:49 | | | |


I morges ble jeg stilt et spørsmål av en kollega: Jeg sa at parameterne som ble mottatt var uforståelige, la meg hjelpe til med å løse det.


Plattformen kollegaen min har ansvar for er bygget Ext.js rammeverk, og web.config-konfigurasjonsfilen er konfigurert med den globale "GB2312"-kodingen:

<globaliseringsforespørselKoding="gb2312" svarKoding="gb2312" filKoding="gb2312" culture="zh-CN"/>

Når frontenden sender inn «kinesisk tekst», mottar backenden forvrengte tegn med Request.QueryString["xxx"].

Uansett hvordan du dekodes med System.Web.HttpUtility.UrlDecode("xxx", "encoding type"), fungerer det ikke.

Hovedbeskrivelse:
1: Det første som må avgjøres er at når klientens URL-parametere sendes inn, vil Ext.js kode dem før de sendes inn, og klientens koding er som standard UTF-8-koding


2: Hvorfor er det da utydelig når man mottar parametere med Request.QueryString["xxx"]?

Vi reverserer kompileringen steg for steg,
2.1: Se på koden for QueryString-egenskapen:

  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. }
Kopier koden

2.2: Kutt inn i FillInQueryStringCollection()-metoden

  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. }
Kopier koden

2.3: Kutt: 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. }
Kopier koden
Fra QueryStringEncoding-koden går systemet som standard over til kodingsmetoden til globaliseringskonfigurasjonsnoden, og hvis ikke, er standarden UTF-8-koding
2.4: Kutt i FillFromString (streng s, bool urlencoded, koding av koding)

  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. }
Kopier koden
Fra dette punktet finner vi at alle parameterinnganger kalles én gang: HttpUtility.UrlDecode(str2, koding);

Når klient js sender kinesisk til serveren i utf-8-koding, vil den først dekode det én gang med gb2312 konfigurert ved globalisering, noe som resulterer i utydelige tegn.

1: JS-kodingsmetoden er URT-8

2: Serversiden har konfigurert standardinnstillingen til GB2312

3: Request.QueryString vil som standard kalle HttpUtility.UrlDecode for å dekode mottatte parametere med systemkonfigurasjonskoding.

1: Systemet velger standardkodingen i følgende rekkefølge: http forespørselshode - >globaliseringskonfigurasjonsnode - standard UTF-8

2: Når URL-en legges direkte inn på kinesisk, kan ulike nettlesere håndtere det forskjellig, for eksempel: IE koder ikke og sender inn direkte, Firefox sender inn URL-en etter GB2312-kodingen.

3: For ukodede "kinesiske tegn", etter bruk av Request.QueryString internt kall HttpUtility.UrlDecode, av gb2312->utf-8,

Hvis det kinesiske tegnet ikke blir funnet, vil det som standard bli konvertert til "%ufffd", noe som resulterer i irreversible utydelige tegn.

4: Veien til løsning
Når man kjenner prinsippet, finnes det mange måter å løse det på:
1: Den globale samlingen er UTF-8-koding, som sparer for problemer og bekymringer.

2: Når GB2312 er globalt spesifisert, er url-en kinesisk, og js må kodes, slik som ext.js rammeverk.

På denne måten kan du bare håndtere det spesielt, ved å spesifisere koding og dekoding på serversiden.
Fordi standardsystemet kaller HttpUtility.UrlDecode("xxx", kodingen av systemkonfigurasjonen) én gang,
Så du kaller HttpUtility.UrlEncode("xxx", kodingen konfigurert av systemet) igjen for å returnere til den opprinnelige urt-8-kodingsparameteren

Bruk deretter HttpUtility.UrlDecode("xxx", utf-8) for å dekode den.
streng aaa = forespørsel. Request.QueryString["admin"];    Huseier
                            streng a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Foregående:Hei
Neste:For en algoritme, jeg har vært deprimert i flere dager.
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com