WebUtility.Htmldecode vs HttpUtilty.HtmlDecode

j'utilisais WebUtilty.HtmlDecode pour décoder HTML. Il s'avère qu'il n'est pas décoder correctement, par exemple, est censé décoder un caractère"–", mais WebUtilty.HtmlDecode ne décode pas. HttpUtilty.HtmlDecode , cependant, fait.

Debug.WriteLine(WebUtility.HtmlDecode("–"));
Debug.WriteLine(HttpUtility.HtmlDecode("–"));


> –
> –

decode screenshot

la documentation pour les deux est la même: Convertit une chaîne de caractères codée HTML pour la transmission HTTP en une chaîne de caractères décodée.

Pourquoi sont-ils différents, lequel dois-je utiliser, et ce qui va changer si je passe à WebUtility.HtmlDecode pour obtenir "–" pour décoder correctement?

22
demandé sur zi3guw 2013-06-28 00:54:07

3 réponses

la mise en œuvre des deux méthodes sont en effet différentes sur Windows Phone.

WebUtility.HtmlDecode:

public static void HtmlDecode(string value, TextWriter output)
{
    if (value != null)
    {
        if (output == null)
        {
            throw new ArgumentNullException("output");
        }
        if (!StringRequiresHtmlDecoding(value))
        {
            output.Write(value);
        }
        else
        {
            int length = value.Length;
            for (int i = 0; i < length; i++)
            {
                bool flag;
                uint num4;
                char ch = value[i];
                if (ch != '&')
                {
                    goto Label_01B6;
                }
                int num3 = value.IndexOfAny(_htmlEntityEndingChars, i + 1);
                if ((num3 <= 0) || (value[num3] != ';'))
                {
                    goto Label_01B6;
                }
                string entity = value.Substring(i + 1, (num3 - i) - 1);
                if ((entity.Length <= 1) || (entity[0] != '#'))
                {
                    goto Label_0188;
                }
                if ((entity[1] == 'x') || (entity[1] == 'X'))
                {
                    flag = uint.TryParse(entity.Substring(2), NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out num4);
                }
                else
                {
                    flag = uint.TryParse(entity.Substring(1), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out num4);
                }
                if (flag)
                {
                    switch (_htmlDecodeConformance)
                    {
                        case UnicodeDecodingConformance.Strict:
                            flag = (num4 < 0xd800) || ((0xdfff < num4) && (num4 <= 0x10ffff));
                            goto Label_0151;

                        case UnicodeDecodingConformance.Compat:
                            flag = (0 < num4) && (num4 <= 0xffff);
                            goto Label_0151;

                        case UnicodeDecodingConformance.Loose:
                            flag = num4 <= 0x10ffff;
                            goto Label_0151;
                    }
                    flag = false;
                }
            Label_0151:
                if (!flag)
                {
                    goto Label_01B6;
                }
                if (num4 <= 0xffff)
                {
                    output.Write((char) num4);
                }
                else
                {
                    char ch2;
                    char ch3;
                    ConvertSmpToUtf16(num4, out ch2, out ch3);
                    output.Write(ch2);
                    output.Write(ch3);
                }
                i = num3;
                goto Label_01BD;
            Label_0188:
                i = num3;
                char ch4 = HtmlEntities.Lookup(entity);
                if (ch4 != '"151900920"')
                {
                    ch = ch4;
                }
                else
                {
                    output.Write('&');
                    output.Write(entity);
                    output.Write(';');
                    goto Label_01BD;
                }
            Label_01B6:
                output.Write(ch);
            Label_01BD:;
            }
        }
    }
}

HttpUtility.HtmlDecode:

