将我的 Windows 窗体应用程序定位到 .NET 3.5 SP1客户端框架会非常好。但是,现在我正在使用HttpUtility.HtmlDecode
andHttpUtility.UrlDecode
函数,而 MSDN 文档并没有指出 System.Net 等内部的任何替代方案。
因此,除了反射源代码并将其复制到我的程序集中(我认为这不值得)之外,您所知道的 .NET 3.5 SP1 客户端框架内部是否有替代方案来替换它功能?他们将这些有用的功能限制为仅限服务器的代码似乎有点奇怪。
将我的 Windows 窗体应用程序定位到 .NET 3.5 SP1客户端框架会非常好。但是,现在我正在使用HttpUtility.HtmlDecode
andHttpUtility.UrlDecode
函数,而 MSDN 文档并没有指出 System.Net 等内部的任何替代方案。
因此,除了反射源代码并将其复制到我的程序集中(我认为这不值得)之外,您所知道的 .NET 3.5 SP1 客户端框架内部是否有替代方案来替换它功能?他们将这些有用的功能限制为仅限服务器的代码似乎有点奇怪。
今天从这个这里的小站点发现可以使用 C# 4.0 客户端配置文件中的 System.Net 库来完成 HtmlEncode/Decode:
Uri.EscapeDataString(...)
WebUtility.HtmlEncode(...)
编辑:我重新阅读了适用于 3.5 客户端框架的问题,但也许这对那些更新了 4.0 的人有用。
我使用 Reflector 从 .NET 4.0 对 Microsoft System.Net.WebUtility 类进行了逆向工程(我认为在这种情况下他们会接受)。因此,您可以使用 .NET 4.0 客户端框架(现在有这个新类)或使用此处的代码。
只要您在程序集等上使用强名称,您就足够安全了。这里:
/// <summary>
/// Taken from System.Net in 4.0, useful until we move to .NET 4.0 - needed for Client Profile
/// </summary>
public static class WebUtility
{
// Fields
private static char[] _htmlEntityEndingChars = new char[] { ';', '&' };
// Methods
public static string HtmlDecode(string value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
if (value.IndexOf('&') < 0)
{
return value;
}
StringWriter output = new StringWriter(CultureInfo.InvariantCulture);
HtmlDecode(value, output);
return output.ToString();
}
public static void HtmlDecode(string value, TextWriter output)
{
if (value != null)
{
if (output == null)
{
throw new ArgumentNullException("output");
}
if (value.IndexOf('&') < 0)
{
output.Write(value);
}
else
{
int length = value.Length;
for (int i = 0; i < length; i++)
{
char ch = value[i];
if (ch == '&')
{
int num3 = value.IndexOfAny(_htmlEntityEndingChars, i + 1);
if ((num3 > 0) && (value[num3] == ';'))
{
string entity = value.Substring(i + 1, (num3 - i) - 1);
if ((entity.Length > 1) && (entity[0] == '#'))
{
ushort num4;
if ((entity[1] == 'x') || (entity[1] == 'X'))
{
ushort.TryParse(entity.Substring(2), NumberStyles.AllowHexSpecifier, (IFormatProvider)NumberFormatInfo.InvariantInfo, out num4);
}
else
{
ushort.TryParse(entity.Substring(1), NumberStyles.Integer, (IFormatProvider)NumberFormatInfo.InvariantInfo, out num4);
}
if (num4 != 0)
{
ch = (char)num4;
i = num3;
}
}
else
{
i = num3;
char ch2 = HtmlEntities.Lookup(entity);
if (ch2 != '\0')
{
ch = ch2;
}
else
{
output.Write('&');
output.Write(entity);
output.Write(';');
goto Label_0117;
}
}
}
}
output.Write(ch);
Label_0117: ;
}
}
}
}
public static string HtmlEncode(string value)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
if (IndexOfHtmlEncodingChars(value, 0) == -1)
{
return value;
}
StringWriter output = new StringWriter(CultureInfo.InvariantCulture);
HtmlEncode(value, output);
return output.ToString();
}
public static unsafe void HtmlEncode(string value, TextWriter output)
{
if (value != null)
{
if (output == null)
{
throw new ArgumentNullException("output");
}
int num = IndexOfHtmlEncodingChars(value, 0);
if (num == -1)
{
output.Write(value);
}
else
{
int num2 = value.Length - num;
fixed (char* str = value)
{
char* chPtr = str;
char* chPtr2 = chPtr;
while (num-- > 0)
{
chPtr2++;
output.Write(chPtr2[0]);
}
while (num2-- > 0)
{
chPtr2++;
char ch = chPtr2[0];
if (ch <= '>')
{
switch (ch)
{
case '&':
{
output.Write("&");
continue;
}
case '\'':
{
output.Write("'");
continue;
}
case '"':
{
output.Write(""");
continue;
}
case '<':
{
output.Write("<");
continue;
}
case '>':
{
output.Write(">");
continue;
}
}
output.Write(ch);
continue;
}
if ((ch >= '\x00a0') && (ch < 'Ā'))
{
output.Write("&#");
output.Write(((int)ch).ToString(NumberFormatInfo.InvariantInfo));
output.Write(';');
}
else
{
output.Write(ch);
}
}
}
}
}
}
private static unsafe int IndexOfHtmlEncodingChars(string s, int startPos)
{
int num = s.Length - startPos;
fixed (char* str = s)
{
char* chPtr = str;
char* chPtr2 = chPtr + startPos;
while (num > 0)
{
char ch = chPtr2[0];
if (ch <= '>')
{
switch (ch)
{
case '&':
case '\'':
case '"':
case '<':
case '>':
return (s.Length - num);
case '=':
goto Label_0086;
}
}
else if ((ch >= '\x00a0') && (ch < 'Ā'))
{
return (s.Length - num);
}
Label_0086:
chPtr2++;
num--;
}
}
return -1;
}
// Nested Types
private static class HtmlEntities
{
// Fields
private static string[] _entitiesList = new string[] {
"\"-quot", "&-amp", "'-apos", "<-lt", ">-gt", "\x00a0-nbsp", "\x00a1-iexcl", "\x00a2-cent", "\x00a3-pound", "\x00a4-curren", "\x00a5-yen", "\x00a6-brvbar", "\x00a7-sect", "\x00a8-uml", "\x00a9-copy", "\x00aa-ordf",
"\x00ab-laquo", "\x00ac-not", "\x00ad-shy", "\x00ae-reg", "\x00af-macr", "\x00b0-deg", "\x00b1-plusmn", "\x00b2-sup2", "\x00b3-sup3", "\x00b4-acute", "\x00b5-micro", "\x00b6-para", "\x00b7-middot", "\x00b8-cedil", "\x00b9-sup1", "\x00ba-ordm",
"\x00bb-raquo", "\x00bc-frac14", "\x00bd-frac12", "\x00be-frac34", "\x00bf-iquest", "\x00c0-Agrave", "\x00c1-Aacute", "\x00c2-Acirc", "\x00c3-Atilde", "\x00c4-Auml", "\x00c5-Aring", "\x00c6-AElig", "\x00c7-Ccedil", "\x00c8-Egrave", "\x00c9-Eacute", "\x00ca-Ecirc",
"\x00cb-Euml", "\x00cc-Igrave", "\x00cd-Iacute", "\x00ce-Icirc", "\x00cf-Iuml", "\x00d0-ETH", "\x00d1-Ntilde", "\x00d2-Ograve", "\x00d3-Oacute", "\x00d4-Ocirc", "\x00d5-Otilde", "\x00d6-Ouml", "\x00d7-times", "\x00d8-Oslash", "\x00d9-Ugrave", "\x00da-Uacute",
"\x00db-Ucirc", "\x00dc-Uuml", "\x00dd-Yacute", "\x00de-THORN", "\x00df-szlig", "\x00e0-agrave", "\x00e1-aacute", "\x00e2-acirc", "\x00e3-atilde", "\x00e4-auml", "\x00e5-aring", "\x00e6-aelig", "\x00e7-ccedil", "\x00e8-egrave", "\x00e9-eacute", "\x00ea-ecirc",
"\x00eb-euml", "\x00ec-igrave", "\x00ed-iacute", "\x00ee-icirc", "\x00ef-iuml", "\x00f0-eth", "\x00f1-ntilde", "\x00f2-ograve", "\x00f3-oacute", "\x00f4-ocirc", "\x00f5-otilde", "\x00f6-ouml", "\x00f7-divide", "\x00f8-oslash", "\x00f9-ugrave", "\x00fa-uacute",
"\x00fb-ucirc", "\x00fc-uuml", "\x00fd-yacute", "\x00fe-thorn", "\x00ff-yuml", "Œ-OElig", "œ-oelig", "Š-Scaron", "š-scaron", "Ÿ-Yuml", "ƒ-fnof", "ˆ-circ", "˜-tilde", "Α-Alpha", "Β-Beta", "Γ-Gamma",
"Δ-Delta", "Ε-Epsilon", "Ζ-Zeta", "Η-Eta", "Θ-Theta", "Ι-Iota", "Κ-Kappa", "Λ-Lambda", "Μ-Mu", "Ν-Nu", "Ξ-Xi", "Ο-Omicron", "Π-Pi", "Ρ-Rho", "Σ-Sigma", "Τ-Tau",
"Υ-Upsilon", "Φ-Phi", "Χ-Chi", "Ψ-Psi", "Ω-Omega", "α-alpha", "β-beta", "γ-gamma", "δ-delta", "ε-epsilon", "ζ-zeta", "η-eta", "θ-theta", "ι-iota", "κ-kappa", "λ-lambda",
"μ-mu", "ν-nu", "ξ-xi", "ο-omicron", "π-pi", "ρ-rho", "ς-sigmaf", "σ-sigma", "τ-tau", "υ-upsilon", "φ-phi", "χ-chi", "ψ-psi", "ω-omega", "ϑ-thetasym", "ϒ-upsih",
"ϖ-piv", " -ensp", " -emsp", " -thinsp", "-zwnj", "-zwj", "-lrm", "-rlm", "–-ndash", "—-mdash", "‘-lsquo", "’-rsquo", "‚-sbquo", "“-ldquo", "”-rdquo", "„-bdquo",
"†-dagger", "‡-Dagger", "•-bull", "…-hellip", "‰-permil", "′-prime", "″-Prime", "‹-lsaquo", "›-rsaquo", "‾-oline", "⁄-frasl", "€-euro", "ℑ-image", "℘-weierp", "ℜ-real", "™-trade",
"ℵ-alefsym", "←-larr", "↑-uarr", "→-rarr", "↓-darr", "↔-harr", "↵-crarr", "⇐-lArr", "⇑-uArr", "⇒-rArr", "⇓-dArr", "⇔-hArr", "∀-forall", "∂-part", "∃-exist", "∅-empty",
"∇-nabla", "∈-isin", "∉-notin", "∋-ni", "∏-prod", "∑-sum", "−-minus", "∗-lowast", "√-radic", "∝-prop", "∞-infin", "∠-ang", "∧-and", "∨-or", "∩-cap", "∪-cup",
"∫-int", "∴-there4", "∼-sim", "≅-cong", "≈-asymp", "≠-ne", "≡-equiv", "≤-le", "≥-ge", "⊂-sub", "⊃-sup", "⊄-nsub", "⊆-sube", "⊇-supe", "⊕-oplus", "⊗-otimes",
"⊥-perp", "⋅-sdot", "⌈-lceil", "⌉-rceil", "⌊-lfloor", "⌋-rfloor", "〈-lang", "〉-rang", "◊-loz", "♠-spades", "♣-clubs", "♥-hearts", "♦-diams"
};
private static Dictionary<string, char> _lookupTable = GenerateLookupTable();
// Methods
private static Dictionary<string, char> GenerateLookupTable()
{
Dictionary<string, char> dictionary = new Dictionary<string, char>(StringComparer.Ordinal);
foreach (string str in _entitiesList)
{
dictionary.Add(str.Substring(2), str[0]);
}
return dictionary;
}
public static char Lookup(string entity)
{
char ch;
_lookupTable.TryGetValue(entity, out ch);
return ch;
}
}
}
我强烈不建议滚动您自己的编码。如果 HttpUtility.HtmlEncode 不可用,我会使用非常小的Microsoft 反跨站点脚本库(v1.5 约为 30kb)。
至于解码,也许你可以使用Mono的解码例程?
显然谷歌也找不到它,所以他们在那里写了自己的 api 兼容版本:
这是一个解决方法:
将 Google 的版本编译为库
wget 'http://google-gdata.googlecode.com/svn/trunk/clients/cs/src/core/HttpUtility.cs'
gmcs -t:library HttpUtility.cs
编辑your-project.cs
以包含该命名空间
using Google.GData.Client; // where HttpUtility lives
使用库重新编译
gmcs your-project.cs -r:System.Web.Services -r:System.Web -r:HttpUtility
从源代码看,这似乎是.NET 2.0
兼容的。
我昨天刚刚在 csharp 中写了我的第一个 hello world,我遇到了这个问题,所以我希望这对其他人有帮助。
在解决Windows Phone 和桌面(客户端配置文件!)世界时,我发现最快的方法是:
private static string HtmlDecode(string text)
{
#if WINDOWS_PHONE
return System.Net.HttpUtility.HtmlDecode(text);
#else
return System.Net.WebUtility.HtmlDecode(text);
#endif
}
对我来说奇怪的是命名空间是System.Net但类名在Windows Phone世界中不同......(不喜欢在不需要时使用 System.Web/full 配置文件并且 System.Web 不是' t 无论如何都支持 Windows Phone 平台...)
.NET 3.5 SP1 客户端配置文件安装包是 .NET的“精简”版本,仅包含 Microsoft 认为对客户端应用程序“有用”的 .NET 部分。HttpUtility
因此,缺少诸如类之类的有用的东西。
有关这方面的更多信息,请参阅ScottGu 的博客,搜索“Client Profile Setup Package”。
为了解决这个问题,您总是可以System.Web.dll
从 GAC 中提取(它将在 中c:\windows\Microsoft.NET\Framework\ ...
)并将其与您的应用程序一起部署。但是,您需要在部署时跟踪更新和服务包。
更好的办法是利用完整的 .NET Framework 部署。
两种主要方式: