[C#] ASP.NET > Localization, ressources etc... Tuto ?

ASP.NET > Localization, ressources etc... Tuto ? [C#] - C#/.NET managed - Programmation

Marsh Posté le 20-03-2006 à 14:28:39    

Chais pas...
Je dois m'y prendre comme un manche, mais je ne trouve rien nulle par de "compréhensible".
 
J'ai l'impression d'être face à un bouquin où on passé 800 pages à expliquer comment écrire "hello world", et qui explique en 20 lignes comment faire une appli client/server multi-threadée d'un jeu en DX10 avec une architecture déporté.
 
Mon besoin est simple.
 
J'ai une page ASPX, avec un texte, genre :
 

Code :
  1. (aspx)
  2. <asp:Label runat="Server" id="myTxt"></asp:Label>
  3. (aspx.cs)
  4. myTxt.Text = "Toto va à la plage";


 
Maintenant, j'ai en Session un code langue.
Il peut être "FRA", "ENG" ou autrechose.
 
Moi je veux que ça donne :
 

Code :
  1. (aspx.cs)
  2. myTxt.Text = maMethodeQuiVaBien.GetText("totoplaya" );


 
Et ça met dans mon label :
"Toto va à la plage" quand ma variable est "FRA"
"Toto goes to the beach" quand elle est "ENG"
"Toto va dtc" quand c'est autrechose.
 
Le tout en utilisant le FrameWork (et un fichier Ressource), plutôt que de faire une méthode proprio qui tape dans la base ou un fichier XML géré à la main.
 
Est-ce que qq1 peut me trouver un lien vers un tuto, ou me filer un exemple (complet) pour faire ça.
 
Jusqu'à présent, tout ce que je trouve, c'est formatter une date en "fr-fr" ou "en-us" en fonction d'une Locale écrite en dure dans la page ASPX (genre 25 pages différentes pour 25 cultures différentes -pkoi pas directement coder en dur...-) et jamais traduire un texte et encore moins un exemple complet.
Genre un coup j'ai bien trouvé un truc, mais à aucun moment j'ai eu l'info de comment ajouter et déclarer mon fichier resx dans mon projet, et je m'en suis jamais sorti...
 
Merci pour votre aide... :sweat:

Reply

Marsh Posté le 20-03-2006 à 14:28:39   

Reply

Marsh Posté le 20-03-2006 à 14:30:32    

Genre ce lien il est pas mal :
 
http://forum.hardware.fr/hardwaref [...] 7795-1.htm
 
Mais j'ai rien panné...
(en plus c'est du VB.NET et non du C#, et rien que sur le nom des objets ça merde...)

Reply

Marsh Posté le 21-03-2006 à 11:05:52    

Arjuna a écrit :

Chais pas...
Je dois m'y prendre comme un manche, mais je ne trouve rien nulle par de "compréhensible".
 
J'ai l'impression d'être face à un bouquin où on passé 800 pages à expliquer comment écrire "hello world", et qui explique en 20 lignes comment faire une appli client/server multi-threadée d'un jeu en DX10 avec une architecture déporté.
 
Mon besoin est simple.
 
J'ai une page ASPX, avec un texte, genre :
 

Code :
  1. (aspx)
  2. <asp:Label runat="Server" id="myTxt"></asp:Label>
  3. (aspx.cs)
  4. myTxt.Text = "Toto va à la plage";


 
Maintenant, j'ai en Session un code langue.
Il peut être "FRA", "ENG" ou autrechose.
 
Moi je veux que ça donne :
 

Code :
  1. (aspx.cs)
  2. myTxt.Text = maMethodeQuiVaBien.GetText("totoplaya" );


 
Et ça met dans mon label :
"Toto va à la plage" quand ma variable est "FRA"
"Toto goes to the beach" quand elle est "ENG"
"Toto va dtc" quand c'est autrechose.
 
Le tout en utilisant le FrameWork (et un fichier Ressource), plutôt que de faire une méthode proprio qui tape dans la base ou un fichier XML géré à la main.
 
Est-ce que qq1 peut me trouver un lien vers un tuto, ou me filer un exemple (complet) pour faire ça.
 
Jusqu'à présent, tout ce que je trouve, c'est formatter une date en "fr-fr" ou "en-us" en fonction d'une Locale écrite en dure dans la page ASPX (genre 25 pages différentes pour 25 cultures différentes -pkoi pas directement coder en dur...-) et jamais traduire un texte et encore moins un exemple complet.
Genre un coup j'ai bien trouvé un truc, mais à aucun moment j'ai eu l'info de comment ajouter et déclarer mon fichier resx dans mon projet, et je m'en suis jamais sorti...
 
Merci pour votre aide... :sweat:


 
Je vois vraiment pas ou est le problème à ton truc.  
 
1e page

Code :
  1. ...
  2.      <asp:combo id="moncombo ... />
  3.      <asp:button id="bok" Text="Valider" onClick="bok_onclick" />
  4. ...


 
1e page (CS)

Code :
  1. public void onload(...)
  2. {
  3.     moncombo.Items.Add("FR" );
  4.     moncombo.Items.Add("EN" );
  5.     ...
  6. }
  7. public void bok_onclick (...)
  8. {
  9.     Session["LANGUE"] = moncombo.SelectedText;
  10.     Response.Redirect("mapage2.aspx" );
  11. }


 
page2

Code :
  1. ...
  2. <asp:Label id="lText" />
  3. ...


 
page2 (CS)

Code :
  1. public void onload(...)
  2. {
  3.    string lg = Session["LANGUE"].ToString();
  4.    if (lg == "FR" )
  5.       lText.Text = "Toto va à la plage"
  6.    else if (lg == "EN" )
  7.       lText.Text = "Toto goes to the beach"
  8. }


 
Voila c'est pas plus compliqué que ça. Si tu veux tu peux racourcir le truc en une page. :D

Reply

Marsh Posté le 22-03-2006 à 09:40:50    

moi23372 a écrit :

Je vois vraiment pas ou est le problème à ton truc.  
....
Voila c'est pas plus compliqué que ça. Si tu veux tu peux racourcir le truc en une page. :D


 
Sauf que si demain il doit mettre une langue en plus, il doit recoder ds toutes ses pages...
Tu dois pouvoir charger ton fichier de ressource en fonction de la langue en session.
une idée :
un fichier xml avec des balises et des contenu avec les langues
ex:

Code :
  1. <MonLabel1>
  2.   <FR>valeur en francais</FR>
  3.   <GB>valeur en GB</GB>
  4. </MonLabel1>


 
et une methode getElement("nomdulabel" ) qui va bien (et qui teste la variable en session)
est ce que l'utilisateur peut changer de langue a la volée ? (je dis ca afin de voir ce qui est le plus pertinent, genre mettre en cache de le fichier de langue ou pas, ou le scinder par langue...)

Reply

Marsh Posté le 22-03-2006 à 14:24:47    

votre solution, c'est ce que j'ai toujours utilisé.
 
sauf que ça n'utilise en rien les outils de localisation du FrameWork, hors c'est ça que je demande...
 
évidement que gérer "manuellement" un document XML ou une table de BDD et utiliser un objet pour y rechercher les libellés que je veux, je sais faire...
 
la solution actuelle :
 
Fichier "labels.xml" :

Code :
  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <labels>
  3. <!-- Bannière -->
  4. <message codmsg="welcome">
  5.  <language codlan="FRA">Bienvenue {0}</language>
  6.  <language codlan="ENG">Welcome {0}</language>
  7. </message>
  8. <message codmsg="prevpage">
  9.  <language codlan="FRA">PAGE PRÉCÉDENTE</language>
  10.  <language codlan="ENG">PREVIOUS PAGE</language>
  11. </message>
  12. [...]
  13. </labels>


 
Fichier language.cs :

Code :
  1. using System;
  2. using System.Xml;
  3. using System.IO;
  4. using System.Text;
  5. namespace bci
  6. {
  7. /// <summary>
  8. /// Summary description for language.
  9. /// </summary>
  10. public class language
  11. {
  12.  private const string DefaultCodlan = "FRA";
  13.  private const string DefaultMessagePattern = "¤{0} - {1}¤";
  14.  private string codlan;
  15.  private XmlNode dom;
  16.  public language(string codlan, string mappath)
  17.  {
  18.   this.codlan = codlan;
  19.   StreamReader sr = new StreamReader(mappath + "/ressources/labels.xml", Encoding.UTF8);
  20.   XmlDocument doc = new XmlDocument();
  21.   try
  22.   {
  23.    doc.LoadXml(sr.ReadToEnd());
  24.   }
  25.   catch
  26.   {
  27.   }
  28.   sr.Close();
  29.   sr = null;
  30.   this.dom = doc.SelectSingleNode("labels" );
  31.   doc = null;
  32.  }
  33.  ~language()
  34.  {
  35.   this.dom = null;
  36.  }
  37.  public string GetMessage(string msgcod)
  38.  {
  39.   string retMessage = string.Format(DefaultMessagePattern, msgcod, this.codlan);
  40.   foreach (XmlNode ch in this.dom.SelectNodes("message" ))
  41.   {
  42.    if (ch.Attributes["codmsg"].Value == msgcod)
  43.    {
  44.     foreach (XmlNode chch in ch.SelectNodes("language" ))
  45.     {
  46.      if (chch.Attributes["codlan"].Value == this.codlan)
  47.      {
  48.       retMessage = chch.InnerText;
  49.       break;
  50.      }
  51.      else if (chch.Attributes["codlan"].Value == DefaultCodlan)
  52.      {
  53.       retMessage = chch.InnerText;
  54.      }
  55.     }
  56.     break;
  57.    }
  58.   }
  59.   return retMessage;
  60.  }
  61. }
  62. }


 
Appels :

Code :
  1. private language lan;
  2. private void Page_Load(object sender, System.EventArgs e)
  3. {
  4. // Ajouter le code pour bloquer si Session vide !
  5. if (Session.Count == 0 || Session["login"] == null || Session["typtie"] == null || Session["codsoc"] == null || Session["password"] == null)
  6. {
  7.  Session.Clear();
  8.  Response.Redirect("Default.aspx", true);
  9. }
  10. lan = new language((string)Session["codlan"], Server.MapPath("." ));
  11. }
  12. private void Page_Unload(object sender, System.EventArgs e)
  13. {
  14. lan = null;
  15. try{commander.Close();}
  16. catch {};
  17. commander = null;
  18. }
  19. protected void NewsList_DataBound(object sender, RepeaterItemEventArgs e)
  20. {
  21. if (e.Item.ItemType == ListItemType.Header)
  22. {
  23.  ((Literal)e.Item.FindControl("titTitle" )).Text = lan.GetMessage("titTitle" );
  24.  ((Literal)e.Item.FindControl("startDate" )).Text = lan.GetMessage("startDate" );
  25.  ((Literal)e.Item.FindControl("endDate" )).Text = lan.GetMessage("endDate" );
  26. }
  27. else if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
  28. {
  29.  DataRowView dr = ((DataRowView) e.Item.DataItem);
  30.  if (dr != null)
  31.  {
  32.   Label newLinkTxt = ((Label) e.Item.FindControl("txtTitre" ));
  33.   LinkButton newLinkBtn = new LinkButton();
  34.   newLinkBtn.Text = ((string) dr["newtit"]).ToString();
  35.   newLinkBtn.CommandName = "numnew";
  36.   newLinkBtn.CommandArgument = ((decimal) dr["numnew"]).ToString();
  37.   newLinkBtn.Command += new CommandEventHandler(NewLinkBtn_Command);
  38.   newLinkTxt.Controls.Add(newLinkBtn);
  39.   ((Label) e.Item.FindControl("txtDatdeb" )).Text = ToolBox.DateGnxToString((string) dr["datdeb"], "-" );
  40.   ((Label) e.Item.FindControl("txtDatfin" )).Text = ToolBox.DateGnxToString((string) dr["datfin"], "-" );
  41.  }
  42. }
  43. }


 
Chuis quand même pas boulet à ce point !
 
Nan, moi ce que je voudrais, c'est un truc genre :
 
<asp:Label runat="Server" id="monMsgCod" />
 
Et zou ! A partir d'un fichier Ressources, ça met automatiquement le libellé correspondant à "monMsgCod" en fonction de la locale actuelle.
Le FrameWork permet de faire ça (à quelques détails près).
J'ai trouvé un bout de code le permettant, mais toujours en se basant sur un truc "manuel", un peu plus amériolé (avec surcharge des méthodes de l'objet WebControl afin de faire la recherche du libellé directement au moment du Render du contrôle, plutôt que de le faire à la main).
Sauf que moi, je cherche une solution pour que ce soit 100% en utilisant le FrameWork.
 
Quand on a une moissoneuse batteuse, je pense que c'est mieux d'apprendre à utiliser l'engin plutôt que de continuer à moissonner à la fauscille...

Message cité 1 fois
Message édité par Arjuna le 22-03-2006 à 14:25:46
Reply

Marsh Posté le 22-03-2006 à 15:13:16    

oui si tu trouves fait moi signe, ça peut être intéressant.

Reply

Marsh Posté le 22-03-2006 à 16:19:30    

Arjuna a écrit :

votre solution, c'est ce que j'ai toujours utilisé.
Quand on a une moissoneuse batteuse, je pense que c'est mieux d'apprendre à utiliser l'engin plutôt que de continuer à moissonner à la fauscille...


ca sent la phrase d'un ex communiste reconverti :D (c une blague, n'y voit pas d'attaque perso ;) )
enfin pour etre plus serieux :  
http://www.microsoft.com/france/ms [...] lier8.mspx
Mais ca ne marche qu'en Framework 2.0 (c'est peut etre celui que tu utilises)

Reply

Marsh Posté le 23-03-2006 à 16:49:23    

merci ! c'est exactement ça !
 
seul truc, c'est que là c'est trop tart, j'ai tout fait à la main :D
mais je mets de ce pas tout de suite là maintenant ce topic en favoris pour le retrouver à la prochaine appli :D
(ça tombe bien, j'ai 3 nouvelles applis à commencer d'ici 1 semaine, et toutes doivent être multi-lingues -dont une en arabe, je vais m'amuser avec la présentation de gauche à droite... heureusement, de mémoire le framework sait faire tout seul- :D)
 
sinon, je n'ai que regardé la vidéo (qui donne pas énorément d'infos) mais à priori, c'est rigoureusement ce que j'avais déjà vu comme possibilité avec le 1.1

Reply

Marsh Posté le 24-03-2006 à 11:09:52    

OK, après tests hier, j'ai réussi à faire marcher le bignou comme je voulais avec un projet PocketPC :)
 
En plus, grosse nouveauté du framework 2.0 : les ressources embeded sont gérée de façon 100% géniales :)
 