public static string HtmlDecode(string html)
{
    if (html == null)
    {
        return null;
    }
    if (html.IndexOf('&') < 0)
    {
        return html;
    }
    StringBuilder sb = new StringBuilder();
    StringWriter writer = new StringWriter(sb, CultureInfo.InvariantCulture);
    int length = html.Length;
    for (int i = 0; i < length; i++)
    {
        char ch = html[i];
        if (ch == '&')
        {
            int num3 = html.IndexOfAny(s_entityEndingChars, i + 1);
            if ((num3 > 0) && (html[num3] == ';'))
            {
                string entity = html.Substring(i + 1, (num3 - i) - 1);
                if ((entity.Length > 1) && (entity[0] == '#'))
                {
                    try
                    {
                        if ((entity[1] == 'x') || (entity[1] == 'X'))
                        {
                            ch = (char) int.Parse(entity.Substring(2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture);
                        }
                        else
                        {
                            ch = (char) int.Parse(entity.Substring(1), CultureInfo.InvariantCulture);
                        }
                        i = num3;
                    }
                    catch (FormatException)
                    {
                        i++;
                    }
                    catch (ArgumentException)
                    {
                        i++;
                    }
                }
                else
                {
                    i = num3;
                    char ch2 = HtmlEntities.Lookup(entity);
                    if (ch2 != '"151910920"')
                    {
                        ch = ch2;
                    }
                    else
                    {
                        writer.Write('&');
                        writer.Write(entity);
                        writer.Write(';');
                        continue;
                    }
                }
            }
        }
        writer.Write(ch);
    }
    return sb.ToString();
}

fait intéressant, WebUtility n'existe pas sur WP7. De plus, la mise en œuvre WP8 de WebUtility est identique à celle du bureau. L'implémentation desktop de HttpUtility.HtmlDecode n'est qu'un WebUtility.HtmlDecode . Enfin, Silverlight 5 a la même implémentation de HttpUtility.HtmlDecode que Windows Phone, et ne implémente pas WebUtility.

de là, je peux tenter une conjecture: depuis le Windows Phone 7 runtime est basé sur Silverlight, WP7 hérité de la version Silverlight de HttpUtility.HtmlDecode , et WebUtility n'était pas présent. Puis est venu WP8, dont le runtime est basé sur WinRT. WinRT a apporté WebUtility, et l'ancienne version de HttpUtility.HtmlDecode a été conservée pour assurer la compatibilité avec les anciennes applications WP7.

pour savoir lequel vous devez utiliser... Si vous souhaitez cibler WP7 vous n'avez pas d'autre choix que d'utiliser HttpUtility.HtmlDecode . Si vous visez WP8, choisissez la méthode qui convient le mieux à vos besoins. WebUtility est probablement le choix à l'épreuve du futur, juste au cas où Microsoft décide de laisser tomber le runtime Silverlight dans une prochaine version de Windows Phone. Mais je me contenterais du choix pratique de choisir HttpUtility pour ne vous inquiétez pas de supporter manuellement l'exemple que vous avez mis dans votre question.

11
répondu Kevin Gosse 2013-06-27 22:31:22

Les méthodes faire exactement la même chose . De plus, si vous essayez de les décompiler, les implémentations ont l'air d'avoir été copiées d'une autre.

La différence n'est que utilisation prévue . HttpUtility est contenu dans l'ensemble System.Web et devrait être utilisé dans ASP.net applications qui sont construits sur cet assemblage. WebUtility est contenu dans l'ensemble System référencé par presque tous les applications et est fourni à des fins plus générales ou à l'usage du client.

5
répondu Jan Dobkowski 2013-06-27 21:31:08

juste pour prévenir les autres qui trouveront ceci dans la recherche. Utilisez n'importe quelle fonction mentionnée dans la question, mais n'utilisez jamais Windows.Data.Html.HtmlUtilities.ConvertToText(string input) . C'est 70 fois plus lent que WebUtilty.HtmlDecode et produit des accidents! Crash sera nommé comme mshtml!IEPeekMessage dans le DevCenter. Il semble que cette fonction appelle InternetExplorer pour convertir la chaîne. Simplement l'éviter.

1
répondu crea7or 2016-08-28 01:05:09