FAQ ASP.NET/C#
FAQ ASP.NET/C#Consultez toutes les FAQ
Nombre d'auteurs : 39, nombre de questions : 371, dernière mise à jour : 15 juin 2021
En ASP.NET, l'utilisation du ~/ est une fonctionalité serveur, faisant donc appel à un traitement sur le serveur.
La problématique
En effet, seul le serveur est en mesure de connaitre la racine de l'application Web. Cette affirmation peut sembler étonnante mais pour comprendre imaginons un domaine comme www.masociete.com. Ce domaine peut héberger autant d'application web qu'on le souhaite (qui peuvent d'ailleurs ne pas être toutes en ASP.NET). Nous pouvons donc avoir :
http://www.masociete.com : Portail de présentation de l'entreprise
http://www.masociete.com/Gestion : Portail de l'application de gestion
http://www.masociete.com/B2B : Portail de travail collaboratif
...
Vue du navigateur, qu'est-ce donc que la racine d'une application ? Comment doit-il interpréter une URL de la forme /Image/Monimage.gif ou ../MonDossier/Monfichier.htm ?
Au yeux du navigateur, ce sont des URLs relatives ! Elles sont relatives à l'URL saisie dans la barre d'adresse du navigateur.
L'opérateur racine
ASP.NET introduit l'opérateur racine (~) pour la raison expliquée ci-dessus. L'utilisation de cet opérateur dans une URL fait de cette URL une URL virtuelle. Puisqu'elle est virtuelle, il faudra lui appliquer un traitement pour la transfomer en une URL réelle. Ce traitement s'effectue sur le serveur. Pour preuve, si l'on reprend ce code :
<li><a
href
=
"~/Boutique/Commandes.aspx"
>
Mes commandes</a></li>
Affichez votre page dans votre navigateur puis visualisez le code source, vous obtenez :
<li><a
href
=
"~/Boutique/Commandes.aspx"
>
Mes commandes</a></li>
Et oui, le (~) est arrivé sur le navigateur pour qui il ne signifie absolument rien ! L'URL virtuelle n'a subie aucune transformation. Il faut a tout pris que le (~) soit traité par le serveur.
Solutions
Comme on le suggère ci-dessus, il est possible d'utiliser WebControl HyperLink en lien et place de la balise HTML <a></a>. Le WebControl HyperLink étant un contrôle serveur Web, l'URL virtuelle sera correctement transformée.
Mais il est aussi possible de transformer la balise HTML <a></a> (qui est traité par ASP.NET comme du text litéral) en ce qu'on appel un HtmlControl, qui lui sera traité coté serveur. Il suffit de lui ajouter l'attribut runat="server" comme dans le code suivant :
<li><a
href
=
"~/Boutique/Commandes.aspx"
runat
=
"server"
>
Mes commandes</a></li>
Testez la différence dans votre navigateur, vous verrez dans la source HTML que l'URL virtuelle a belle et bien étée transformée. Le serveur a fait son travail.
Limitations
Qu'il s'agisse de WebControl ou d'HtmlControl, l'utilisation de l'opérateur (~) n'est pas la panacée. Par exemple le code suivant ne fonctionnera pas :
<div
style
=
"background-image:url(~/Image/Monimage.jpg);"
runat
=
"serve"
></div>
En effet, seules les propriétés marquées comme étant des urls bénéficient du mécanisme lié à l'utilisation de l'opérateur (~). Et là, pour resoudre le problème, il faut passer par une abstraction supplémentaire, mais c'est une autre histoire...
J'ai eu ce petit soucis avec le ReportViewer qui ouvre une nouvelle fenêtre du navigateur quand on lui demande d'exporter l'état. J'ai trouvé cette parade (et je reprendrais l'exemple de l'export d'un état pour cet exemple)
// Préparation de la réponse :
// effacement,renseignement du type de contenu,informations supplémentaires
Page.
Response.
Clear
(
);
Page.
Response.
ContentType =
mimeType;
Page.
Response.
AddHeader
(
"Content-Disposition"
,
"attachment; filename="
+
nomdufichier);
Page.
Response.
Flush
(
);
// Ecriture du contenu du fichier dans le flux de réponse
Page.
Response.
BinaryWrite
(
reportContent);
// Fermeture et envoie de la réponse
Page.
Response.
Flush
(
);
Page.
Response.
Close
(
);
Page.
Response.
End
(
);
Voila, votre navigateur vous affiche maintenant la boite de dialogue de téléchargement du fichier sans ouvrir de nouvelle page.