Ma question est similaire à ceci:
Sauf que je veux m'en tenir au propre groupement de MVC si je le peux. J'ai un crash cérébral essayant de comprendre quel est le modèle correct pour spécifier des ensembles de styles tels que les ensembles d'images et de CSS autonomes tels que l'interface utilisateur jQuery.
J'ai une structure de site MVC typique avec /Content/css/
laquelle contient mon CSS de base tel que styles.css
. Dans ce dossier CSS, j'ai également des sous-dossiers tels que celui /jquery-ui
qui contient son fichier CSS plus un /images
dossier. Les chemins des images dans jQuery UI CSS sont relatifs à ce dossier et je ne veux pas les déranger.
Si je comprends bien, lorsque je spécifie un, StyleBundle
je dois spécifier un chemin virtuel qui ne correspond pas également à un vrai chemin de contenu, car (en supposant que j'ignore les routes vers le contenu) IIS essaierait alors de résoudre ce chemin en tant que fichier physique. Je précise donc:
bundles.Add(new StyleBundle("~/Content/styles/jquery-ui")
.Include("~/Content/css/jquery-ui/*.css"));
rendu en utilisant:
@Styles.Render("~/Content/styles/jquery-ui")
Je peux voir la demande envoyée à:
http://localhost/MySite/Content/styles/jquery-ui?v=nL_6HPFtzoqrts9nwrtjq0VQFYnhMjY5EopXsK8cxmg1
Cela renvoie la réponse CSS correcte et réduite. Mais alors le navigateur envoie une demande pour une image relativement liée comme:
http://localhost/MySite/Content/styles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
Qui est un 404
.
Je comprends que la dernière partie de mon URL jquery-ui
est une URL sans extension, un gestionnaire pour mon bundle, donc je peux voir pourquoi la demande relative pour l'image est simplement/styles/images/
.
Donc ma question est quelle est la bonne façon de gérer cette situation?
la source
Réponses:
Selon ce fil sur le regroupement css MVC4 et les références d'image , si vous définissez votre bundle comme:
Lorsque vous définissez le regroupement sur le même chemin que les fichiers source qui ont constitué le regroupement, les chemins d'accès relatifs à l'image continueront de fonctionner. La dernière partie du chemin du bundle est vraiment celle
file name
de ce bundle spécifique (c'est-à-dire,/bundle
peut être n'importe quel nom que vous aimez).Cela ne fonctionnera que si vous regroupez des CSS à partir du même dossier (ce qui, je pense, est logique du point de vue du regroupement).
Mettre à jour
Selon le commentaire ci-dessous de @Hao Kung, cela peut désormais être réalisé en appliquant un
CssRewriteUrlTransformation
( Modifier les références d'URL relatives aux fichiers CSS lorsqu'ils sont regroupés ).REMARQUE: je n'ai pas confirmé les commentaires concernant les problèmes de réécriture vers des chemins absolus dans un répertoire virtuel, donc cela peut ne pas fonctionner pour tout le monde (?).
la source
La solution Grinn / ThePirat fonctionne bien.
Je n'aimais pas le fait qu'elle ait créé la méthode Include sur le bundle et qu'elle ait créé des fichiers temporaires dans le répertoire de contenu. (ils ont fini par être enregistrés, déployés, alors le service ne démarre pas!)
Donc, pour suivre la conception de Bundling, j'ai choisi de réaliser essentiellement le même code, mais dans une implémentation IBundleTransform ::
Et puis enveloppé cela dans une implémentation de bundle:
Exemple d'utilisation:
Voici ma méthode d'extension pour RelativeFromAbsolutePath:
la source
relativeToCSS
avant d'appelerPath.GetFullPath()
.Mieux encore (à mon humble avis) implémentez un bundle personnalisé qui corrige les chemins d'image. J'en ai écrit un pour mon application.
...
Pour l'utiliser, faites:
...au lieu de...
Ce qu'il fait est (lorsqu'il n'est pas en mode débogage) le recherche
url(<something>)
et le remplace parurl(<absolute\path\to\something>)
. J'ai écrit la chose il y a environ 10 secondes, donc elle pourrait avoir besoin d'un petit ajustement. J'ai pris en compte les URL pleinement qualifiées et les DataURI base64 en m'assurant qu'il n'y a pas de deux-points (:) dans le chemin de l'URL. Dans notre environnement, les images résident normalement dans le même dossier que leurs fichiers css, mais je l'ai testé avec les dossiers parents (url(../someFile.png)
) et les dossiers enfants (url(someFolder/someFile.png
).la source
Il n'est pas nécessaire de spécifier une transformation ou d'avoir des chemins de sous-répertoire fous. Après beaucoup de dépannage, je l'ai isolé à cette règle "simple" (est-ce un bug?) ...
Si le chemin de votre ensemble ne commence pas par la racine relative des éléments inclus, la racine de l'application Web ne sera pas prise en compte.
Cela ressemble plus à un bug pour moi, mais de toute façon c'est comme ça que vous le corrigez avec la version actuelle de .NET 4.51. Peut-être que les autres réponses étaient nécessaires sur les anciennes versions d'ASP.NET, je ne peux pas dire que je n'ai pas le temps de tester rétrospectivement tout cela.
Pour clarifier, voici un exemple:
J'ai ces fichiers ...
Ensuite, configurez le bundle comme ...
Et le rendre comme ...
Et obtenez le "comportement" (bug), les fichiers CSS eux-mêmes ont la racine de l'application (par exemple "http: // localhost: 1234 / MySite / Content / Site.css") mais l'image CSS dans tous les start "/ Content / Images / ... "ou" / Images / ... "selon que j'ajoute ou non la transformation.
J'ai même essayé de créer le dossier "Bundles" pour voir s'il s'agissait du chemin existant ou non, mais cela n'a rien changé. La solution au problème est vraiment l'exigence que le nom du bundle commence par la racine du chemin.
Ce qui signifie que cet exemple est corrigé en enregistrant et en rendant le chemin du bundle comme ..
Donc, bien sûr, vous pouvez dire que c'est RTFM, mais je suis sûr que moi et d'autres avons choisi ce chemin "~ / Bundles / ..." à partir du modèle par défaut ou quelque part dans la documentation sur le site Web MSDN ou ASP.NET, ou je suis juste tombé dessus parce qu'en fait, c'est un nom assez logique pour un chemin virtuel et il est logique de choisir de tels chemins virtuels qui n'entrent pas en conflit avec de vrais répertoires.
Quoi qu'il en soit, c'est comme ça. Microsoft ne voit aucun bogue. Je ne suis pas d'accord avec cela, soit cela devrait fonctionner comme prévu, soit une exception devrait être levée, ou un remplacement supplémentaire pour ajouter le chemin du bundle qui opte pour inclure la racine de l'application ou non. Je ne peux pas imaginer pourquoi quelqu'un ne voudrait pas que la racine de l'application soit incluse quand il y en a une (normalement sauf si vous avez installé votre site Web avec un alias DNS / racine de site Web par défaut). Donc, en fait, cela devrait être la valeur par défaut.
la source
J'ai trouvé que CssRewriteUrlTransform ne s'exécute pas si vous faites référence à un
*.css
fichier et que vous avez le*.min.css
fichier associé dans le même dossier.Pour résoudre ce problème, supprimez le
*.min.css
fichier ou référencez-le directement dans votre bundle:Après cela, vos URL seront transformées correctement et vos images devraient être correctement résolues.
la source
Peut-être que je suis biaisé, mais j'aime bien ma solution car elle ne fait aucune transformation, regex, etc. et elle a le moins de code :)
Cela fonctionne pour un site hébergé en tant que répertoire virtuel dans un site Web IIS et en tant que site Web racine sur IIS
J'ai donc créé une implantation d'
IItemTransform
encapsulé leCssRewriteUrlTransform
et utiliséVirtualPathUtility
pour fixer le chemin d'accès et appeler le code existant:Semble bien fonctionner pour moi?
la source
Bien que la réponse de Chris Baxter aide à résoudre le problème d'origine, cela ne fonctionne pas dans mon cas lorsque l'application est hébergée dans un répertoire virtuel . Après avoir étudié les options, j'ai terminé avec une solution de bricolage.
ProperStyleBundle
La classe inclut du code emprunté à l'originalCssRewriteUrlTransform
pour transformer correctement les chemins relatifs dans le répertoire virtuel. Il lance également si le fichier n'existe pas et empêche la réorganisation des fichiers dans le bundle (code extrait deBetterStyleBundle
).Utilisez-le comme
StyleBundle
:la source
Depuis la v1.1.0-alpha1 (package de pré-version), le framework utilise le
VirtualPathProvider
pour accéder aux fichiers plutôt que de toucher le système de fichiers physique.Le transformateur mis à jour peut être vu ci-dessous:
la source
Voici une transformation d'ensemble qui remplacera les URL css par des URL relatives à ce fichier css. Ajoutez-le simplement à votre ensemble et cela devrait résoudre le problème.
la source
cannot convert type from BundleFile to FileInfo
Une autre option consisterait à utiliser le module de réécriture d'URL IIS pour mapper le dossier d'images d'ensemble virtuel au dossier d'images physiques. Vous trouverez ci-dessous un exemple de règle de réécriture que vous pourriez utiliser pour un ensemble appelé "~ / ensembles / votre page / styles" - notez les correspondances d'expression régulière sur les caractères alphanumériques ainsi que les traits d'union, les traits de soulignement et les points, qui sont courants dans les noms de fichiers image .
Cette approche crée un petit surcoût supplémentaire, mais vous permet d'avoir plus de contrôle sur les noms de vos bundles, et réduit également le nombre de bundles que vous devrez peut-être référencer sur une page. Bien sûr, si vous devez référencer plusieurs fichiers css tiers contenant des références de chemin d'image relatives, vous ne pouvez toujours pas contourner la création de plusieurs ensembles.
la source
La solution Grinn est excellente.
Cependant, cela ne fonctionne pas pour moi lorsqu'il y a des références relatives au dossier parent dans l'URL. c'est à dire
url('../../images/car.png')
J'ai donc légèrement modifié la
Include
méthode afin de résoudre les chemins pour chaque correspondance d'expressions régulières, en permettant des chemins relatifs et en option pour intégrer les images dans le CSS.J'ai également changé l'IF DEBUG pour vérifier
BundleTable.EnableOptimizations
au lieu deHttpContext.Current.IsDebuggingEnabled
.J'espère que ça aide, salut.
la source
Vous pouvez simplement ajouter un autre niveau de profondeur à votre chemin de bundle virtuel
C'est une réponse super low-tech et une sorte de hack mais cela fonctionne et ne nécessitera aucun prétraitement. Étant donné la longueur et la complexité de certaines de ces réponses, je préfère le faire de cette façon.
la source
J'ai eu ce problème avec des bundles ayant un chemin d'accès aux images incorrect et
CssRewriteUrlTransform
ne résolvant pas..
correctement les chemins parent relatifs (il y avait aussi un problème avec les ressources externes comme les polices Web). C'est pourquoi j'ai écrit cette transformation personnalisée (semble faire tout ce qui précède correctement):Edit: je ne l'ai pas réalisé, mais j'ai utilisé des méthodes d'extension personnalisées dans le code. Le code source de ceux-ci est:
Bien sûr, il devrait être possible de le remplacer
String.StartsWith(char)
parString.StartsWith(string)
.la source
m.Groups[2].Value.Count("..")
ne fonctionne pas.) EtValue.StartsWith('/')
ne fonctionne pas non plus car StartsWith attend une chaîne au lieu d'un caractère.Après une petite enquête, j'ai conclu ce qui suit: Vous avez 2 options:
aller avec des transformations. Package très utile pour cela: https://bundletransformer.codeplex.com/ vous avez besoin de la transformation suivante pour chaque bundle problématique:
Avantages: de cette solution, vous pouvez nommer votre bundle comme vous le souhaitez => vous pouvez combiner des fichiers css en un seul bundle à partir de répertoires différents. Inconvénients: vous devez transformer chaque bundle problématique
la source
CssRewriteUrlTransform
résolu mon problème.Si votre code ne charge toujours pas les images après utilisation
CssRewriteUrlTransform
, changez le nom de votre fichier CSS à partir de:À:
D'une certaine manière. (Les points) ne reconnaissent pas dans l'url.
la source
N'oubliez pas de corriger plusieurs inclusions CSS dans un ensemble, telles que:
Vous ne pouvez pas simplement ajouter
new CssRewriteUrlTransform()
à la fin comme vous pouvez le faire avec un fichier CSS car la méthode ne le prend pas en charge, vous devez donc utiliserInclude
plusieurs fois :la source