Я провел небольшое исследование за прошедший день или около того, и я думаю, что у меня есть некоторая информация об этом.
Когда вы используете Request.Querystring или HttpUtility.UrlDecode (или Encode), он использует кодировку, указанную в элементе (в частности, атрибуте requestEncoding) файла web.config (или иерархии .config, если вы этого не сделали). указано) --- НЕ Encoding.Default, который является кодировкой по умолчанию для вашего сервера.
Если для кодировки установлено значение UTF-8, один символ Unicode может быть закодирован как шестнадцатеричные значения 2% xx. Он также будет декодирован таким образом, когда передано все значение.
Если вы UrlDecoding с другой кодировкой, с которой не был закодирован URL-адрес, вы получите другой результат.
Поскольку HttpUtility.UrlEncode и UrlDecode могут принимать параметр кодирования, заманчиво попытаться кодировать с использованием кодовой страницы ANSI, но UTF-8 - правильный путь, если у вас есть поддержка браузера (очевидно, старые версии не поддерживают UTF-8). Вам просто нужно убедиться, что он правильно установлен, и обе стороны будут работать нормально.
UTF-8 Кажется кодировкой по умолчанию: (из .net отражатель System.Web.HttpRequest)
internal Encoding QueryStringEncoding
{
get
{
Encoding contentEncoding = this.ContentEncoding;
if (!contentEncoding.Equals(Encoding.Unicode))
{
return contentEncoding;
}
return Encoding.UTF8;
}
}
Следуя пути, чтобы узнать this.ContentEncoding ведет вас (также в HttpRequest)
public Encoding ContentEncoding
{
get
{
if (!this._flags[0x20] || (this._encoding == null))
{
this._encoding = this.GetEncodingFromHeaders();
if (this._encoding == null)
{
GlobalizationSection globalization = RuntimeConfig.GetLKGConfig(this._context).Globalization;
this._encoding = globalization.RequestEncoding;
}
this._flags.Set(0x20);
}
return this._encoding;
}
set
{
this._encoding = value;
this._flags.Set(0x20);
}
}
Чтобы ответить на ваш конкретный вопрос о разнице между Request.Url.Quer и Request.QueryString ... вот как HttpRequest создает свое свойство Url:
public Uri Url
{
get
{
if ((this._url == null) && (this._wr != null))
{
string queryStringText = this.QueryStringText;
if (!string.IsNullOrEmpty(queryStringText))
{
queryStringText = "?" + HttpEncoder.CollapsePercentUFromStringInternal(queryStringText, this.QueryStringEncoding);
}
if (AppSettings.UseHostHeaderForRequestUrl)
{
string knownRequestHeader = this._wr.GetKnownRequestHeader(0x1c);
try
{
if (!string.IsNullOrEmpty(knownRequestHeader))
{
this._url = new Uri(this._wr.GetProtocol() + "://" + knownRequestHeader + this.Path + queryStringText);
}
}
catch (UriFormatException)
{
}
}
if (this._url == null)
{
string serverName = this._wr.GetServerName();
if ((serverName.IndexOf(':') >= 0) && (serverName[0] != '['))
{
serverName = "[" + serverName + "]";
}
this._url = new Uri(this._wr.GetProtocol() + "://" + serverName + ":" + this._wr.GetLocalPortAsString() + this.Path + queryStringText);
}
}
return this._url;
}
}
Вы можете видеть, что он использует класс HttpEncoder для декодирования, но использует то же значение QueryStringEncoding.
Поскольку я уже выкладываю здесь много кода, и любой может получить .NET Reflector, я собираюсь описать остальные. Свойство QueryString происходит из коллекции HttpValueCollection, которая использует метод FillFromEncodedBytes для окончательного вызова HttpUtility.UrlDecode (со значением QueryStringEncoding, установленным выше), который в конечном итоге вызывает HttpEncoder для его декодирования.
Похоже, они используют другую методологию для декодирования действительных байтов строки запроса, но кодировка, которую они используют для этого, кажется, одинакова.
Мне интересно, что HttpEncoder имеет так много функций, которые, кажется, делают одно и то же, поэтому возможно, что в этих методах есть различия, которые могут вызвать проблему.