Подтвердить что ты не робот

Альтернатива HttpUtility для платформы .NET 3.5 SP1?

Было бы неплохо настроить таргетинг на мое приложение Windows Forms на клиентскую среду .NET 3.5 SP1. Но сейчас я использую функции HttpUtility.HtmlDecode и HttpUtility.UrlDecode, а документация MSDN не указывает на какие-либо альтернативы внутри, скажем, System.Net или что-то в этом роде.

Итак, не так, чтобы отразить исходный код и скопировать его в мою сборку --- что я не думаю, что это того стоит... есть ли альтернативы внутри клиентской среды .NET 3.5 SP1, о которой вы знаете, заменить эту функциональность? Кажется немного странным, что они ограничивают эти полезные функции только кодом сервера.

4b9b3361

Ответ 1

Id настоятельно не рекомендует откатывать свою собственную кодировку. Id использует Microsoft Anti-Cross Site Scripting Library, которая очень мала (v1.5 is ~ 30kb), если HttpUtility.HtmlEncode не доступен.

Что касается декодирования, возможно, вы могли бы использовать процедуру декодирования из Mono?

Ответ 2

Нашел сегодня из этот маленький сайт, который может быть выполнен с помощью библиотеки System.Net в C.Net. Клиентский профиль:

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

Изменить: я перечитываю, что вопрос применим к 3.5 Client Framework, но, возможно, это может быть полезно тем, кто обновил 4.0..

Ответ 3

Я отменил проектирование класса Microsoft System.Net.WebUtility с .NET 4.0 с использованием Reflector (я думаю, с ними все будет в порядке, учитывая обстоятельства). Таким образом, вы можете использовать .NET 4.0 Client Framework (который теперь имеет этот новый класс) или использовать здесь код.

Пока вы используете сильное имя на своей сборке и т.д., вы будете достаточно безопасны. Здесь:

/// <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;
        }
    }
}

Ответ 4

Очевидно, Google не смог найти его, поэтому они написали там собственную 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 -compatible.

Я только что написал свой первый мир привет в Csharp вчера, и я столкнулся с этой проблемой, поэтому надеюсь, что это поможет кому-то еще.

Ответ 5

При обращении к Windows Phone и миру Desktop (клиентский профиль!) самый быстрый способ:

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

Ответ 6

Пакет установки профиля клиента .NET 3.5 SP1 - это "вырезанная" версия .NET, которая включает только то, что Microsoft воспринимает как "полезные" биты .NET для клиентских приложений. Таким образом, отсутствуют полезные вещи, такие как классы HttpUtility.

Подробнее об этом см. блог ScottGu, найдите "Пакет настройки профиля клиента".

Чтобы обойти это, вы всегда можете извлечь System.Web.dll из GAC (он будет в c:\windows\Microsoft.NET\Framework\ ...) и развернуть его с вашим приложением. Тем не менее вам придется отслеживать обновления и пакеты обновления при развертывании.

Лучше всего было бы принять удар полного развертывания .NET Framework.

Ответ 7

Два основных способа:

  • Развертывание с использованием полной .NET Framework
  • Напишите свою собственную/стороннюю библиотеку для этих функций.