HttpUtility.HtmlEncode не кодирует все
Я взаимодействую с веб-сервером с помощью клиентской клиентской программы на С# и .Net 3.5. Я использую Fiddler, чтобы посмотреть, какой трафик веб-браузер отправляет, и подражать этому. К сожалению, этот сервер устарел и немного запутался в понятиях кодировок и utf-8. В основном он использует Latin-1.
Когда я ввожу данные в веб-браузер, содержащий "специальные" символы, например "Ω π ℵ ∞ ♣ ♥
♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ "скрипач показать мне, что они передаются следующим образом из браузера на сервер: "♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ "
Но для моего клиента HttpUtility.HtmlEncode не преобразует эти символы, он оставляет их как есть. Что мне нужно, чтобы позвонить, чтобы преобразовать "♈" в & # 9800; и так далее?
Ответы
Ответ 1
Кажется ужасно неэффективным, но единственный способ, которым я могу это сделать, - просмотреть каждый символ:
public static string MyHtmlEncode(string value)
{
// call the normal HtmlEncode first
char[] chars = HttpUtility.HtmlEncode(value).ToCharArray();
StringBuilder encodedValue = new StringBuilder();
foreach(char c in chars)
{
if ((int)c > 127) // above normal ASCII
encodedValue.Append("&#" + (int)c + ";");
else
encodedValue.Append(c);
}
return encodedValue.ToString();
}
Ответ 2
Тип возвращаемого значения HtmlEncode - это строка, которая имеет Unicode и, следовательно, не нуждается в кодировании этих символов.
Если кодировка вашего выходного потока несовместима с этими символами, используйте HtmlEncode следующим образом: -
HttpUtility.HtmlEncode(outgoingString, Response.Output);
HtmlEncode с последующим выводом символов соответствующим образом.
Ответ 3
Rich Strahl только что разместил сообщение в блоге, Html и Uri String Encoding без System.Web, где у него есть собственный код, который кодирует верхний диапазон символов тоже.
/// <summary>
/// HTML-encodes a string and returns the encoded string.
/// </summary>
/// <param name="text">The text string to encode. </param>
/// <returns>The HTML-encoded text.</returns>
public static string HtmlEncode(string text)
{
if (text == null)
return null;
StringBuilder sb = new StringBuilder(text.Length);
int len = text.Length;
for (int i = 0; i < len; i++)
{
switch (text[i])
{
case '<':
sb.Append("<");
break;
case '>':
sb.Append(">");
break;
case '"':
sb.Append(""");
break;
case '&':
sb.Append("&");
break;
default:
if (text[i] > 159)
{
// decimal numeric entity
sb.Append("&#");
sb.Append(((int)text[i]).ToString(CultureInfo.InvariantCulture));
sb.Append(";");
}
else
sb.Append(text[i]);
break;
}
}
return sb.ToString();
}
Ответ 4
Библиотека AntiXSS от Microsoft правильно кодирует эти символы.
AntiXSS на Codeplex
пакет Nuget (лучший способ добавить в качестве ссылки)
Ответ 5
Кажется, что HtmlEncode предназначен только для кодирования строк, которые помещаются в HTML-документы, где только /< > и т.д. вызывают проблемы. Для URL-адресов просто замените HtmlEncode на UrlEncode.
Ответ 6
Ответ на @bdukes выше выполнит эту работу, но мы можем сделать это намного быстрее, если предположить, что большинство символов не будут в этом диапазоне. Обратите внимание на цитируемый 'À' (unicode 0x0100)
/// <summary>.Net 2.0 HttpUtility.HtmlEncode will not properly encode
/// Unicode characters above 0xFF. This may be fixed in newer
/// versions.</summary>
public static string HtmlEncode(string s)
{
// Let .Net 2.0 get right what it gets right.
s = HttpUtility.HtmlEncode(s);
// Search for first non-ASCII. Hopefully none and we can just
// return s.
int num = IndexOfHighChar(s, 0);
if (num == -1)
return s;
int old_num = 0;
StringBuilder sb = new StringBuilder();
do {
sb.Append(s, old_num, num - old_num);
sb.Append("&#");
sb.Append(((int)s[num]).ToString(NumberFormatInfo.InvariantInfo));
sb.Append(';');
old_num = num + 1;
num = IndexOfHighChar(s, old_num);
} while (num != -1);
sb.Append(s, old_num, s.Length - old_num);
return sb.ToString();
}
static unsafe int IndexOfHighChar(string s, int start)
{
int num = s.Length - start;
fixed (char* str = s) {
char* chPtr = str + start;
while (num > 0) {
char ch = chPtr[0];
if (ch >= 'Ā')
return s.Length - num;
chPtr++;
num--;
}
}
return -1;
}
Ответ 7
Вы всегда можете заменить нежелательный ASCII следующим образом: когда это закодировано без оператора if, строка результата: "Это означает, что я плачу: '&' # 39;) По какой-либо причине обрабатываются" специальные символы "и заменен на HTML char.
string text = "This means I am crying :'(";
string encoded = HttpUtility.HtmlEncode(text);
if(encoded.Contains("'"))
{
encoded = encoded.Replace("'", "'");
}