Dans ma boîte à outils : Fingerprint pour versionner les ressources statiques

Un aspect primordial du développement est la mise en cache des ressources statiques qui sont utilisées par votre application web. De nos jours, cette pratique devient essentielle en raison du poids sans cesse augmenté des applications web. Il est donc essentiel d’évaluer ce qu’est un contenu dynamique et ce qui peut être mis en stockage permanent côté client.

Des applications plus lourdes à exécuter et des librairies CSS et JavaScript qui font de l’obésité. C’est un peu cela le web moderne.

À petite échelle, l’effort de s’assurer qu’un navigateur télécharge qu’une seule fois un fichier afin d’éviter de le réutiliser à travers vos différentes visites peut sembler exagéré. Cependant, lorsque votre application a un peu d’affluence, l’idée du caching a beaucoup de sens. Si vous payez pour votre bande passante, vous apprécierez tous les kilobits économisés.

Dans le même genre d’économies d’échelle, chaque requête que votre serveur web n’a pas à faire c’est des cycles de CPU qui peuvent être utilisés à faire d’autres traitements ou même vous permettre d’utiliser un serveur de plus petite capacité pour vos besoins. Considérant les coûts de certains hébergements dans le cloud, ce n’est pas si bête comme idée.

Mise en cache

Avec IIS (et les autres serveurs web), tout commence par l’activation de la cache des contenus statiques dans la configuration de votre application. Cela aura pour effet d’envoyer l’instruction aux navigateurs web n’éviter de télécharger inutilement les éléments image, CSS et JavaScript.

À ceci, j’ajouterais qu’en réalité, la configuration de la mise en cache des contenus est un peu plus complexe que cela. Ce que j’ai affirmé au paragraphe précédent va fonctionner pour une majorité de cas. Il s’agit uniquement d’une recette de base. Par exemple, il faut savoir quand et comment utiliser le etag, connaitre les différences entre les entêtes cache-control et expires.

Le web, c’est compliqué quand on s’attarde aux détails!

Fingerprint

Une fois que votre contenu est mis en cache pour les jours ou même les semaines à venir, que faire si vous venez de mettre à jour une partie de ceux-ci et désirez vous assurer qu’ils sont téléchargés par vos visiteurs?

Le meilleur et le plus simple mécanisme que je connaisse est d’introduire un paramètre d’URL indiquant un identifiant de version à vos fichiers statiques. Cet identifiant doit être incrémenté à chaque nouvelle révision de vos fichiers afin que le navigateur le télécharge à nouveau lorsqu’il sera modifié.

Ce que j’utilise depuis déjà un bon moment est l’utilitaire développé par Mads Kristensen nommé Fingerprint. Ce que cette classe fait est très simple. Elle permet la création d’URL convertissant la date de modification des fichiers désirés en un identifiant de version unique. Par exemple, la ressource /content/site.css devient /content/v-634933238684083941/site.css.

Cool, n’est-ce pas? En plus, c’est super simple à utiliser. Avec ASP.NET MVC, il suffit d’invoquer la classe Fingerprint de cette façon pour obtenir l’URL @Fingerprint.Tag(« /content/site.css »). Magie, magie.

La dernière chose à mentionner est l’ajout de cet élément de configuration dans votre web.config.

<rewrite>
  <rules>
    <rule name="fingerprint">
      <match url="([\S]+)(/v-[0-9]+/)([\S]+)" />
      <action type="Rewrite" url="{R:1}/{R:3}" />
    </rule>
  </rules>
</rewrite>

Parlant d’URL Rewrite, la seule vraie mise en garde est la configuration sur vos environnements de développement et de production. Fingerprint requiert l’installation de l’extension URL Rewrite sur vos serveurs IIS. Donc, si vous allez de l’avant avec ceci (je vous le conseille fortement), installez URL Rewrite avant tout. Sinon, votre site web sera simplement kaput à son démarrage.

Les liens de la semaine – Édition #193

Développement

.NET

Web

Technologie

Science et autres

 

 

Internationalisation de la validation de vos données de formulaire avec ASP.NET MVC et jQuery.Globalize

Laissez-moi vous dire, s’il y a quelque chose qui pue avec ASP.NET MVC et bien l’état des outils de validation de données client-side. C’est simple. Dans un contexte multilingue, la seule chose qui fonctionne est l’intégration de la logique de validation à la librairie jQuery.Validate.

Tous ceux qui auront à valider des données dans un formulaire avec données numériques ou des dates pouvant avoir un format variant selon la culture m’en reparleront.

Vous voulez un exemple? Considérez la propriété suivante.


