août 19 2010

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

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

Comme je l’indiquais dans mon précédent billet sur les Nouveautés pour la détection et gestion des navigateurs internet, la propriété Request.Browser correspond à un objet HttpBrowserCapabilities. Cet objet obtient des informations du navigateur ou périphérique client lors d'une demande HTTP, indiquant à notre application le type et le niveau de prise en charge proposés par le navigateur.

Les propriétés exposées par l'objet HttpBrowserCapabilities indiquent des fonctions inhérentes du navigateur, mais ne reflètent pas nécessairement les paramètres actuels de celui-ci. Par exemple, la propriété Cookies indique si un navigateur prend en charge des cookies de manière fondamentale, mais il n'indique pas si le navigateur à l’origine de la requête possède des cookies activés.  

ASP.NET 4.0 : Nouveautés concernant les Browser Capabilities

L’object HttpBrowserCapabilities est piloté par un ensemble de fichiers de définition de navigateur. Ces fichiers, dont l’extension est .browser, contiennent des informations sur les capacités des navigateurs. Avec l’arrivée de la  version 4 d’ASP.NET, ces fichiers de définition ont été mis à jour et contiennent des informations sur les navigateurs les plus récents. La liste suivante montre de nouveaux fichiers de définition de navigateur:

  • blackberry.browser
  • chrome.browser
  • Default.browser
  • firefox.browser
  • gateway.browser
  • generic.browser
  • ie.browser
  • iemobile.browser
  • iphone.browser
  • opera.browser
  • safari.browser

 

Utilisation des Providers de Browser Capabilities

Depuis le Service Pack 1 d’ASP.NET 3.5, il est possible définir soi-même les capacités d'un navigateur. En effet, pour une modification appliquée à un serveur Web complet (donc touchant toutes les applications ASP.NET hébergées sur celui-ci), on peut créer ou mettre à jour un fichier .browser dans le dossier du Framework :

%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\CONFIG\Browsers

Après modification du fichier la commande suivante, via le prompt de commande Visual Studio, permet de rebuilder l’assembly des Browser Capabilities et de l’ajouter dans le GAC :

aspnet_regbrowsers.exe -I c 

Pour mettre à jour les Browser Capabilities pour un navigateur donné et pour une seule application ASP.NET, on peut créer un fichier .browser dans le dossier App_Browsers de l’application. Pour une explication plus détaillée du contenu de ces fichiers, vous pouvez consulter cet article MSDN.

Cette approche nécessite donc de modifier des fichiers, est fortement source d’erreur. Dans la pratique, peu de développeurs définissent des Browser Capabilities customisés et c’est normal. Les fichiers .browser sont difficiles à mettre à jour, la syntaxe XML peut être complexe à utiliser, et pour être prises en compte les modifications peuvent nécessiter un redémarrage du serveur Web.

Ce qui rendrait le processus plus aisé serait d’avoir une syntaxe commune pour tous les navigateurs, ou de pouvoir stocker ces définitions de Browser Capabilities ailleurs que dans un fichier. Imaginez un Web Service qui vous propose la dernière version des capacités pour un navigateur, ces définitions étant stockées sur SQL Azure par exemple (ou dans une base de données locale) et mises à jour quotidiennement. La donne a changée avec la sortie d’ASP.NET 4.0, cette version inclut une nouvelle fonctionnalité : le Provider de Browser Capabilities. Comme son nom le suggère, ce Provider va nous permettre d'utiliser notre propre code pour déterminer les capacités du navigateur (voire utiliser un futur système de Content Delivery Netwok pour les Browser Capabilities, à l’instar du Windows Azure CDN, ou des CDN pour les bibliothèques Javascript et JQuery).

Il existe deux approches principales pour l'utilisation de ces Providers : étendre les Browser Capabilities d’un navigateur, ou les remplacer totalement.

 

Remplacement des Browser Capabilities

Pour remplacer les Browser Capabilities d’un navigateur, il suffit de créer Provider personnalisé qui hérite de la classe HttpCapabilitiesProvider :

public class MonProvider : HttpCapabilitiesProvider 
{
public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
{
HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities();
Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase);
values[String.Empty] = request.UserAgent;
values["browser"] = "MonNavigateur";
browserCaps.Capabilities = values;
return browserCaps;
}
}


Ce code permet de créer un nouveau Provider de Browser Capabilities et de l’associer au navigateur nommé “MonNavigateur”. Pour pouvoir l’utiliser, il faut le référencer dans notre application. Pour ce faire, une petite modification dans notre fichier Web.config (voire Machine.config si besoin est) :

<system.web> 
<browserCaps provider="ApplicationBidon.MonProvider, ApplicationBidon, Version=1.0.0.0, Culture=neutral" />
</system.web>