-> La ressource "default" est intégrée à l'EXE
-> Les autres sont sous forme de DLL dans un répertoire par culture
-> Le fallback fonctionne correctement : si je suis en "fr-FR" (Français/France), mais qu'il n'y a pas de ressouce associée, il teste la ressource "fr" (Français/Standard), et s'il ne trouve pas, la ressource par défaut (InvariantCultulre, par convention, "en" ), et si toujours rien n'est trouvé, une exception est levée.
-> Si après la compilation on supprime ces DLL, l'appli fonctionne sans problème, mais affiche donc les infos à partir de la ressource par défaut (incluse dans la DLL)
-> Si après la compilation on ajouteune nouvelle DLL en fonction d'une nouvelle culture, elle est immédiatement prise en compte, ce qui permet, comme certains softs, de livrer après coup des traductions, mais aussi de demander à une tierce personne de créer ces traduction au format DLL sans avoir à lui donner les sources de l'appli.
 
Ce que j'ai fais (je posterai le source ce soir, peut-être dans un nouveau thread) :
 
- Création de classes GForm et GLabel dérivées de System.Windows.Forms.Form et System.Windows.Forms.Label
- Pour le GForm, override du "OnPaint", afin de faire ce petit algo :
Si this.Text == string.Empty Ou this.Text == this.Name
Alors
    try {
    this.Text = recherche du txt localisé selon la culture de l'appli (automatiquement mise à la culture UI de l'OS, mais aisément écrasable manuellement si besoin)
    } catch (MissingRessourceDefaultMachinChoseException ex) {
    this.Text = ex.Message
    }
