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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
0
16 435
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

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

Для получения дополнительной информации см. Блог ScottGu, найдите «Пакет установки профиля клиента».

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

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

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

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

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

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

Я перепроектировал класс 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;
        }
    }
}

Сегодня обнаружил из этот вот маленький сайт, что HtmlEncode / Decode может быть выполнен с использованием библиотеки System.Net в профиле клиента C# 4.0:

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

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

Как человек, использующий .NET, я действительно нашел это полезным. Спасибо!

Greg 25.03.2011 08:55

Uri.EscapeDataString был тем, что мне было нужно, и этот является в профиле клиента 3.5, спасибо!

Blake Mitchell 25.02.2014 01:47

Видимо гугл тоже не смог его найти, поэтому написали там собственную api-совместимую версию:

Вот обходной путь:

  1. Скомпилировать версию Google как библиотеку

    wget 'http://google-gdata.googlecode.com/svn/trunk/clients/cs/src/core/HttpUtility.cs'
    gmcs -t:library HttpUtility.cs
    
  2. Отредактируйте your-project.cs, чтобы включить это пространство имен

    using Google.GData.Client; // where HttpUtility lives
    
  3. Перекомпилируйте с помощью библиотеки

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

Взглянув на исходный код, можно сделать вывод, что он совместим с .NET 2.0.

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

Согласно комментарию в верхней части файла, похоже, что они использовали Mono.

Domenic 15.12.2011 18:19

Лучшее решение этой проблемы! Спасибо!

Peter VARGA 15.02.2015 19:01

При обращении к телефон с операционной системой Виндоуси в мире Рабочий стол (Профиль клиента!) Самый быстрый способ, который я нашел, это:

        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, но имя класса отличается в мире телефон с операционной системой Виндоус ... (не люблю использовать System.Web / полный профиль, когда он действительно не нужен, а System.Web не поддерживается на платформу Windows Phone в любом случае ...)

Другие вопросы по теме