Bien entendu, nous avons la possibilité de l’enregistrer dynamiquement au chargement de l’application Web dans le Global.asax, comme dans le code ci-dessous :

void Application_Start(object sender, EventArgs e) 
{
HttpCapabilitiesBase.BrowserCapabilitiesProvider = new ApplicationBidon.MonProvider();
// ...
}

Toutefois, gardez en tête que tout changement dans la classe BrowserCapabilitiesProvider doit intervenir au démarrage de l’application, avant l’exécution de n’importe quel code. Ceci, afin d’être sûr que le cache contienne un état valide pour l’objet pour traiter les requêtes HTTP.

 

Mise en cache des objets HttpBrowserCapabilities

L'exemple précédent a un problème : le code est exécuté à chaque fois que le Provider customisé est invoqué pour obtenir l’objet HttpBrowserCapabilities. De plus, cela peut se produire plusieurs fois au cours d’une même requête. Evidemment, dans le simple exemple précédent, notre Provider nommé MonProvider ne fait pas grand chose. Cependant, s’il devait réaliser un travail plus important, l’impact sur les performances se ferait sentir. Pour éviter cela, nous pouvons mettre en cache les objets HttpBrowserCapabilities :

public class MonProvider : HttpCapabilitiesProvider 
{
public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
{
string cacheKey = BuildCacheKey();
int cacheTime = GetCacheTime();
HttpBrowserCapabilities browserCaps = HttpContext.Current.Cache[cacheKey] as HttpBrowserCapabilities;

if (browserCaps == null)
{
HttpBrowserCapabilities browserCaps = new HttpBrowserCapabilities();
Hashtable values = new Hashtable(180, StringComparer.OrdinalIgnoreCase);
values[String.Empty] = request.UserAgent;
values["browser"] = "MonBrowser";
browserCaps.Capabilities = values;
HttpContext.Current.Cache.Insert(cacheKey, browserCaps, null, DateTime.MaxValue, TimeSpan.FromSeconds(cacheTime));
}

return browserCaps;
}
}

Dans l’exemple ci-dessus, le code génère une clé de cache et y ajoute l’objet HttpBrowserCapabilities. Celui-ci peut ensuite être récupéré du cache et utilisé dans les multiples requêtes qui utiliseront le Provider MonProvider.

 

Etendre les Browser Capabilities ASP.NET

Le paragraphe précédent décrit comment créer un nouvel objet HttpBrowserCapabilities en ASP.NET 4.0. Le Provider MonProvider correspond en fait au Browser MonBrowser. Nous allons voir maintenant comment étendre à la volée les définitions des navigateurs déjà définis en ASP.NET. Je vous vois venir avec une remarque du style “oui, mais il va falloir mettre les mains dans le cambouis et trafiquer les fichiers .browser XML”. Et bien rassurez-vous : non. Un exemple sera plus parlant :

public class MonProvider : HttpCapabilitiesEvaluator 
{
public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
{
HttpBrowserCapabilities browserCaps = base.GetHttpBrowserCapabilities(request);
if (browserCaps.Browser == "Unknown")
browserCaps = MonBrowserCapabilitiesEvaluator(request);

return browserCaps;
}
}

Dans le code, la fonction GetBrowserCapabilities va tenter d’identifier le browser de la requête. Si toutefois aucun browser n’est identifié, alors nous utilisons notre propre provider nommé MonBrowserCapabilitiesEvaluator pour identifier le browser de la requête.

 

Ajout de fonctionnalités à un Browser Capabilities existant

L’exemple ci-dessous permet de rajouter la capacité MultiTouch à un Browser existant. Le principe est simple on ajoute au à l’object browserCaps.Capabilities, qui implémente IDictionary, une nouvelle paire clé/valeur :

public class MonProvider : HttpCapabilitiesEvaluator
{
public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
{
HttpBrowserCapabilities browserCaps = base.GetHttpBrowserCapabilities(request);
browserCaps.Frames = true;
browserCaps.Capabilities["MultiTouch"] = "true";
return browserCaps;
}
}

Grâce aux nouvelles fonctionnalités apparues en ASP.NET 4.0, nous pouvons maintenant modifier facilement les Browser Capabilities d’un navigateur. Nous pouvons aussi gérer à notre manière et selon nos besoins l’identification d’un navigateur. Mais aussi, pour aller plus loin, ces nouveautés nous permettent de stocker et partager nos définitions des capacités d’un navigateur.

Tags: , , , ,

Commentaires

1.
pingback topsy.com says:

Pingback from topsy.com

Twitter Trackbacks for
        
        [ASP.NET 4.0] Nouveautés pour la détection et gestion des navigateurs internet – Partie 2
        [nicolasesprit.com]
        on Topsy.com

Les commentaires sont clos