Cet article est un article miroir de traduction automatique, veuillez cliquer ici pour accéder à l’article original.

Vue: 23136|Répondre: 0

[Source] La requête c# reçoit des caractères brouillés pour les paramètres

[Copié le lien]
Publié sur 25/12/2015 18:41:49 | | | |


Ce matin, un collègue m’a posé une question : j’ai dit que les paramètres reçus étaient brouillés, laissez-moi aider à les résoudre.


La plateforme dont mon collègue est responsable est construite Ext.js framework, et le fichier de configuration web.config est configuré avec l’encodage global « GB2312 » :

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

Lorsque le frontend envoie le « texte chinois », le backend reçoit des caractères brouillés avec Request.QueryString["xxx"].

Peu importe comment vous décodez avec System.Web.HttpUtility.UrlDecode(« xxx », « encoding type »), cela ne fonctionne pas.

Description du principe :
1 : La première chose à déterminer est que lorsque les paramètres URL du client sont soumis, Ext.js les encodera avant de les soumettre, et que l’encodage du client est par défaut un codage UTF-8


2 : Alors pourquoi est-ce brouillé lors de la réception des paramètres avec Request.QueryString["xxx"] ?

Nous inversons la compilation étape par étape,
2.1 : Regardez le code de la propriété 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. }
Code de copie

2.2 : Découper dans la méthode 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. }
Code de copie

2.3 : Cut : 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. }
Code de copie
D’après le code QueryStringEncoding, le système utilise par défaut la méthode d’encodage du nœud de configuration de globalisation, et sinon, le code par défaut est l’encodage UTF-8
2.4 : Coupe dans FillFromString(chaîne s, urlencodée bool, encodage par encodage)

  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. }
Code de copie
À partir de ce point, on constate que toutes les entrées de paramètres sont appelées une seule fois : HttpUtility.UrlDecode(str2, encoding) ;

Lorsque le client js soumet du chinois au serveur en codage utf-8, lorsqu’il le reçoit avec Request.QueryString, il le décode d’abord une fois avec gb2312 configuré par la mondialisation, ce qui donne des caractères brouillés.

1 : La méthode d’encodage JS est URT-8

2 : Le côté serveur a configuré le code par défaut sur GB2312

3 : Request.QueryString appellera par défaut HttpUtility.UrlDecode pour décoder les paramètres reçus avec l’encodage de configuration système.

1 : Le système sélectionne l’encodage par défaut dans l’ordre suivant : en-tête requête http - nœud de configuration >globalisation - UTF-8 par défaut

2 : Lors de la saisie directe de l’URL en chinois, différents navigateurs peuvent la gérer différemment, par exemple : IE n’encode pas et soumet directement, Firefox envoie l’URL après l’encodage GB2312.

3 : Pour les « caractères chinois » non encodés, après avoir utilisé Request.QueryString, appel interne HttpUtility.UrlDecode, par gb2312->utf-8,

Si le caractère chinois n’est pas trouvé, il sera converti par défaut en « %ufffd », ce qui entraînera des caractères irréversiblement brouillés.

4 : La route vers la résolution
Connaissant le principe, il existe de nombreuses façons de le résoudre :
1 : L’unification mondiale est l’encodage UTF-8, qui évite des soucis et des soucis.

2 : Lorsque GB2312 est spécifié globalement, l’URL est chinoise, et js doit être encodé, comme ext.js framework.

De cette façon, vous ne pouvez le gérer que de manière spéciale, en spécifiant l’encodage et le décodage côté serveur.
Parce que le système par défaut appelle HttpUtility.UrlDecode(« xxx », l’encodage de la configuration système) une fois,
Vous appelez donc HttpUtility.UrlEncode (« xxx », l’encodage configuré par le système) pour revenir au paramètre d’encodage urt-8 d’origine

Ensuite, utilisez HttpUtility.UrlDecode (« xxx », utf-8) pour le décoder.
chaîne AAA = requête. Request.QueryString["admin"] ;    Propriétaire
                            chaîne a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding(« GB2312 »)) ;
                            chaîne a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8) ;








Précédent:Salut
Prochain:Quel algorithme, je suis déprimé depuis plusieurs jours.
Démenti:
Tous les logiciels, supports de programmation ou articles publiés par Code Farmer Network sont uniquement destinés à l’apprentissage et à la recherche ; Le contenu ci-dessus ne doit pas être utilisé à des fins commerciales ou illégales, sinon les utilisateurs assumeront toutes les conséquences. Les informations sur ce site proviennent d’Internet, et les litiges de droits d’auteur n’ont rien à voir avec ce site. Vous devez supprimer complètement le contenu ci-dessus de votre ordinateur dans les 24 heures suivant le téléchargement. Si vous aimez le programme, merci de soutenir un logiciel authentique, d’acheter l’immatriculation et d’obtenir de meilleurs services authentiques. En cas d’infraction, veuillez nous contacter par e-mail.

Mail To:help@itsvse.com