This article is a mirror article of machine translation, please click here to jump to the original article.

View: 23136|Reply: 0

[Source] c# Request receives garbled characters for parameters

[Copy link]
Posted on 12/25/2015 6:41:49 PM | | | |


This morning I was asked a question by a colleague: I said that the parameters received were garbled, let me help solve it.


The platform my colleague is responsible for is built Ext.js framework, and the web.config configuration file is configured with the global "GB2312" encoding:

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

When the frontend submits the "Chinese text", the backend receives garbled characters with Request.QueryString["xxx"].

No matter how you decode with System.Web.HttpUtility.UrlDecode("xxx", "encoding type"), it doesn't work.

Principle description:
1: The first thing to determine is that when the client's URL parameters are submitted, Ext.js will encode them before submitting them, and the client's encoding is UTF-8 encoding by default


2: Then why is it garbled when receiving parameters with Request.QueryString["xxx"]?

We reverse the compilation step by step,
2.1: Look at the code for the QueryString property:

  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. }
Copy code

2.2: Cut into the FillInQueryStringCollection() method

  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. }
Copy code

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. }
Copy code
From the QueryStringEncoding code, the system defaults to the encoding method of the globalization configuration node, and if not, the default is UTF-8 encoding
2.4: Cut into FillFromString(string s, bool urlencoded, Encoding encoding)

  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. }
Copy code
From this point we find that all parameter inputs are called once: HttpUtility.UrlDecode(str2, encoding);

When client js submits Chinese to the server in utf-8 encoding, when receiving it with Request.QueryString, it will first decode it once with gb2312 configured by globalization, resulting in garbled characters.

1: The JS encoding method is URT-8

2: The server side has configured the default to GB2312

3: Request.QueryString will call HttpUtility.UrlDecode by default to decode the received parameters with system configuration encoding.

1: The system selects the default encoding in the following order: http request header - >globalization configuration node - default UTF-8

2: When entering the URL directly into Chinese, different browsers may handle it differently, for example: IE does not encode and submits directly, Firefox submits the URL after GB2312 encoding.

3: For unencoded "Chinese characters", after using Request.QueryString internal call HttpUtility.UrlDecode, by gb2312->utf-8,

If the Chinese character is not found, it will be converted to "%ufffd" by default, resulting in irreversible garbled characters.

4: The road to resolution
Knowing the principle, there are many ways to solve it:
1: The global unification is UTF-8 encoding, which saves trouble and worry.

2: When GB2312 is globally specified, the url is Chinese, and js must be encoded, such as ext.js framework.

In this way, you can only handle it specially, specifying the encoding and decoding on the server side.
Because the default system calls HttpUtility.UrlDecode("xxx", the encoding of the system configuration) once,
So you call HttpUtility.UrlEncode("xxx", the encoding configured by the system) again to return to the original urt-8 encoding parameter

Then use HttpUtility.UrlDecode("xxx", utf-8) to decode it.
string aaa = request. Request.QueryString["admin"];    Homeowner
                            string a1 = HttpUtility.UrlEncode(aaa, System.Text.Encoding.GetEncoding("GB2312"));
                            string a2 = HttpUtility.UrlDecode(a1,System.Text.Encoding.UTF8);








Previous:hi
Next:What an algorithm, I have been depressed for several days.
Disclaimer:
All software, programming materials or articles published by Code Farmer Network are only for learning and research purposes; The above content shall not be used for commercial or illegal purposes, otherwise, users shall bear all consequences. The information on this site comes from the Internet, and copyright disputes have nothing to do with this site. You must completely delete the above content from your computer within 24 hours of downloading. If you like the program, please support genuine software, purchase registration, and get better genuine services. If there is any infringement, please contact us by email.

Mail To:help@itsvse.com