août 11 2010

[ASP.NET 4] Nouveautés pour la détection et gestion des navigateurs internet – Partie 1

Category: ASP.NET | ASP.NET 4Nicolas Esprit @ 23:22

Depuis l’an 2000 le nombre de navigateurs, ainsi que les différentes versions de ceux-ci, n’a cessé de croître. Chacun ayant ses propres spécificités et respectant les normes W3C jusqu’à un certain degré. Il n’est pas toujours aisé de rendre un site compatible avec tous les navigateurs. Bien entendu les choses évoluent, il suffit de regarder les résultats du dernier preview d’Internet Explorer 9 ou bien les excellentes capacités de Chrome ou Firefox 4. Néanmoins il existe encore de nombreux postes de travail équipés d’anciennes versions, comme Internet Explorer 6 pour ne citer que lui. Nous allons voir dans cet article les bases de la détection de navigateur en ASP.NET, avec un rappel sur l’entête User-Agent. Nous regarderons ensuite les moyens à notre disposition de gérer les spécificités des différents navigateurs. Enfin, nous nous attarderons sur les nouveautés apparues en ASP.NET 4.0 à ce sujet. Note : le sujet de l’article n’est pas de produire des feuilles de style CSS compatibles avec les différents navigateurs, mais bel et bien de détecter gérer ces derniers au cas par cas.

User-Agent

Lorsqu’un navigateur adresse une requête à un serveur pour obtenir une page web, il transmet une chaîne de type texte pour s’identifier. Celle-ci est incluse dans la requête HTTP via l'entête « User-Agent » et elle donne des informations comme par exemple : le nom de l'application, la version, le système d'exploitation, la langue, etc...

 

L’image ci-dessus représente le User-Agent pour un navigateur Internet Explorer 8 tournant sous Windows Seven. Cette représentation est simplifiée, car dans la réalité le User-Agent va contenir des informations complémentaires sur certaines applications ou composants additionnels installés sur le poste. Prenons un exemple, pour mon portable pro le User-Agent est le suivant :

Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; InfoPath.3)

On peut déduire de cette chaîne que mon portable :

  • utilise une version 64 bit de Windows Seven grâce à la présence de WOW64 (Windows-On-Windows 64–bit) qui signifie que j’exécute une version 32 bit d’Internet Explorer sur un processeur 64 bit et de NT 6.1 qui indique que c’est un Windows 7. En fait je triche, c’est un Windows Server 2008 R2, mais ce n’est qu’un détail vu qu’il est basé sur la même couche que Windows 7.
  • utilise le moteur de rendu Trident 4.0 (Trident/4.0) qui est le moteur de rendu le plus standard (et celui par défaut) d’Internet Explorer 8
  • dispose des frameworks .NET 2.0 (.NET CLR 2.0.50727), .NET 3.0 (.NET CLR 3.0.30729) et 3.5 (.NET CLR 3.5.30729) et 4.0 (.NET4.0C et  .NET4.0E)
  • dispose du OfficeLiveConnector.1.4
  • etc…

Si vous désirez en savoir plus sur les différentes informations, ces liens vous seront utiles :

Après avoir révisé les bases sur le User-Agent, regardons de plus prêt quels mécanismes offre ASP.NET pour la détection des browsers.

 

La propriété HttpRequest.Browser

En ASP.NET et depuis la version 1.0, cette propriété représente un objet HttpBrowserCapabilities qui permet de lister les capacités d’un navigateur. Le code ci-dessous permet d’afficher les différentes informations qu’il contient :

HttpBrowserCapabilities bc = Request.Browser;
Response.Write("<p>Browser Capabilities:</p>");
Response.Write("Type = " + bc.Type + "<br>");
Response.Write("Name = " + bc.Browser + "<br>");
Response.Write("Version = " + bc.Version + "<br>");
Response.Write("Major Version = " + bc.MajorVersion + "<br>");
Response.Write("Minor Version = " + bc.MinorVersion + "<br>");
Response.Write("Platform = " + bc.Platform + "<br>");
Response.Write("Is Beta = " + bc.Beta + "<br>");
Response.Write("Is Crawler = " + bc.Crawler + "<br>");
Response.Write("Is AOL = " + bc.AOL + "<br>");
Response.Write("Is Win16 = " + bc.Win16 + "<br>");
Response.Write("Is Win32 = " + bc.Win32 + "<br>");
Response.Write("Supports Frames = " + bc.Frames + "<br>");
Response.Write("Supports Tables = " + bc.Tables + "<br>");
Response.Write("Supports Cookies = " + bc.Cookies + "<br>");
Response.Write("Supports VB Script = " + bc.VBScript + "<br>");
Response.Write("Supports JavaScript = " + bc.JavaScript + "<br>");
Response.Write("Supports Java Applets = " + bc.JavaApplets + "<br>");
Response.Write("Supports ActiveX Controls = " + bc.ActiveXControls + "<br>");
Response.Write("CDF = " + bc.CDF + "<br>");

