.NET 3.5 SP1客户端框架的HttpUtility替代品是什么?

13

我希望将我的Windows Forms应用程序针对.NET 3.5 SP1 客户端框架进行优化。但是,我现在正在使用HttpUtility.HtmlDecodeHttpUtility.UrlDecode函数,而MSDN文档并没有指向任何其他替代方法,例如System.Net等。

除了从反射源代码并将其复制到我的程序集中(我认为这不值得),您是否知道.NET 3.5 SP1客户端框架内的其他替代方法来替换此功能?它似乎有点奇怪,他们会将这些有用的函数限制为仅限服务器端代码。

7个回答

27

这个网站中得知,在C# 4.0客户端框架中,可以使用System.Net库进行HtmlEncode/Decode操作:

Uri.EscapeDataString(...)
WebUtility.HtmlEncode(...)

编辑:我重新阅读了问题,发现它适用于3.5客户端框架,但对于那些已经更新到4.0的人可能也有用。


Edit: I re-read that the question applied for the 3.5 Client Framework but maybe this can be useful those who have updated 4.0..

作为一个使用 .NET 的人,我确实觉得这很有用。谢谢! - Greg
Uri.EscapeDataString 是我所需要的,而且它在3.5客户端框架中,谢谢! - Blake Mitchell

7

我使用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("&amp;");
                                        continue;
                                    }
                                case '\'':
                                    {
                                        output.Write("&#39;");
                                        continue;
                                    }
                                case '"':
                                    {
                                        output.Write("&quot;");
                                        continue;
                                    }
                                case '<':
                                    {
                                        output.Write("&lt;");
                                        continue;
                                    }
                                case '>':
                                    {
                                        output.Write("&gt;");
                                        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;
        }
    }
}

3
显然,谷歌也找不到它,所以他们自己编写了一个兼容API的版本:
以下是解决方法:
  1. Compile Google's version as a library

    wget 'http://google-gdata.googlecode.com/svn/trunk/clients/cs/src/core/HttpUtility.cs'
    gmcs -t:library HttpUtility.cs
    
  2. Edit your-project.cs to include that namespace

    using Google.GData.Client; // where HttpUtility lives
    
  3. Recompile using the library

    gmcs your-project.cs -r:System.Web.Services -r:System.Web -r:HttpUtility
    

从查看源代码来看,这似乎与.NET 2.0兼容。

昨天我刚写了我的第一个C# hello world程序,然后遇到了这个问题,所以我希望这能帮助其他人。


根据文件顶部的注释,看起来他们使用了Mono的。 - Domenic
这个问题的最佳解决方案!谢谢! - Peter VARGA

3

当涉及到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/完整配置文件,而且System.Web在Windows Phone平台上也不受支持...)


3
我强烈不建议自己编写编码方式。如果 HttpUtility.HtmlEncode 不可用,我会使用 Microsoft Anti-Cross Site Scripting Library,它非常小(v1.5 大约是 30kb)。
至于解码,也许你可以使用 Mono 的解码程序?

1

.NET 3.5 SP1客户端配置文件安装包是.NET的“精简”版本,仅包含Microsoft认为适用于客户端应用程序的“有用”部分。因此,像HttpUtility类这样的有用功能会缺失。

更多信息请参见ScottGu的博客,搜索“Client Profile Setup Package”。

为了解决这个问题,您可以从GAC中提取System.Web.dll(它将在c:\windows\Microsoft.NET\Framework\ ...中),并将其与您的应用程序一起部署。但是,您需要跟踪更新和服务包的部署。

更好的方法可能是承受完整的.NET Framework部署的影响。


0

两种主要方式:

  1. 使用完整的.NET Framework进行部署
  2. 编写自己的/第三方库来实现这些功能

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接