Fin Si
 
Pour le GLabel, évidement, FrameWork buggé pourri inside... OnPaint ne se déclenche jamais. J'ai pas pu trouver un seul évènement capable de se lancer lors de l'affichage/création du contrôle.
Du coup j'ai ajouté une méthode public "SetLabel()" qui fait la même chose.
 
J'ai modifié dans mon projet toutes mes Form et Label par GForm et GLabel (G pour "Globalized" ).
Et du coup, sans une ligne de code (sauf ces putains de "SetLabel()" sur les GLabel) je localise et nomme correctement toutes mes fenêtres et libellés.
J'ai créé aussi une class "GMessage" qui me permet de gérer tout ce qui est message (de la même manière, la classe appelle sur le "get" d'une propriété "Text" la ressource correspondant à la valeur du msgCode passé en paramètre au constructeur).
 
Bref, ça marche et c'est bien cool (mais j'en ai chié un max pour en arriver là :o)

Reply

Marsh Posté le 24-03-2006 à 15:49:07    

Arjuna a écrit :

Genre ce lien il est pas mal :
 
http://forum.hardware.fr/hardwaref [...] 7795-1.htm
 
Mais j'ai rien panné...
(en plus c'est du VB.NET et non du C#, et rien que sur le nom des objets ça merde...)


Ah ouais j'me rappelle. J'en ai aussi chié pour réussir à faire tout fonctionner. Mais une fois que t'as capté pour ces histoires de localisation, ça va. Tu remercie les concepteurs d'avoir rendu ça aussi simple (une fois que tout est pigé)...

Reply

Marsh Posté le 24-03-2006 à 15:49:07   

Reply

Marsh Posté le 24-03-2006 à 15:50:46    

surtout avec la version 2.0, où maintenant "tous" les défaut des versions précédentes ont disparus !

Reply

Marsh Posté le 24-03-2006 à 15:57:06    

P'tain, et moi qui doit développer encore sous le 1.1... J'me rappelle de certains trucs (qui touchent aux bases de données et aux transactions). Des machins qui paraissaient logiques, mais seulement implémentés dans le 2.0... Je sais plus exactement ce que c'était. Je crois style impossible de faire un rollback lors d'un UPDATE. Faudrait que je retrouve...

Reply

Marsh Posté le 24-03-2006 à 16:05:42    

Ah ouais nan voilà : ils ont enfin mis un AcceptChangesDuringUpdate sur les DataAdapter :D

Reply

Marsh Posté le 24-03-2006 à 16:41:03    

chais pas, moi je suis de la vieille école, je bosse jamais sur des données en mode connecté. je trouve ça tout ce qu'il y a de plus gore.

Reply

Marsh Posté le 27-03-2006 à 09:00:59    

Nan là c'est justement pas connecté. C'est plutôt "Je rappatrie ce que je veux dans un DataSet, et après je bosse sur le DataSet. Une fois que c'est fait, mise à jour"...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed