Asp .net 2.0: des points obscurs expliques

<!-- 1 image "new" ds CoursASPNET2-0.aspx --> == SOMMAIRE ==
I) GENERALITES

I.1) Un EDI formidable

I.2) Différentes manière d'inclure C# ou Visual Basic

I.3) L'objet Response

I.4) Les évènements

II) ASP .net et les bases de données

II.1) Essayer plusieurs fois les requêtes, quand perte de connexion

( "lost connexion during query" )

COURS ASP .NET 2.0

I) GENERALITES

 Ce cours n'est pas complet. Je préciserai des points utiles à connaître de l'ASP .Net 2.0 .
L'environnement ASP .Net 2.0 est composé de deux parties. Une partie qui est un langage de programmation évolué, comme le C# ou Visual Basic .Net . La deuxième partie est le langage ASP .Net proprement dit. C'est-à-dire tous les contrôles serveurs ASP .Net. Je parlerai aussi, de manière ponctuelle, de tout l'environnement ASP .Net, vu de manière globale.
 
  ASP .Net 2.0 est difficile d'accès si on essaye de l'aborder directement, sans même connaître Visual Basic .net ou C#, ni la programmation des bases de données dans ces langages, et sans connaître XHTML et CSS( voire Javascript).
  Par conséquent, je vous conseille de ne pas vous lancer directement dans le développement sous ASP .net, car cela peut sembler décourageant, si on tente de se lancer directement. Il est préférable d'abord de maîtriser Visual Basic ou C#, ainsi que XHTML et CSS.

Ce cours sera complété au fûr et à mesure.

Note: j'ai écrit le xhtml entre guillemets, pour éviter les problèmes d'affichage dans le tuto.

I.1) Un EDI formidable

  L'EDI ( Environnement de Développement Intégré) de Visual Studio 2005 est formidable, notamment grâce à Intellisense( qui est une aide à la frappe).   Cet EDI est également hors du commun, car il permet de saisir, et toujours avec Intellisense, tous les langages possibles en programmation ASP .net 2.0:

  • Visual Basic 2005 .net
  • C#
  • Le langage ASP .net 2.0 proprement dit
  • XHTML
  • CSS( les feuilles de style)
  • Javascript( eh oui!)
  • L'ASP classique( ASP 3.0), donc le VB script

  On dispose donc d'un formidable EDI pour chacun de ces langages, y compris l'aide Intellisense, ce qui est très appréciable!

  Un autre intérêt de l'IDE est d'avoir une vue Design, qui permet de visualiser instantanément le résultat à l'écran, et aussi de créer sa page à partir de ce design, quand on le souhaite. Ce n'est donc pas uniquement un simple éditeur de texte.

===I.2) Différentes manière d'inclure C# ou Visual Basic=== Il existe 3 possibilités d'intégrer le code source C# ou Visual Basic. === I.2.1) Séparer le code ASP .net et le code C# dans deux fichiers distincts === La façon la plus simple et la plus claire pour intégrer le code C#( ou Visual Basic .net) est de le placer dans un fichier distinct( d'extension .cs ou .vb).  Ceci présente l'avantage que la lisibilité du programme est meilleure, car on n'a pas à rechercher dans son code ASP .net et XHTML, les parties qu'on a écrites en C#. Cette manière de faire est donc la plus conseillée. Cependant, elle ne suffit pas toujours. I.2.2) Intégrer le code C# avec le code ASP, avec la balise "<script>"
 Une deuxième façon de faire est de mélanger le code C# au code ASP .net, dans le fichier .aspx, en mettant le code C# dans des balises: "<script runat="server" >" et "</script>". Ceci ne présente pas beaucoup de différences avec la méthode de séparer les fichiers, et ne présente, à mon sens, pas beaucoup d'intérêt, car on perd beaucoup de lisibilité. En effet, il est difficile après de retrouver les parties en C# dans tout le code, quand il est mélangé avec le code ASP .net( et donc XHTML).
 Cette méthode est strictement équivalente, en terme d'effet produit, à la méthode de séparer en 2 fichiers.
 Une restriction gênante est qu'on ne peut pas mettre de code c# directement, sans qu'il ne soit inclus dans une fonction, ce qui peut ne pas répondre à tous les besoins. On peut faire d'ailleurs également ce reproche à la méthode de séparer le code.

