[MVC] Corriger les liens CSS relatifs dans un StyleBundle

Récemment, pour un nouveau projet en MVC 5, nous avons utilisé Bootstrap et jQuery DataTables.

Afin de mieux s’intégrer à « l’esprit » Boostrap, DataTables intègre un fichier JavaScript (dataTables.bootstrap.js) et un fichier CSS (dataTables.bootstrap.css).

Nous avions décidé d’ajouter ce fichier CSS à un StyleBundle dans BundleConfig.RegisterBundles :

bundles.Add(new StyleBundle("~/Content/bootstrap-datatable").Include(
            "~/Content/DataTables-1.10.0/css/dataTables.bootstrap.css"));

En local tout fonctionnait correctement, mais une fois sur le serveur d’intégration, les images de tri de DataTables n’apparaissaient pas. En regardant avec l’outil de développeur de Chrome, on peut voir que nous avions des erreurs 404 sur nos images :

Failed to load resource: the server responded with a status of 404 (Not Found) http://xxx/images/sort_desc.png

Après analyses, nous avons détecté que dataTables.bootstrap.css spécifie des chemins relatifs pour ses images :

table.table thead .sorting { backgroundurl('../images/sort_both.png') no-repeat center right; }
table.table thead .sorting_asc { backgroundurl('../images/sort_asc.png') no-repeat center right; }
table.table thead .sorting_desc { backgroundurl('../images/sort_desc.png') no-repeat center right; }

Le navigateur Web recherche donc les images en relatif par rapport au chemin de notre Bundle (~/Content/boostrap-datatable) et non pas en fonction du chemin relatif du fichier css (~/Content/DataTables-1.10.0/css/dataTables.boostrap.css).

Pour régler ce problème, la solution est très simple : il suffit de passer un IItemTransform à votre StyleBundle, et plus spécifiquement, le CssRewriteUrlTransform qui réécrit automatiquement les URLs des fichiers CSS inclus dans le StyleBundle.
Il vous suffit juste d’ajouter le CssRewriteUrlTransform à votre Include:

bundles.Add(new StyleBundle("~/Content/bootstrap-datatable").Include(
  "~/Content/DataTables-1.10.0/css/dataTables.bootstrap.css"new CssRewriteUrlTransform()));

A présent, nos images ont réapparu, et nous n’avons plus d’erreur 404. En analysant le CSS généré avec Chrome, on peut voir que les URLs du bundle ont été réécrites en fonction du chemin du fichier CSS :

table.table thead .sorting_desc {
    backgroundurl(/Content/DataTables-1.10.0/images/sort_desc.png) no-repeat center right;
}

Edit du 1er octobre 2014 :

Si vous utilisez une application dans un virtual directory (autre que dans la racine /), cette solution ne fonctionne pas. En effet, il n’ajoute pas le préfixe de l’application.

Dans ce cas, vous devez créer votre propre IItemTransform tout en utilisant CssRewriteUrlTransform auquel vous fournissez le chemin corrigé :

public class CssRewriteUrlTransformWrapper : IItemTransform
{
    public string Process(string includedVirtualPath, string input)
    {
        return new CssRewriteUrlTransform().Process("~" + VirtualPathUtility.ToAbsolute(includedVirtualPath), input);
    }
}

Source : http://aspnetoptimization.codeplex.com/workitem/83

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s