Avec ces informations facilement accessibles, il est possible de gérer le rendu des pages d’une application Web en fonction du navigateur et/ou des modules complémentaires installés sur le poste client.

 

Changer dynamiquement la feuille de style CSS en fonction du navigateur

Le code ci-dessous propose une bête solution réutilisable en ASP.NET qui permet de choisir un fichier CSS basé sur le type de navigateur et son numéro de version. Ce code peut-être inclut dans une MasterPage ou un UserControl comme c’est le cas ici :

<%@ Control Language="C#" %>

<%
if (Request.Browser.Browser.ToString() == "IE")
if (Request.Browser.MajorVersion < 4 )
Response.Write("<link rel='stylesheet' type='text/css' href='../Styles/NewSite.css'></link>");
else
Response.Write("<link rel='stylesheet' type='text/css' href='../Styles/Site.css'></link>");
else if (Request.Browser.MajorVersion < 5)
Response.Write("<link rel='stylesheet' type='text/css' href='../Styles/NewSite.css'></link>");
else
Response.Write("<link rel='stylesheet' type='text/css' href='../Styles/Site.css'></link>");
%>

Pour utiliser cet UserControl que nous allons appeler Browser.ascx, on utilise la classique balise Register. Il faut remplacer le link statique de la feuille de style actuelle au sein de la balise <head>. Dans l’exemple suivant, le UserControl est utilisé dans une MasterPage :

<%@Register TagPrefix="util" TagName="Browser" Src="~/UserControls/Browser.ascx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>ASP.NET : Application de test</title>
<%-- <link href="~/Styles/Site.css" rel="stylesheet" type="text/css" /> --%>
<util:Browser runat="server" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>

 

Changer dynamiquement la MasterPage en fonction du navigateur

L’astuce qui suit est apparue avec ASP.NET 2.0, à savoir changer dynamiquement de MasterPage dans une Page en fonction du navigateur par le biais d’une syntaxe déclarative. Admettons que j’ai dans mon application Web une MasterPage pour Internet Explorer et une autre pour Firefox dont voici l’aperçu :

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Firefox.master.cs" Inherits="MasterPageBrowser.Firefox" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>ASP.NET : Application de test pour Firefox</title>
<link href="~/Styles/SiteFirefox.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>

et pour Internet Explorer :

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="IE.master.cs" Inherits="MasterPageBrowser.IE" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head runat="server">
<title>ASP.NET : Application de test pour Internet Explorer</title>
<link href="~/Styles/SiteIE.css" rel="stylesheet" type="text/css" />
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>

Le code suivant montre comme il est facile de faire cela dans la directive Page :

<%@ Page Title="Home Page" Language="C#" ie:MasterPageFile="~/IE.master" mozilla:MasterPageFile="~/Firefox.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="MasterPageBrowser._Default" %>


<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
...
</asp:Content>

Comme vous pouvez le voir, les directives “ie:” et “mozilla” permettent de choisir la bonne MasterPage en fonction du Browser. Le tableau ci-dessous résume les différentes possibilités :

Browser ID Browser Name

ie

Any version of Internet Explorer

netscape3

Netscape Navigator 3.x

netscape4

Netscape Communicator 4.x

netscape6to9

Any version of Netscape higher than 6.0

mozilla

Firefox and other Mozilla-powered browsers

opera

Opera

up

Openwave-powered devices

nokia

Nokia-powered devices

pie

Pocket Internet Explorer

 

Nous aurions pu bien entendu ne pas utiliser la version déclarative et choisir dynamiquement la MasterPage dans l’event PreInit de la page grâve à l’objet HttpBrowserCapabilities (propriété Request.Browser) comme ci-dessous :

public void Page_PreInit (Object sender, EventArgs e) 
{
if (Request.Browser.IsBrowser("IE"))
this.MasterPageFile = "IE.master";
else if (Request.Browser.IsBrowser("Mozilla"))
this.MasterPageFile = "Firefox.master";
else
this.MasterPageFile = "Site.master";
}

Notez que l’astuce utilisant la syntaxe déclarative ne s’arrête pas aux MasterPages, mais peut également être appliquée aux contrôles :

<asp:button id="btnTest" runat="server"
ie:text="IE Text"
mozilla:text="Firefox Text"
text="Default Text"/>

Dans la deuxième partie de cet article nous irons plus loin avec les nouveautés ASP.NET 4.0, notamment l’extensibilité des HttpBrowserCapabilities.

Tags: , , , , ,

Commentaires

1.
Macbernie Macbernie France says:

ça marche pas du tout la méthode pour changer la feuille de style en fonction du navigateur, sa affiche <%@Register TagPrefix="util" TagName="browser" Src="browser.ascx" %> en haut de page comme du simple texte

Les commentaires sont clos