I.2.3) Intégrer vraiment le code C# au code ASP .net

 Une dernière possibilité est enfin possible, celle d'intégrer "réellement" le code C# au code ASP .net . C'est-à-dire de pouvoir écrire du code XHTML à l'intérieur même de vos lignes C#. Ceci est possible grâce à la balise "<<![CDATA[<%% %>".
Cette façon de procéder est la même que celle utilisée en ASP classique, et permet de faire ce qu'on réalise également en PHP. Dans certains cas, elle est irremplaçable, comme par exemple l'affichage de données d'une base de données, en les mettant en forme dans un tableau XHTML.
On n'est plus obligé de mettre le code C# dans une fonction, on peut commencer à l'écrire directement. Ceci est fondamental, car notre code n'est pas toujours fait pour faire partie d'une fonction liée( à un évènement). Ainsi, votre C# sera exécuté dans l'ordre d'affichage du XHTML et ASP .net de votre page, comme s'il en faisait partie. Ceci est une démarche naturelle et intuitive, qui est d'ailleurs celle du PHP et de l'ASP 3.0.
Le seul inconvénient est qu'on ne pourra plus utiliser de contrôles serveurs ASP .net, tels que les labels par exemple, dans notre fichier .aspx. Et on ne pourra pas non plus exécuter ces contrôles serveurs ASP .net en les mettant dans une fonction qu'on appellerait du fichier .aspx. Cependant, les fonctions liées qui exécutent des contrôles ASP .net sont toujours opérationnelles.
On ne perd rien avec cette méthode, car on garde les possibilités des autres méthodes( c'est-à-dire exécuter de l'ASP .net depuis les fonctions liées), et on a, en plus, d'autres possibilités.

- A l'intérieur même d'une balise XHTML:
Il reste cependant un cas où il faut s'y prendre avec une syntaxe précise, pour intégrer du C# au XHTML: c'est le cas où on veut inclure du C# à l'intérieur même d'une balise XHTML. Par exemple, si on veut, dans une balise "<a href= >" XHTML, définir le lien href avec une variable C#. Dans ce cas, il faut procéder de la manière suivante:

<![CDATA[<%"<% int b=1; %>"
"<a href="Dest.aspx"><%=<![CDATA[<%b %></a>"

On remarque facilement que le code C# à l'intérieur de la balise "<a>" a une syntaxe particulière et inhabituelle. C'est une syntaxe qui est faite juste pour signifier qu'on veut que le compilateur insère le contenu de la variable b, d'où ce "=" écrit directement( on comprend intuitivement cette écriture). De plus, il ne faut pas ajouter de ";" à la fin de la ligne. Là aussi, on peut comprendre, car il ne s'agit pas d'une réelle ligne C#: on demande simplement une insertion dans une balise XHTML.

On peut s'en sortir aussi en utilisant Reponse.Write(), dont je parle ci-dessous. Il suffit alors de concaténer notre code XHTML qu'on passe à l'objet Response, à notre variable C# convertie en string.

  • Remarque: on peut insérer la balise "<% = %>" à l'intérieur d'une chaîne de caractères XHTML, par exemple:===

"href="ma_page.aspx?index=<%=i%></<%=i%></< span>a>"

I.2.4) En utilisant la méthode Response.Write()

Il existe une quatrième possibilité de mélanger du XHTML à du C#.
Ceci est réalisable en utilisant la méthode Response.Write( ). On passe à la méthode une string, qui peut contenir du XHTML. Tout est donc possible, notamment d'inclure des variables C# à l'intérieur même d'une balise XHTML. Le résultat du Response.Write est exactement identique à si on avait écrit le code html dans un fichier html.
Bien sûr, l'inconvénient est que le code XHTML n'est plus coloré par l'IDE, et aussi qu'on n'a plus accès à Intellisense. Cette façon de procéder est donc à éviter.

===I.3) L'objet Response=== L'objet Response de la page courante, représente la réponse donnée au navigateur de l'internaute, par le serveur Web. Cela peut être du XHTML, dans ce cas, il est aisé de comprendre: c'est juste du code XHTML envoyé à l'internaute. Cela peut être aussi des instructions qu'on donne au navigateur de l'internaute, par exemple demander au navigateur de l'internaute de demander lui-même une autre page( dont Response précise l'url, bien sûr).

I.3.1) La méthode Response.Redirect()

