HttpUtility.HtmlEncode ne code pas tout

J’interagis avec un serveur Web à l’aide d’un programme client de bureau en C # et .Net 3.5. J’utilise Fiddler pour voir quel trafic le navigateur Web envoie et l’émuler. Malheureusement, ce serveur est ancien et un peu confus quant aux notions de jeux de caractères et de utf-8. Généralement, il utilise le latin-1.

Lorsque je saisis dans le navigateur Web des données contenant des caractères “spéciaux”, comme par exemple, le fiddler “me montre qu’ils sont transmis comme suit du navigateur au serveur: "♈ ♉ ♊ ♋ ♌ ♍ ♎ ♏ ♐ ♑ ♒ ♓ "

Mais pour mon client, HttpUtility.HtmlEncode ne convertit pas ces caractères, il les laisse tels quels. De quoi ai-je besoin pour appeler “♈” en & # 9800; etc?

Cela semble horriblement inefficace, mais la seule façon de le faire est de regarder à travers chaque personnage:

 public static ssortingng MyHtmlEncode(ssortingng value) { // call the normal HtmlEncode first char[] chars = HttpUtility.HtmlEncode(value).ToCharArray(); SsortingngBuilder encodedValue = new SsortingngBuilder(); foreach(char c in chars) { if ((int)c > 127) // above normal ASCII encodedValue.Append("&#" + (int)c + ";"); else encodedValue.Append(c); } return encodedValue.ToSsortingng(); } 

Le type de valeur de retour de HtmlEncode est une chaîne qui est de type Unicode et n’a donc pas besoin de coder ces caractères.

Si l’encodage de votre stream de sortie n’est pas compatible avec ces caractères, utilisez HtmlEncode comme ceci: –

  HttpUtility.HtmlEncode(outgoingSsortingng, Response.Output); 

HtmlEncode avec puis échappe les caractères de manière appropriée.

Rich Strahl vient de publier un article de blog, Html et Uri Ssortingng Encoding sans System.Web , dans lequel il a également un code personnalisé qui code la plage de caractères supérieure.

 ///  /// HTML-encodes a ssortingng and returns the encoded ssortingng. ///  /// The text ssortingng to encode.  /// The HTML-encoded text. public static ssortingng HtmlEncode(ssortingng text) { if (text == null) return null; SsortingngBuilder sb = new SsortingngBuilder(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]).ToSsortingng(CultureInfo.InvariantCulture)); sb.Append(";"); } else sb.Append(text[i]); break; } } return sb.ToSsortingng(); } 

La bibliothèque AntiXSS de Microsoft code correctement ces caractères.

AntiXSS sur Codeplex

Nuget package (meilleur moyen d’append comme référence)

Il semble que HtmlEncode soit juste pour encoder des chaînes qui sont placées dans des documents HTML, où seulement / <> et etc. peuvent causer des problèmes. Pour les URL, remplacez simplement HtmlEncode par UrlEncode.

La réponse de @bdukes ci-dessus fera l’affaire, mais nous pouvons le faire beaucoup plus rapidement si nous supposons que la plupart des caractères ne seront pas dans cette plage. Notez le ‘Â’ (Unicode 0x0100)

 /// .Net 2.0's HttpUtility.HtmlEncode will not properly encode /// Unicode characters above 0xFF. This may be fixed in newer /// versions. public static ssortingng HtmlEncode(ssortingng 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; SsortingngBuilder sb = new SsortingngBuilder(); do { sb.Append(s, old_num, num - old_num); sb.Append("&#"); sb.Append(((int)s[num]).ToSsortingng(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.ToSsortingng(); } static unsafe int IndexOfHighChar(ssortingng 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; } 

Vous pouvez toujours remplacer les ASCII indésirables comme suit: Lorsque celui-ci est codé sans l’instruction if, la chaîne de résultat est “Cela signifie que je pleure: ‘&” # 39;) Pour une raison quelconque, les “caractères spéciaux” sont gérés et remplacés par du caractère HTML. .

 ssortingng text = "This means I am crying :'("; ssortingng encoded = HttpUtility.HtmlEncode(text); if(encoded.Contains("'")) { encoded = encoded.Replace("'", "'"); }