Что ж, документация, на которую вы ссылаетесь, относится к IIS 6 Server.UrlEncode, но ваш заголовок спрашивает о .NET System.Web.HttpUtility.UrlEncode .Используя такой инструмент, как Reflector, мы можем увидеть реализацию последнего и определить, соответствует ли он спецификации W3C.
Вот процедура кодирования, которая в конечном счете вызывается (обратите внимание, она определена для массива байтов,и другие перегрузки, которые принимают строки, в конечном итоге преобразуют эти строки в байтовые массивы и вызывают этот метод).Вы должны вызывать это для каждого имени и значения элемента управления (чтобы избежать экранирования зарезервированных символов = &
, используемых в качестве разделителей).
protected internal virtual byte[] UrlEncode(byte[] bytes, int offset, int count)
{
if (!ValidateUrlEncodingParameters(bytes, offset, count))
{
return null;
}
int num = 0;
int num2 = 0;
for (int i = 0; i < count; i++)
{
char ch = (char) bytes[offset + i];
if (ch == ' ')
{
num++;
}
else if (!HttpEncoderUtility.IsUrlSafeChar(ch))
{
num2++;
}
}
if ((num == 0) && (num2 == 0))
{
return bytes;
}
byte[] buffer = new byte[count + (num2 * 2)];
int num4 = 0;
for (int j = 0; j < count; j++)
{
byte num6 = bytes[offset + j];
char ch2 = (char) num6;
if (HttpEncoderUtility.IsUrlSafeChar(ch2))
{
buffer[num4++] = num6;
}
else if (ch2 == ' ')
{
buffer[num4++] = 0x2b;
}
else
{
buffer[num4++] = 0x25;
buffer[num4++] = (byte) HttpEncoderUtility.IntToHex((num6 >> 4) & 15);
buffer[num4++] = (byte) HttpEncoderUtility.IntToHex(num6 & 15);
}
}
return buffer;
}
public static bool IsUrlSafeChar(char ch)
{
if ((((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z'))) || ((ch >= '0') && (ch <= '9')))
{
return true;
}
switch (ch)
{
case '(':
case ')':
case '*':
case '-':
case '.':
case '_':
case '!':
return true;
}
return false;
}
Первая часть подпрограммы подсчитывает количество символов, которые необходимо заменить(пробелы и небезопасные символы).Вторая часть подпрограммы выделяет новый буфер и выполняет замены:
- Url Safe Символы сохраняются как:
a-z A-Z 0-9 ()*-._!
- Пробелы преобразуются в знаки плюс
- Все остальные символы преобразуются в
%HH
RFC1738 состояния (выделено мое):
Таким образом, только буквенно-цифровые символы, специальные символы "$ -_. +! * '(), "и
зарезервированные символы, используемые в зарезервированных целях могут использоваться
без кодировки в URL.
С другой стороны, символы, которые являютсянеобязательно кодировать
(включая буквенно-цифровые символы) может быть закодировано в специфичной для схемы части URL-адреса
, если они не используются для зарезервированной
цели.
Набор безопасных символов URL, разрешенных UrlEncode
, является подмножеством специальных символов, определенных в RFC1738.А именно, символы $,
отсутствуют и будут закодированы как UrlEncode
, даже если спецификация говорит, что они безопасны.Поскольку они могут использоваться в незашифрованном виде (а не must ), они все еще соответствуют спецификации для их кодирования (и во втором абзаце прямо указывается).
В отношениидо разрывов строк, если вход имеет последовательность CR LF
, тогда он будет экранирован %0D%0A
.Однако, если вход имеет только LF
, тогда он будет экранирован %0A
(поэтому в этой процедуре нормализация разрывов строк не выполняется).
Итог: Соответствуетспецификацией при дополнительном кодировании $,
, и вызывающий абонент отвечает за предоставление соответственно нормализованных разрывов строк на входе.