WebUtility.HtmlDecode 与 HttpUtilty.HtmlDecode
Posted
技术标签:
【中文标题】WebUtility.HtmlDecode 与 HttpUtilty.HtmlDecode【英文标题】:WebUtility.HtmlDecode vs HttpUtilty.HtmlDecode 【发布时间】:2013-06-25 12:50:11 【问题描述】:我使用WebUtilty.htmlDecode
来解码 HTML。事实证明它没有正确解码,例如,–
应该解码为“-”字符,但 WebUtilty.HtmlDecode
没有解码。但是,HttpUtilty.HtmlDecode
可以。
Debug.WriteLine(WebUtility.HtmlDecode("–"));
Debug.WriteLine(HttpUtility.HtmlDecode("–"));
> –
> –
这两者的文档是相同的: 将已经为 HTTP 传输进行 HTML 编码的字符串转换为解码的字符串。
为什么它们不同,我应该使用哪一个,如果我切换到 WebUtility.HtmlDecode 以使“-”正确解码会发生什么变化?
【问题讨论】:
【参考方案1】:这些方法完全相同。此外,如果您尝试对它们进行反编译,它们的实现看起来就像是从另一个复制而来的。
区别仅在于预期用途。 HttpUtility
包含在 System.Web
程序集中,预计将用于基于此程序集构建的 ASP.net 应用程序。 WebUtility
包含在几乎所有应用程序引用的 System
程序集中,并提供给更通用的用途或客户端使用。
【讨论】:
@argaz 我刚刚再次测试了这个并且使用控制台应用程序,你是对的 - 它可以工作,但是在(全新的、全新的)Windows Phone 应用程序中 WebUtilty.HtmlDecode 无法解码–
@JanDobkowski 代码在 .NET 的桌面版本上可能相同(我没有检查过),但在 Windows Phone 8 上显然不同【参考方案2】:
这两种方法在Windows Phone上的实现确实不同。
WebUtility.HtmlDecode:
public static void HtmlDecode(string value, TextWriter output)
if (value != null)
if (output == null)
throw new ArgumentNullException("output");
if (!StringRequiresHtmlDecoding(value))
output.Write(value);
else
int length = value.Length;
for (int i = 0; i < length; i++)
bool flag;
uint num4;
char ch = value[i];
if (ch != '&')
goto Label_01B6;
int num3 = value.IndexOfAny(_htmlEntityEndingChars, i + 1);
if ((num3 <= 0) || (value[num3] != ';'))
goto Label_01B6;
string entity = value.Substring(i + 1, (num3 - i) - 1);
if ((entity.Length <= 1) || (entity[0] != '#'))
goto Label_0188;
if ((entity[1] == 'x') || (entity[1] == 'X'))
flag = uint.TryParse(entity.Substring(2), NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out num4);
else
flag = uint.TryParse(entity.Substring(1), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num4);
if (flag)
switch (_htmlDecodeConformance)
case UnicodeDecodingConformance.Strict:
flag = (num4 < 0xd800) || ((0xdfff < num4) && (num4 <= 0x10ffff));
goto Label_0151;
case UnicodeDecodingConformance.Compat:
flag = (0 < num4) && (num4 <= 0xffff);
goto Label_0151;
case UnicodeDecodingConformance.Loose:
flag = num4 <= 0x10ffff;
goto Label_0151;
flag = false;
Label_0151:
if (!flag)
goto Label_01B6;
if (num4 <= 0xffff)
output.Write((char) num4);
else
char ch2;
char ch3;
ConvertSmpToUtf16(num4, out ch2, out ch3);
output.Write(ch2);
output.Write(ch3);
i = num3;
goto Label_01BD;
Label_0188:
i = num3;
char ch4 = HtmlEntities.Lookup(entity);
if (ch4 != '\0')
ch = ch4;
else
output.Write('&');
output.Write(entity);
output.Write(';');
goto Label_01BD;
Label_01B6:
output.Write(ch);
Label_01BD:;
HttpUtility.HtmlDecode:
public static string HtmlDecode(string html)
if (html == null)
return null;
if (html.IndexOf('&') < 0)
return html;
StringBuilder sb = new StringBuilder();
StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);
int length = html.Length;
for (int i = 0; i < length; i++)
char ch = html[i];
if (ch == '&')
int num3 = html.IndexOfAny(s_entityEndingChars, i + 1);
if ((num3 > 0) && (html[num3] == ';'))
string entity = html.Substring(i + 1, (num3 - i) - 1);
if ((entity.Length > 1) && (entity[0] == '#'))
try
if ((entity[1] == 'x') || (entity[1] == 'X'))
ch = (char) int.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
else
ch = (char) int.Parse(entity.Substring(1), CultureInfo.InvariantCulture);
i = num3;
catch (FormatException)
i++;
catch (ArgumentException)
i++;
else
i = num3;
char ch2 = HtmlEntities.Lookup(entity);
if (ch2 != '\0')
ch = ch2;
else
writer.Write('&');
writer.Write(entity);
writer.Write(';');
continue;
writer.Write(ch);
return sb.ToString();
有趣的是,WP7 上不存在 WebUtility。此外,WebUtility 的 WP8 实现与桌面实现相同。 HttpUtility.HtmlDecode
的桌面实现只是 WebUtility.HtmlDecode
的包装。最后但同样重要的是,Silverlight 5 与 Windows Phone 具有相同的 HttpUtility.HtmlDecode
实现,但没有实现 WebUtility。
从那里,我可以大胆猜测:由于 Windows Phone 7 运行时基于 Silverlight,WP7 继承了 HttpUtility.HtmlDecode
的 Silverlight 版本,并且不存在 WebUtility。然后是 WP8,它的运行时基于 WinRT。 WinRT带来了WebUtility,并保留了旧版HttpUtility.HtmlDecode
,以确保与旧版WP7应用的兼容性。
至于知道你应该使用哪一个...如果你想瞄准 WP7 那么你别无选择,只能使用HttpUtility.HtmlDecode
。如果您的目标是 WP8,那么只需选择其行为最适合您需求的方法。 WebUtility 可能是面向未来的选择,以防万一微软决定在即将推出的 Windows Phone 版本中放弃 Silverlight 运行时。但我只是选择 HttpUtility 的实际选择,而不必担心手动支持您在问题中提出的示例。
【讨论】:
【参考方案3】:只是为了通知将在搜索中找到此内容的其他人。使用问题中提到的任何函数,但不要使用Windows.Data.Html.HtmlUtilities.ConvertToText(string input)
。它比 WebUtilty.HtmlDecode
慢 70 倍并产生崩溃!崩溃将在 DevCenter 中命名为mshtml!IEPeekMessage
。看起来这个函数调用 InternetExplorer 来转换字符串。避免它。
【讨论】:
以上是关于WebUtility.HtmlDecode 与 HttpUtilty.HtmlDecode的主要内容,如果未能解决你的问题,请参考以下文章