none
Encodage RRS feed

  • Question

  • Bonjour tout le monde,

    Voilà un sujet a priori battu et rebattu, pourtant me voilà perplexe ...

    Je ne comprenais pas pourquoi mon composant me sortait des choses bizarres, alors je suis parti dans le traitement du détail : en ISO-8859-1, un accent aigu est représenté par le caractère 233, encodé en HTML par %E9, voyons voir comment on l'obtient en UTF8.

    bytes[] b = Encoding.Convert(
                      Encoding.GetEncoding("ISO-8859-1"),
                      Encoding.UTF8,
                      Encoding.GetEncoding("ISO-8859-1").GetBytes("%E9")
                      );
    ? Encoding.UTF8.GetString(b)
    "%E9"

    Ah bon, mais alors si le UTF8 est égal à l'ISO-8859-1, est-ce vraiment la peine de faire tout ça ?
    D'autant qu'il en va de même de "é"

    Alors que d'après d'autres sources, je m'attends à traduire le caractère 233 par la succession des caractères 195 et 169, mais manifestement, pas par la fonction ci-dessus.

    Ai-je commis une confusion ?

    (il y avait bien un forum ASP.Net Fr ?)

    vendredi 28 juin 2013 14:24

Réponses

  • J'ai repris le stockage de données du composant car il s'est avéré que mettre l'intitulé dans l'index, outre que ce n'était pas conceptuellement la meilleure idée qu'on n'ait jamais eue, confirmait créer des effets de bord, à savoir la présence de lignes en doublons.

    Mais en plus, il n'est pas complètement absurde de penser que le fait d'aller chercher ces intitulés dans le contenu de la page plutôt que la base de données source ait quelque chose à voir avec le problème.

    Confirmation (ou pas) demain.


    Eh bien ça y est c'est confirmé, en fait j'étais à quelques clics de souris de l'arrivée.

    Le résultat est tellement évident qu'il m'a fallu réfléchir pour me rappeler où était le problème.

    Le composant que j'ai téléchargé sur codeproject fonctionnait bien en culture anglaise, donc séparateur décimal point et sans accents. Pour adapter au séparateur virgule je m'en suis sorti, pour les accents ça s'est gâté.

    J'ai gardé une bonne partie du format de sérialisation, en une chaîne de caractères qui présente un numéro de ligne dans le panier, numéro de ligne de l'article dans le catalogue, référence article, désignation, prix unitaire. J'ai ajouté un champ quantité, plutôt que de répéter l'enregistrement autant de fois qu'on commande l'article. J'ai quand même apporté une autre modification, c'est que les enregistrements sont séparés par des points-virgules, et j'ai gardé la virgule pour séparer les champs. Ce qui fait qu'en deux split j'ai séparé les enregistrements puis les champs. J'ai mis le prix entre "guillemets simples" car ça s'est avéré plus facile à gérer. Et je garde le point pour séparer les décimales dans la sérialisation, puisque la virgule sert à séparer les champs.

    Dans le projet d'origine, à chaque ligne on récupère dans le contenu de la page les différents champs, on les transfère d'un DataTable vers un DefaultView puis DefaultView.ToTable, ce qui permet d'éviter les doublons, mais comme je le disais jusqu'à un point seulement, puisque l'argument distinct de ToTable effectue en fait un DISTINCT ROW, donc en Anglais, sans accents, ça baigne, puisqu'un article a toujours même numéro de ligne dans le catalogue, même référence, même intitulé, même prix, mais en Français, je n'ai pas détaillé exactement le mécanisme mais pour les désignations comportant des accents je me retrouve avec deux lignes encodées différemment, dont parfois une des deux avec le caractère accentué qui apparaît correctement, pas toujours.

    Une fois que j'ai refait le composant, plutôt que de créer une DataTable dans le composant lui-même je me suis appuyé sur une paire de classes éléments/collection, dans la collection j'ai géré la sérialisation vers le format que je décrivais à l'instant et la désérialisation en sens inverse. Je stocke les données dans le profil utilisateur plutôt qu'un cookie mais ça c'est anecdotique, et ensuite, je peux effectuer les tests en lisant le panier du profil utilisateur dans le Page_Load, et la classe collection dé-sérialise les lignes de commande, et ça nous donne un affichage avec les caractères accentués qui apparaissent proprement. Il y a juste un "e accent aigu" en fait, mais puisqu'il passe bien je ne suis pas inquiet pour le reste.

    Ce n'est pas prêt à être mis en ligne puisqu'il reste à rendre paramétrables l'internationalisation et le formatage, mais au moins le problème des caractères accentués est réglé en même temps que celui des lignes en doublon.

    Que je sois bien sûr d'avoir compris : UTF8 affiche chaque caractère accentué sous la forme de deux caractères (plus pour certains caractères spéciaux), mais c'est transparent pour le programmeur ASP.Net, qui envoie simplement le texte qu'il veut afficher, c'est bien ça ?


    Pour les tests j'initialise simplement comme ça :

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpContext.Current.Profile["Panier"] = "1,'601','AWG601','Axe de pédalier LL','45.98',1;2,'602','BWK602','Axe de pédalier MM','57.94',2;";
        }
    


    Ah oui il me reste à implémenter Ajax,  c'est ça qui occasionne un changement de jeu de caractères, donc la réponse sera plus sûre une fois que ce sera fait.

    • Marqué comme réponse Gloops mercredi 3 juillet 2013 13:30
    • Modifié Gloops mercredi 3 juillet 2013 13:44 référence à Ajax
    mercredi 3 juillet 2013 13:23