Cette fonction permet de rediriger vers une autre page, c'est à dire d'afficher une autre page. Ceci peut répondre à un besoin, dans certaines situations.
Prenons l'exemple Response.Redirect( "~/destination.aspx" ) : dans ce cas, la réponse renvoyée à l'internaute est une demande de redirection vers la page destination.aspx. Le navigateur n'a donc plus qu'à exécuter cette demande, et à afficher cette page destination.aspx( c'est à dire, faire une demande au serveur web, comme d'habitude dans ce cas classique). Conclusion: le serveur web ne va pas chercher directement la page destination.aspx, lorsqu'on utilise Response.Redirect( ). Il va se produire un aller-retour vers l'internaute( serveur->navigateur, puis navigateur->serveur). Mais cet aller-retour est invisible aux yeux de l'internaute, et ne pose par conséquent aucun inconvénient.

- Contrainte du Response.Redirect( ):

Il y a une contrainte à la méthode Response.Redirect( ): on ne peut pas écrire de code html avant de l'appeler, pour une raison que je préciserai. Je veux dire que dans les lignes qui précèdent la ligne du Response.Redirect( ), il ne doit pas y avoir de html. On ne peut donc pas faire de Response.Write( ) avant, car faire Response.Write équivaut à écrire en html. On peut utiliser le Response.Redirect( ) dans un fichier C# ou VB .net, bien sûr. Dans ce cas, le fait de ne pas mettre de html avant est moins gênant, car il y a du html surtout dans le fichier .aspx. On est donc moins gêné qu'en PHP, où existe le même problème pour la redirection, mais où n'existe pas la séparation en deux fichiers .cs et .aspx(par exemple).

===I.4) Les évènements====== I.4.1) Résoudre le problème que peut engendrer le postback des pages ===
Que se passe t'il lorsqu'un évènement tel que l'évènement click est déclenché?
Bien sûr, la procédure liée est appelée. Mais on peut remarquer que la page est réaffichée par post( d'ailleurs on voit que la page se réaffiche à l'écran). Ensuite la procédure liée au click est appelée. Par conséquent, la procédure load est appelée, avant la procédure liée. Cet appel du load en général n'est pas gênant et passe inaperçu. Cependant, le cas où par exemple on initialise le contenu d'une textbox dans le load, afin que la personne puisse modifier un contenu existant, peut être problématique. Car, à supposer que le click valide la saisie, la page sera réaffichée automatiquement par post. Par conséquent, le load sera exécuté à nouveau. Et donc, comme le load initialisait la textbox, cela pose problème, car la textbox sera de nouveau initialisée avec le contenu initial. Ce qui implique que la valeur entrée par l'internaute sera effacée, et remplacée par le contenu initial. Comment résoudre le problème? Il suffit d'utiliser la propriété this.IsPostBack ( this est la page courante). Cette propriété permet de savoir si c'est la première fois ou non, que la page est affichée, ou si c'est un réaffichage par postback. Voici un exemple de source démontrant mes propos:

protected void Page_Load(object sender, EventArgs e)
{
(...)
if (this.IsPostBack = = false)
{
==Text = chaine_depart;==
}
(...)
}

