.NET 3.5 SP1客户端框架的HttpUtility的替代产品?
将Windows Forms应用程序定位到.NET 3.5 SP1客户端框架真是太好了。但是,现在我正在使用HttpUtility.HtmlDecode
和HttpUtility.UrlDecode
函数,并且MSDN文档没有指向System.Net之类的任何替代方法。
因此,除了反射源代码并将其复制到我的程序集中(我认为这不值得)之外,.NET 3.5 SP1客户端框架内部还有其他替代方法可以替代此方法功能?他们将这些有用的功能限制在仅用于服务器的代码中,这似乎有点奇怪。
解决方案
回答
.NET 3.5 SP1客户端配置文件安装程序包是.NET的"精简版",仅包含Microsoft认为对客户端应用程序而言.NET的"有用"位。因此,缺少诸如HttpUtility类之类的有用内容。
有关更多信息,请参见ScottGu的博客,搜索"客户端配置文件安装包"。
为了解决这个问题,我们总是可以从GAC中提取" System.Web.dll"(它将位于" c:\ windows \ Microsoft.NET \ Framework \ ..."中)并与应用程序一起部署。但是,我们将需要在部署时跟踪更新和Service Pack。
更好的选择是完全部署.NET Framework。
回答
两种主要方式:
- 使用完整的.NET Framework进行部署
- 为这些功能编写我们自己的/ 3rd party lib
回答
强烈建议我们不要滚动自己的编码。如果HttpUtility.HtmlEncode不可用,请使用很小的Microsoft反跨站点脚本库(v1.5为〜30kb)。
至于解码,也许我们可以使用Mono的解码例程?
回答
我使用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 != 'Uri.EscapeDataString(...) WebUtility.HtmlEncode(...)') { 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; } } }
回答
今天从这里的这个小站点可以找到可以使用C4.0客户端配置文件中的System.Net库完成HtmlEncode / Decode的操作:
##代码##编辑:我重读该问题适用于3.5客户端框架,但也许这对更新4.0的用户可能有用。