Alternative to HttpUtility for .NET 3.5 SP1 client framework?
Asked Answered
I

7

13

It'd be really nice to target my Windows Forms app to the .NET 3.5 SP1 client framework. But, right now I'm using the HttpUtility.HtmlDecode and HttpUtility.UrlDecode functions, and the MSDN documentation doesn't point to any alternatives inside of, say, System.Net or something.

So, short from reflectoring the source code and copying it into my assembly---which I don't think would be worth it---are there alternatives inside of the .NET 3.5 SP1 client framework that you know of, to replace this functionality? It seems a bit strange that they'd restrict these useful functions to server-only code.

Impiety answered 30/8, 2008 at 20:13 Comment(0)
U
3

I’d strongly not recommend rolling your own encoding. I’d use the Microsoft Anti-Cross Site Scripting Library which is very small (v1.5 is ~30kb) if HttpUtility.HtmlEncode isn’t available.

As for decoding, maybe you could use the decoding routine from Mono?

Unexceptionable answered 31/8, 2008 at 1:41 Comment(0)
I
27

Found today from this here little site that HtmlEncode/Decode can be done using System.Net library in C# 4.0 Client Profile:

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

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..

Insinuate answered 18/12, 2010 at 23:0 Comment(2)
As someone using .NET, I indeed found this useful. Thanks!Chess
Uri.EscapeDataString was what I needed, and that is in the 3.5 Client Profile, thanks!Xylidine
C
7

I reverse engineered the Microsoft System.Net.WebUtility class from .NET 4.0 using Reflector (I think they'd be ok with it given the circumstances). So you could either use .NET 4.0 Client Framework (which now has this new class) or use the code here.

As long as you use a strong name on your assembly etc., you'll be safe enough. Here:

/// <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;
        }
    }
}
Cati answered 8/12, 2010 at 15:45 Comment(0)
U
3

I’d strongly not recommend rolling your own encoding. I’d use the Microsoft Anti-Cross Site Scripting Library which is very small (v1.5 is ~30kb) if HttpUtility.HtmlEncode isn’t available.

As for decoding, maybe you could use the decoding routine from Mono?

Unexceptionable answered 31/8, 2008 at 1:41 Comment(0)
P
3

Apparently google couldn't find it either, so they wrote there own api-compatible version:

Here's a workaround:

  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
    

From glancing at the source code, it appears that this is .NET 2.0-compatible.

I just wrote my first hello world in csharp yesterday and I ran into this problem, so I hope this helps someone else.

Possessory answered 15/12, 2011 at 9:15 Comment(1)
According to the comment at the top of the file, it looks like they used Mono's.Impiety
G
3

When addressing Windows Phone and the Desktop (Client profile!) world the fastest way I found is:

        private static string HtmlDecode(string text)
        {
#if WINDOWS_PHONE
            return System.Net.HttpUtility.HtmlDecode(text);
#else
            return System.Net.WebUtility.HtmlDecode(text);
#endif
        }

The odd thing for me was that the namespace is System.Net but the class name differs in the Windows Phone world ... (don't like to use System.Web/full profile when not really needed and the System.Web isn't supported on the Windows Phone platform anyway ...)

Grados answered 8/10, 2012 at 21:22 Comment(0)
A
1

The .NET 3.5 SP1 Client Profile Setup Package is the "cut down" version of .NET that only includes what Microsoft perceive to be the "useful" bits of .NET for client applications. So, useful things like the HttpUtility classes are missing.

For more on that see ScottGu's blog, search for "Client Profile Setup Package".

To get around this you could always extract System.Web.dll from the GAC (it'll be in c:\windows\Microsoft.NET\Framework\ ... ) and deploy it with your application. You will, however, need to track updates and service packs as you deploy.

Better might be to take the hit of the full .NET Framework deployment.

Apc answered 30/8, 2008 at 21:30 Comment(0)
I
0

Two main ways :

  1. Deploy using the full .NET Framework
  2. Write your own / 3rd party lib for these functionalities
Intercrop answered 31/8, 2008 at 1:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.