[Required]
[Range(Min=0, Max=int.MaxValue)
public decimal Salary { get; set; }

view raw

decimal.cs

hosted with ❤ by GitHub

Avec ASP.NET MVC, une propriété avec ces deux attributs de validation va faire en sorte de s’assurer que la saisie soit obligatoire et que le nombre soit compris entre 0 et int.MaxValue. En théorie, ça fonctionne bien. En particulier lorsqu’on fait uniquement affaire avec des formats anglais (ex.: en-US, en-CA, ca, etc.).

Dans une vue MVC, le code Salary.ToString(« n ») prendra la forme « 10 00,12 » avec la culture « fr ». Tandis qu’elle prendra la forme « 10,000.12 » avec la culture « en ». Une image vaut mille mots. Allez voir l’exemple sur csharppad que j’ai monté pour l’occasion.

Le problème est lié au fait que, avant d’exécuter les validations sur vos données, la librairie de validation utilisée par ASP.NET MVC va faire en sorte de s’assurer que votre donnée est du bon type. Dans notre cas en particulier, elle va s’assurer que la valeur soit une valeur décimale.

J’ai une question quiz pour vous. Comment la librairie fait-elle pour cette validation? En utilisant ce regex^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$. Allez vous amuser avec celle-ci. Sommairement, ce regex fait en sorte que 10,000.12 va valider correctement, mais pas 10 000,12.

Déprimant, n’est-ce pas? J’ai fait face à cette conclusion-là moi aussi.

À partir de ceci, quelles sont les possibilités afin d’être en mesure de faire une validation côté client?

  1. Faire des validations côté serveur. Principalement en mettant en place une logique impliquant decimal.TryParse et ModelState.
  2. Forcer les données dans un format de culture « en ».
  3. Trouver une façon de faire de la validation multiculturelle côté client avec une librairie JavaScript qui a du sens.

Valider des données en utilisant jQuery.Globalize

La bonne nouvelle dans tout ça c’est que la librairie jQuery.Validation est facile à bonifier en fonctionnalités. Cela signifie qu’il est possible d’aller modifier les règles de validations pour les différents scénarios requis. Dans mon cas, en plus des formats de nombres, je dois aussi valider des dates.

S’il y a bien de quoi qui est chiant à valider, ces dates. L’ironie est que la majorité des guides que vous allez trouver sur le web proposent de le faire par l’intermédiaire d’un regex. Dans un contexte multilingue, il s’agit d’une très mauvaise approche.

Une bonne pratique est de passer par l’utilisation de la librairie jquery.Globalize. Cette librairie propose un API permettant de manipuler ou générer des informations étant soumises à un formatage selon la langue. Par exemple, Globalize.parseDate permet de parser une chaîne de texte contenant une date.

La force de jquery.Globalize réside sous le fait que les règles d’analyse et de formatage de données est régi par le CLDR (Unicode Common Locale Data Repository). Avec le CLDR, tout ce qui peut varier selon la langue y est défini. Le bonheur dans tout ça est que les fichiers de définition sont disponibles librement sur GitHub en format JSON.

Faire fonctionner jQuery.Globalize sur son projet web peut être un peu déconcertant à première vue. Les instructions contiennent beaucoup trop d’informations. Résumons ainsi:

  • Exécutez la commande suivante: npm install globalize cldr-data et attendez un peu (Globalize sera sous node_modules\globalize\dist et CLDR sous node_modules\cldr-data).
  • Visitez ce site web et sélectionnez les fonctionnalités que vous désirez intégrer à votre site.

Ce dernier site web vous donnera la liste des fichiers JavaScript et JSON par langue à intégrer sur votre site web. C’est l’outil essentiel pour se donner un petit coup de main pour mettre en place correctement jQuery.Globalize.

Par la suite, c’est assez simple si vous vous référez au gist suivant :


$.when(
$.get( "cldr/main/en/ca-gregorian.json" ),
$.get( "cldr/main/fr/ca-gregorian.json" ),
$.get( "cldr/supplemental/likelySubtags.json" ),
$.get( "cldr/supplemental/timeData.json" ),
$.get( "cldr/supplemental/weekData.json" )
).then(function() {
return [].slice.apply( arguments, [ 0 ] ).map(function( result ) {
return result[ 0 ];
});
}).then( Globalize.load );
//Instantier jQuery.Globalize dans une culture
Globalize("en") //Cette culture peut être fournie par votre backend MVC, par exemple System.Threading.Thread.CurrentThread.CurrentCulture
//L'initialisation des règles peronnalisées pour jQuery.Validate se fait ici.
$.validator.methods.date = function (value, element) {
return this.optional(element) || Globalize.parseDate(value);
};

Il s’agit du minimum de JavaScript à inclure dans votre application pour inclure jQuery.Globalize et pour réimplémenter la règle de validation « date » de jQuery.Validate. Il s’agit d’un minimum. Vous allez devoir aussi implémenter d’autres règles selon votre scénario. Il y a notamment « number » et « range » qui vous seront utiles.

J’espère que ce petit guide vous sera utile comme il me l’a été. Vous pouvez maintenant valider des données comme un pro!

Lecteurs français: en ce jour de fête nationale française, je vous souhaite de passer une très belle journée! 20px-Flag_of_France.svg[1]

Les liens de la semaine – Édition #192

Développement

.NET

Technologie

Web

Science et autres

Les liens de la semaine – Édition #191

Développement

.NET

Technologie

Web