Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Actualités

  • Blog de Cyril DURAND, passionné de JavaScript, Ajax, ASP.net et tout ce qui touche au developpement Web Client-Side.

    View Cyril Durand's profile on LinkedIn

    hit counters

BUG : updatepanel et encoding ISO (non UTF-8)

EDIT : hotfix dispo par Ms voir : Updatepanel et encoding non UTF-8 - la suite

Actuellement je bosse sur un site qui utilise l'encoding ISO-8859-15 plutôt que UTF-8. Cela est définit au niveau du web.config via la balise globalization :

<globalization requestEncoding="ISO-8859-15" responseEncoding="ISO-8859-15" fileEncoding="ISO-8859-15" culture="fr-FR" uiCulture="fr-FR" />

Tout fonctionnait bien jusqu'au jour où j'ai décidé de mettre un UpdatePanel ...

<script type="text/C#"> protected void btn1_Click(object sender, EventArgs e) { lit1.Text = Server.HtmlEncode(tb1.Text); } </script> <asp:TextBox ID="tb1" runat="server" /> <asp:UpdatePanel ID="up1" runat="server"> <ContentTemplate> <asp:Literal ID="lit1" runat="server" /> <asp:Button ID="Button1" runat="server" Text="toto" OnClick="btn1_Click" /> </ContentTemplate> </asp:UpdatePanel>

Lorsque je faisais des tests avec mon éfélant, il se transformait en éfélant, vraiment pas cool pour un éfélant !

Je regarde sur google et je tombe sur plusieurs post décrivant le problème, principalement celui-ci : http://forums.asp.net/p/1020399/1379727.aspx. Mais bien sur aucune réponse ...

Après avoir sortis Fiddler, je vois que les paramètres passé en POST lors de la requête ne sont pas encodé comme il faut. Ni une, ni deux, je sors l'artillerie lourde : notepad2 et je regarde les sources de Atlas, je tombe alors sur le code qui génère le contenu de la requête POST :

if (tagName === 'INPUT') { var type = element.type; if ((type === 'text') || (type === 'password') || (type === 'hidden') || (((type === 'checkbox') || (type === 'radio')) && element.checked)) { formBody.append(name); formBody.append('='); formBody.append(encodeURIComponent(element.value)); formBody.append('&'); } } else if (tagName === 'SELECT') { var optionCount = element.options.length; for (var j = 0; j < optionCount; j++) { var option = element.options[j]; if (option.selected) { formBody.append(name); formBody.append('='); formBody.append(encodeURIComponent(option.value)); formBody.append('&'); } } } else if (tagName === 'TEXTAREA') { formBody.append(name); formBody.append('='); formBody.append(encodeURIComponent(element.value)); formBody.append('&'); }

Apparemment le encodeURIComponent n'encode pas les caractères spéciaux comme il faudrait pour ISO-8859-15 (ou tout autre ISO je suppose). A quoi sert cette méthode ? Regardons dans les specs : http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

15.1.3.4 encodeURIComponent (uriComponent)
The encodeURIComponent function computes a new version of a URI in which each instance of
certain characters is replaced by one, two or three escape sequences representing the UTF-8 encoding
of the character.
When the encodeURIComponent function is called with one argument uriComponent, the
following steps are taken:

  1. Call ToString(uriComponent).
  2. Let unescapedURIComponentSet be a string containing one instance of each character valid in
  3. uriUnescaped.
  4. Call Encode(Result(1), unescapedURIComponentSet)
  5. Return Result(3).