====
===II.1) Essayer plusieurs fois les requêtes, quand perte de connexion( "lost connexion during query" )=== Il peut arriver, lorsque vous faites une requête sql dans asp .net, que vous perdiez la connexion durant la requête. Il se produit alors l'erreur suivante: "lost connexion during query". J'ai rencontré ce problème avec une base MySQL, sur un hébergeur asp .net 2.0 . Mais quand j'exécutais le site en local, l'erreur ne se produisait pas.
Lors d'un appel à la méthode .fill d'un data adapter, par exemple, l'erreur arrivait, et la requête était, bien entendu, interrompue. Cela pouvait arriver aussi lors d'un insert de la méthode ExecuteNonQuery. La seule possibilité de s'en sortir pour l'internaute utilisateur du site, était d'actualiser la page par F5. Il faut remarquer que lorsque cela arrivait, l'erreur ne se reproduisait jamais lors de l'essai suivant. Le site restait donc utilisable, mais son utilisation était assez fastidieuse, et un peu problématique pour le novice.

Je précise que cela m'est arrivé sur une base MySQL avec une liaison ODBC, et en C#.

Un moyen pour s'en sortir définitivement et efficacement, est de recommencer( par programme) une deuxième fois la requête, lorsque le problème arrive. Cela se révèle très efficace, et règle complètement le problème. Le délai d'attente pour l'internaute demeure inchangé, par rapport à l'attente normal de la réponse à la requête, il ne s'aperçoit de rien. Et n'oublions pas que le deuxième essai est tenté uniquement en cas d'échec, donc pas systèmatiquement. Voici un exemple de code pour effectuer ceci:

Remarque: on peut modifier facilement la fonction, afin de lui faire effectuer autant de tentatives qu'on le souhaite( 2 essais étaient assez dans mon cas).

/*********************************************************/
/* Méthode daFill( DataAdapter.fill ) */
/*********************************************************/
// Sans mettre un temps d'attente anormal pour faire le fill.

//Cette méthode sert à faire UNIQUEMENT le data_ad.fill
//Retourne -1 si problème base de données, ou 0 si pas de problème
//Cette valeur sert à pouvoir savoir si le programme appelant doit faire return

public static int daFill(System.Data.Odbc.OdbcConnection Conn, System.Data.Odbc.OdbcDataAdapter data_ad, System.Data.DataSet data_set,
string table, string texte_aff_open, string texte_aff_fill, System.Web.UI.Page mapage)
{

int essais = 0;
Boolean reussi;
do {
reussi = true; //on suppose que ca sera bon cette fois-ci
essais += 1;
try {
data_ad.Fill(data_set, table); // 2eme paramètre pas obligé
} catch (System.Data.Odbc.OdbcException err) {
//je vérifie pas que c'est bien lost connection
//car c'est ça tout le temps, et même si pas ça,
//on fait que réessayer une 2ème fois
reussi = false; //dès qu'on rentre ici, c'est faux!
if (essais > 1) //2 échecs : c'est fini
{
//je change qd même VarGlob.deuxfois
//(VarGlob.deux fois est une variable globale( static) d'un module de
//classe ) VarGlob.deux_fois "Pour webmestre: 2 échecs fill";Response.Write(texte_aff_fill);==

Response.Write("2essais fill effectués. 2 échecs.");

Response.Write("Message: " + err.Message);

Close();

return -1; pb bdd
}
else //on n'a essayé qu'une fois( un échec) { VarGlob.deux_fois "Fill effectué la 2ème fois";Close(); //je fais qd même Conn.close, malgré lost connection==
//( perdue)
//Je rouvre la connexion
try {

Open();

}
catch ( System.Data.Odbc.OdbcException err2) {

Response.Write(texte_aff_open);

Response.Write("open pour 2ème essai fill");

Response.Write("Message: " + err2.Message);

return -1; pb bdd
} //fin try du open no2
//on a pu rouvrir
} //fin if essais>1
}//fin catch du fill no1
} while ((essais < 2) && (reussi = = false));
//essais=1 ou essais=2
if (essais == 1) {
VarGlob.deux_fois = "Fill effectué en une fois";
} //fin du data_ad.fill
return 0; //pas de pb bdd
} // fin daFill
===

</html> * ]>

Adresse d'origine

Ce document intitulé « Asp .net 2.0: des points obscurs expliques » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Rejoignez-nous