Toutes les réponses

  • D'ailleurs ... Je simplifie un peu, je me doute un peu que ce n'est pas l'encodage HTML qu'il faut passer en argument, mais plutôt le caractère 233 lui-même, dans l'exemple, donc avant la fonction ci-dessus j'appelle HttpUtility.HtmlDecode. Mouais, doit y avoir un truc qui cloche ...

    ? Formatage.isoToUtf(HttpUtility.HtmlDecode("axe de p%e9dalier"))
    "axe de p%e9dalier"
        public static string isoToUtf(string entree)
        {
            byte[] b = Encoding.GetEncoding("ISO-8859-1").GetBytes(entree);
            return(Encoding.UTF8.GetString(b));
        }
    
    

    vendredi 28 juin 2013 14:33
  • Bonjour,

    C'est vrai que ce que j'ai fait sur ce point n'est pas très orthodoxe du côté ASP.Net, mais je l'ai quand même mis, puisque la page maîtresse contient ceci :

    <head runat="server">
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    </head>
    

    En tout cas le navigateur indique bien qu'il affiche en UTF-8.

    Il est vrai qu'il y a de quoi se poser la question puisque le corps de la page est correctement accentué, alors que les mêmes intitulés reportés sur le composant s'affichent bizarrement.

    Pourtant, si j'en crois ce que j'ai lu, c'est si on n'affiche pas en UTF-8, que ça arrive ?

    Donc c'est normal on peut envoyer les mêmes caractères pour afficher en UTF-8 qu'en ISO-8859-1 ?

    C'est vrai que conceptuellement c'est assez ardu à assimiler ...

    lundi 1 juillet 2013 10:45
  • Apres quelques recherches "%E9" c'est en effet l'encodage URL.

    Pour obtenir "é" vous devez faire Server.UrlDecode ("%E9").

    Si vous utilisez  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  vous pouvez envoyer directement  "é".

    Cordialement

     

    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.


    • Modifié Aurel Bera mardi 2 juillet 2013 13:43 modif
    mardi 2 juillet 2013 13:41
  • Je suis décidément perplexe, car ça fait effectivement partie de ce que j'ai essayé.

    En fait, si je fais ça sur la page ça s'affiche effectivement correctement, mais sur le composant non.

    Or, ce que j'ai lu laisse entendre que la différence, c'est qu'un composant Ajax convertit d'office son affichage en UTF8. Donc, la différence entre les deux est d'autant moins compréhensible, du fait que toute la page est en UTF8.

    Il va falloir que je donne quelques éléments un peu plus précis, je crois que je vais revenir là-dessus Jeudi.

    J'ai commencé avec un composant proposé tout prêt, après l'avoir adapté en fonction du séparateur décimal, mais finalement le problème de l'encodage met en avant une erreur de conception, qui fait apparaître des lignes en doublons lorsqu'un intitulé contient des caractères accentués, du fait que l'intitulé est inclus dans l'index de ce qui est affiché (si si on a osé).

    Alors hier j'ai écrit un objet base de données, j'ai pu écrire sur une page avec, histoire de le tester, donc maintenant je vais pouvoir m'en servir pour écrire un nouveau composant. Et donc une fois que je vais mettre celui-ci sur une page je m'attends à retrouver mon problème d'encodage, avec la différence que ça ne générera plus de lignes en doublons (une avec le caractère accentué et une avec l'encodage).

    Donc, prochain épisode Jeudi, ou peut-être Vendredi si j'ai à répondre à autre chose.

    Mais alors ... que l'Unicode affiche un caractère accentué sur deux caractères, je l'ai inventé ? Ou Unicode et UTF8 ce n'est pas la même chose peut-être ?

    mardi 2 juillet 2013 15:34
  • Pour éclairer Unicode/UTF8 veuillez regarder ici:

    https://en.wikipedia.org/wiki/UTF-8

    De l'autre cote, avez-vous bien enregistre le fichier ascx avec Unicode?
    Pour ça, ouvrez avec Visual Studio le fichier, Save As, petite icone a cote de Save, Save with Encodning et sélectez Unicode?

    Voir l'image:

    Save With Encoding 

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    mercredi 3 juillet 2013 07:59
  • J'ai repris le stockage de données du composant car il s'est avéré que mettre l'intitulé dans l'index, outre que ce n'était pas conceptuellement la meilleure idée qu'on n'ait jamais eue, confirmait créer des effets de bord, à savoir la présence de lignes en doublons.

    Mais en plus, il n'est pas complètement absurde de penser que le fait d'aller chercher ces intitulés dans le contenu de la page plutôt que la base de données source ait quelque chose à voir avec le problème.

    Confirmation (ou pas) demain.


    • Modifié Gloops mercredi 3 juillet 2013 08:42 syntaxe
    mercredi 3 juillet 2013 08:37
  • J'ai repris le stockage de données du composant car il s'est avéré que mettre l'intitulé dans l'index, outre que ce n'était pas conceptuellement la meilleure idée qu'on n'ait jamais eue, confirmait créer des effets de bord, à savoir la présence de lignes en doublons.

    Mais en plus, il n'est pas complètement absurde de penser que le fait d'aller chercher ces intitulés dans le contenu de la page plutôt que la base de données source ait quelque chose à voir avec le problème.

    Confirmation (ou pas) demain.


    Eh bien ça y est c'est confirmé, en fait j'étais à quelques clics de souris de l'arrivée.

    Le résultat est tellement évident qu'il m'a fallu réfléchir pour me rappeler où était le problème.

    Le composant que j'ai téléchargé sur codeproject fonctionnait bien en culture anglaise, donc séparateur décimal point et sans accents. Pour adapter au séparateur virgule je m'en suis sorti, pour les accents ça s'est gâté.

    J'ai gardé une bonne partie du format de sérialisation, en une chaîne de caractères qui présente un numéro de ligne dans le panier, numéro de ligne de l'article dans le catalogue, référence article, désignation, prix unitaire. J'ai ajouté un champ quantité, plutôt que de répéter l'enregistrement autant de fois qu'on commande l'article. J'ai quand même apporté une autre modification, c'est que les enregistrements sont séparés par des points-virgules, et j'ai gardé la virgule pour séparer les champs. Ce qui fait qu'en deux split j'ai séparé les enregistrements puis les champs. J'ai mis le prix entre "guillemets simples" car ça s'est avéré plus facile à gérer. Et je garde le point pour séparer les décimales dans la sérialisation, puisque la virgule sert à séparer les champs.

    Dans le projet d'origine, à chaque ligne on récupère dans le contenu de la page les différents champs, on les transfère d'un DataTable vers un DefaultView puis DefaultView.ToTable, ce qui permet d'éviter les doublons, mais comme je le disais jusqu'à un point seulement, puisque l'argument distinct de ToTable effectue en fait un DISTINCT ROW, donc en Anglais, sans accents, ça baigne, puisqu'un article a toujours même numéro de ligne dans le catalogue, même référence, même intitulé, même prix, mais en Français, je n'ai pas détaillé exactement le mécanisme mais pour les désignations comportant des accents je me retrouve avec deux lignes encodées différemment, dont parfois une des deux avec le caractère accentué qui apparaît correctement, pas toujours.

    Une fois que j'ai refait le composant, plutôt que de créer une DataTable dans le composant lui-même je me suis appuyé sur une paire de classes éléments/collection, dans la collection j'ai géré la sérialisation vers le format que je décrivais à l'instant et la désérialisation en sens inverse. Je stocke les données dans le profil utilisateur plutôt qu'un cookie mais ça c'est anecdotique, et ensuite, je peux effectuer les tests en lisant le panier du profil utilisateur dans le Page_Load, et la classe collection dé-sérialise les lignes de commande, et ça nous donne un affichage avec les caractères accentués qui apparaissent proprement. Il y a juste un "e accent aigu" en fait, mais puisqu'il passe bien je ne suis pas inquiet pour le reste.

    Ce n'est pas prêt à être mis en ligne puisqu'il reste à rendre paramétrables l'internationalisation et le formatage, mais au moins le problème des caractères accentués est réglé en même temps que celui des lignes en doublon.

    Que je sois bien sûr d'avoir compris : UTF8 affiche chaque caractère accentué sous la forme de deux caractères (plus pour certains caractères spéciaux), mais c'est transparent pour le programmeur ASP.Net, qui envoie simplement le texte qu'il veut afficher, c'est bien ça ?


    Pour les tests j'initialise simplement comme ça :

        protected void Page_Load(object sender, EventArgs e)
        {
            HttpContext.Current.Profile["Panier"] = "1,'601','AWG601','Axe de pédalier LL','45.98',1;2,'602','BWK602','Axe de pédalier MM','57.94',2;";
        }
    


    Ah oui il me reste à implémenter Ajax,  c'est ça qui occasionne un changement de jeu de caractères, donc la réponse sera plus sûre une fois que ce sera fait.

    • Marqué comme réponse Gloops mercredi 3 juillet 2013 13:30
    • Modifié Gloops mercredi 3 juillet 2013 13:44 référence à Ajax
    mercredi 3 juillet 2013 13:23
  • Ah oui il me reste à implémenter Ajax,  c'est ça qui occasionne un changement de jeu de caractères, donc la réponse sera plus sûre une fois que ce sera fait.

    ça y est, à présent j'ai un panier qui peut se placer où on veut sur la page, et qui affiche correctement les axes de pédaliers, à raison d'une ligne par référence.

    Il sera certes intéressant que j'harmonise les styles, car là c'est un panier à fond jaune avec entête rouge, sur les pages à entêtes bleues proposées par défaut par Visual Web Developer 2010 :)

    mercredi 3 juillet 2013 16:41
  • Que je sois bien sûr d'avoir compris : UTF8 affiche chaque caractère accentué sous la forme de deux caractères (plus pour certains caractères spéciaux), mais c'est transparent pour le programmeur ASP.Net, qui envoie simplement le texte qu'il veut afficher, c'est bien ça ?

    Tant qu'à avoir mobilisé des ressources, ça serait bien que j'aie les idées nettes sur cette question.

    En tout cas merci pour m'avoir aidé à chercher.

    mercredi 3 juillet 2013 16:43