La solution est donc de redéfinir la méthode encodeURIComponent (ce que c'est beau JavaScript quand même). A force de bidouille et d'analyse avec Fiddler j'obtiens cette nouvelle fonction.

// corrige des bugs d'atlas lié à l'encoding non utf-8 et les caractères spéciaux var CS_encodeURIComponent = encodeURIComponent; var CS_decodeURIComponent = decodeURIComponent; encodeURIComponent = function(s){ s = escape(s); while (s.indexOf('/') >= 0) { s = s.replace('/', '%2F'); } while (s.indexOf('+') >= 0) { s = s.replace('+', '%2B'); } return s; } decodeURIComponent = function(s){ while (s.indexOf('%2B') >= 0) { s = s.replace('%2B', '+'); } while (s.indexOf('%2F') >= 0) { s = s.replace('%2F', '/'); } return unescape(s); }

Il suffit alors de placer cette fonction quelques part dans votre site, par exemple fixAtlas.js (ben oui vu le nombre de fix faut bien les rassembler quelque part ...) et vous pourrez utiliser l'encoding que vous souhaitez avec un UpdatePanel.

Attention ! Je ne connais pas assez le fonctionnement de l'encoding au niveau d'une requête HTTP pour garantir le bon fonctionnement de cette bidouille. Si vous l'utilisez, il faut bien avoir conscience que cela redéfinit une fonction native de JavaScript, cela peut donc avoir des conséquences inatendu ailleurs dans votre site ! Cette bidouille fonctionne seulement si vous utilisez de l'ISO, en UTF-8 la méthode ne fonctionne pas. 
Si vous modifiez la bidouille ou si vous trouvez des bugs, n'hésitez pas à me le dire via les commentaires.  

Posted: dimanche 10 juin 2007 22:34 par cyril
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Commentaires

benC&S a dit :

Salut Cyril,

J'ai exactement le même problème, mais lorsque j'applique ta solution ca ne change rien.

Où as-tu placé ton javascript dans ta page ?

T'es sûr qu'il n'y a rien d'autre à changer ?

Pour infos, j'ai une page avec une MasterPage et différents UserControl contenant des UpdatePanel. Tout marche nickel quand je rafraichi les UpdatePanel. Mais si je déclarer un bouton en Asynchrone non lié aux UpdatePanel mais qui doit afficher un UpdateProgress ca plante si j'ai des caractères spéciaux dans le titre de la page.

# juin 19, 2007 20:28

cyril a dit :

normalement tu peux placer le js n'importe ou dans la page.

Es tu sur qu'il est bien appellé ? met un alert derriere le block :p

sinon c'est la seule chose que j'ai modifié ...

tu peux reproduire le problème sur une site web tout bete avec une seule page ? si oui envoie le moi par mail (via la page contact) que je regarde.

# juin 19, 2007 22:34

benC&S a dit :

J'avais effectivement testé ton code avec des alerts, mais il n'était jamais appelé. C'est pour ca qu'il me semblait qu'il devait manquer quelque chose.

Finalement j'ai résolu mon problème en essayant de te fabriquer une page reconstituant mon problème.

J'obtenais une erreur javascript 'c00ce514'. Après quelques recherches sur Google, ca marche si j'ajoute ce code dans ma MasterPage :

protected override void OnPreRender(EventArgs e)

{

Response.ContentType = "text/html";

Response.Charset = "iso-8859-1";

base.OnPreRender(e);

}

Regarde si ca peut marcher chez toi aussi comme solution alternative. Merci pour ton aide.

# juin 20, 2007 11:18

cyril a dit :

bizarre que ton code js ne soit jamais lancé, à mon avis doit y avoir un problème ou tu l'as inseré.

pour la solution que tu proposes je vais tester ca m'a l'air plutot interessant.

Merci :)

# juin 20, 2007 12:49

benC&S a dit :

En fait, ta solution permet de résoudre les problèmes d'encodage pour les controles à l'intérieur d'un UpdatePanel et l'autre solution s'applique aux header.

# juillet 5, 2007 14:47

Bleroy a dit :

Bonjour,

J'ai transmis le problème à qui de droit. Il serait judicieux sur ce genre de cas de créer un bug sur Connect ou de me contacter directement.

Je suis très dubitatif sur ton fix qui redéfinit une fonction native de JavaScript pour lui donner un comportement différent, ce qui risque de briser du code existant. En gros, tu dé-ECMA-tises JavaScript...

Je posterai ici des nouvelles quand j'en aurai.

Merci en tout cas d'avoir relevé le problème et proposé une solution.

Bertrand

# septembre 6, 2007 23:53

Bleroy a dit :

Le problème est corrigé dans Orcas beta 2.

# septembre 8, 2007 01:22

cyril a dit :

Merci Bertrand pour la réponse.

Je suis totalement conscient que ma bidouille n'est pas propre est qu'il y a des risques de disfonctionnement sur du code existant mais c'est la seule solution que j'ai trouvé.

Pour les prochains bugs, j'essayerais d'utiliser connect et/ou de te contacter directement.

# septembre 9, 2007 16:42
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- [Expression Web] Astuce de la Semaine : Utilisation et Configuration des Extraits de Code par Chronos, Blog d'un Intégrateur .NET le il y a 4 heures et 17 minutes

- Faire de l'AJAX sans restrictions de domaine par Kévin Gosse le il y a 6 heures et 46 minutes

- [IronPython] : IronPython & Silverlight 2 - Part II par Kim's Blog le 07-22-2008, 14:50

- [WPF] Des requêtes NDepend pour analyser vos projets WPF par Thomas Lebrun le 07-21-2008, 09:27

- Liste de jeux pour Silverlight par Pierrick's Blog le 07-20-2008, 14:37

- T_PAAMAYIM_NEKUDOTAYIM par MadMatt le 07-19-2008, 16:16

- Et je mets le son.... par Pierrick's Blog le 07-19-2008, 12:09

- SharePoint : Comment interdire l’accès à un utilisateur pour tous les sites d’une Web Application par Blog Technique de Romelard Fabrice le 07-18-2008, 19:05

- VPC - Reset de la position de la console par Blog technique de Nicolas Boonaert le 07-18-2008, 16:29

- Un bug dans IE rendra cette page… non-imprimable ! par Le blog de FremyCompany le 07-18-2008, 15:33