MVC4 StyleBundle pas la résolution des images
Ma question est similaire à ceci:
Sauf que je veux coller avec MVC propre groupement, si je peux. Je vais avoir un cerveau crash à essayer de comprendre ce que le modèle correct est de spécifier le style de faisceaux tels que autonome css et de l'image fixe telle que jQuery UI travail.
J'ai un typique MVC de la structure du site avec /Content/css/
qui contient ma base de CSS comme styles.css
. Au sein de ce répertoire css j'ai aussi des sous-dossiers tels que /jquery-ui
qui contient son fichier CSS en plus d'un /images
dossier. Les chemins des images dans l'INTERFACE utilisateur de jQuery CSS sont relatifs à ce dossier et je ne veux pas mess avec eux.
Comme je le comprends, quand je spécifier un StyleBundle
j'ai besoin de spécifier un chemin d'accès virtuel qui n'est pas aussi correspondre à un véritable chemin de contenu, parce que (en supposant que je suis ignorant les routes de Contenu) IIS seraient alors tenter de résoudre ce chemin comme un fichier physique. Donc, je suis en précisant:
bundles.Add(new StyleBundle("~/Content/styles/jquery-ui")
.Include("~/Content/css/jquery-ui/*.css"));
rendus à l'aide de:
@Styles.Render("~/Content/styles/jquery-ui")
Je peut voir la demande de sortir:
http://localhost/MySite/Content/styles/jquery-ui?v=nL_6HPFtzoqrts9nwrtjq0VQFYnhMjY5EopXsK8cxmg1
C'est le retour de la corriger, minifiés CSS réponse.
Mais ensuite, le navigateur envoie une requête pour un relativement lié image:
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 un extensionless URL, un gestionnaire pour mon paquet, donc je peux voir pourquoi la demande relative de l'image est tout simplement /styles/images/
.
Donc ma question est quelle est la bonne façon de gestion de cette situation?
- après avoir été frustré encore et encore avec le nouveau Regroupement et la Minification partie, j'ai déménagé sur Cassete la sorcière est maintenant gratuit et fonctionne bien mieux!
- Merci pour le lien, Cassette a l'air sympa et je vais certainement le vérifier. Mais je veux coller avec l'approche si possible, il est sûr que cela doit être possible sans jouer avec les chemins des images dans la 3ème partie CSS fichiers chaque fois qu'une nouvelle version est disponible. pour l'instant j'ai gardé mon ScriptBundles (qui fonctionne bien), mais est revenue à la plaine des liens de CSS jusqu'à ce que je obtenir une résolution. Des acclamations.
- L'ajout de l'erreur possible pour des raisons SEO: Le contrôleur pour le chemin '/bundles/images/blah.jpg " n'a pas été trouvé ou n'est pas de mettre en œuvre IController.
Vous devez vous connecter pour publier un commentaire.
En fonction de ce fil de discussion sur MVC4 css regroupement et de références sur l'image, si vous définissez votre bundle:
Où vous définissez l'ensemble sur le même chemin que les fichiers source qui ont fait le bundle, la relative chemins d'image fonctionne toujours. La dernière partie de l'ensemble du chemin est vraiment le
file name
pour que le bundle spécifique (c'est à dire,/bundle
peut être n'importe quel nom que vous voulez).Cela ne fonctionnera que si vous êtes regroupant CSS à partir du même dossier (qui je pense a un sens d'un regroupement point de vue).
Mise à jour
Que par le commentaire ci-dessous par @Hao Kung, sinon cela peut maintenant être obtenue par l'application d'un
CssRewriteUrlTransformation
(Changement d'URL relative des références à des fichiers CSS lors de livré).NOTE: je n'ai pas confirmé les commentaires en rapport avec la réécriture des chemins absolus dans un répertoire virtuel, de sorte que cela peut ne pas fonctionner pour tout le monde (?).
Grinn /ThePirat solution fonctionne bien.
Je n'aimais pas qu'il nouveau, la méthode include sur bundle, et qu'il a créé les fichiers temporaires dans le répertoire de contenu. (ils ont fini de se faire contrôler en, déployé, le service ne démarre pas!)
Afin de suivre la conception de la vente Groupée, j'ai choisi d'effectuer essentiellement le même code, mais dans un IBundleTransform mise en œuvre::
Et puis enroulé dans un Bundle mise en œuvre:
Exemple D'Utilisation:
Voici ma méthode d'extension pour RelativeFromAbsolutePath:
relativeToCSS
avant d'appelerPath.GetFullPath()
.Encore mieux (à mon humble avis) de mettre en œuvre un lot personnalisé qui résout les chemins de l'image. J'ai écrit pour mon application.
...
Pour l'utiliser, faire:
...au lieu de...
Ce qu'il fait est (lorsqu'il n'est pas en mode debug) recherche
url(<something>)
et le remplace parurl(<absolute\path\to\something>)
. J'ai écrit la chose à propos de 10 secondes il y a donc peut-être besoin d'un peu de peaufinage. J'ai pris en compte pleinement qualifié Url et base64 DataURIs en vous assurant que il n'y a pas de deux-points (:) dans le chemin de l'URL. Dans notre environnement, des images normalement se trouver dans le même dossier que leurs fichiers css, mais je l'ai testé avec les deux dossiers parents (url(../someFile.png)
) et les dossiers enfant (url(someFolder/someFile.png
).Il n'est pas nécessaire de spécifier une transformation ou un fou sous-répertoire chemins. Après beaucoup de dépannage j'ai isolé à cette "simple" règle (est-ce un bug?)...
Si votre bundle chemin ne commence pas avec un parent de la racine des éléments inclus, alors la racine de l'application web ne seront pas prises en compte.
Ressemble plus à un bug pour moi, mais de toute façon c'est comment vous fixer avec le courant .NET version 4.51. Peut-être d'autres réponses ont été nécessaires sur les anciens ASP.NET construit, ne peut pas dire, n'ont pas le temps de façon rétrospective tester tout ça.
Pour clarifier, voici un exemple:
J'ai ces fichiers...
Puis l'installation du bundle comme...
Et de rendu... comme
Et obtenir le "comportement" (bug), les fichiers CSS, eux-mêmes ont de la racine de l'application (par exemple, "http://localhost:1234/MySite/Content/Site.css") mais le CSS de l'image dans toutes les start "/Content/Images/..." ou "/Images/..." selon si j'ai ajouter la transformation ou non.
Même essayé de créer les "Bundles" dossier pour voir si elle a à voir avec le chemin d'accès existant ou pas, mais cela n'a rien changé. La solution à ce problème est vraiment la condition que le nom du bundle doit commencer avec le chemin d'accès racine.
Sens cet exemple est fixé par l'enregistrement et le rendu du bundle chemin comme..
Alors bien sûr, vous pourriez dire que c'est RTFM, mais je suis assez sûr de moi et d'autres ramassé cette "~/Bundles/..." chemin d'accès à partir du modèle par défaut ou quelque part dans la documentation MSDN à l'adresse ou ASP.NET site web, ou tout simplement trébuché sur elle parce qu'en fait, il est tout à fait logique de nom pour un chemin d'accès virtuel et de la logique de choisir des chemins virtuels qui ne sont pas en conflit avec de vrais répertoires.
De toute façon, c'est la façon dont il est. Microsoft vois pas de bug. Je ne suis pas d'accord avec cela, il doit fonctionner comme prévu ou une exception doit être levée, ou un supplément de substituer à l'ajout de l'bundle chemin, qui opte pour inclure la racine de l'application ou non. Je ne peux pas imaginer pourquoi quelqu'un ne voudrait pas la racine de l'application inclus quand il y avait un (normalement, sauf si vous avez installé votre site web avec un alias DNS/web par défaut à la racine du site). Donc, en fait, qui doit être la valeur par défaut de toute façon.
J'ai trouvé que CssRewriteUrlTransform ne parvient pas à exécuter si vous faites référence à une
*.css
fichier et que vous avez l'associé*.min.css
fichier dans le même dossier.Pour résoudre ce problème, supprimez les
*.min.css
fichier de référence ou directement dans votre bundle:Après que vous faites cela, votre Url sera transformé correctement et vos images doivent être correctement résolu.
Peut-être que je suis partial, mais je l'aime bien ma solution car il ne fait pas du transformation de, regex, etc ... et c'est le moins de code 🙂
Cela fonctionne pour un site hébergé comme un Répertoire Virtuel dans un Site Web IIS et comme une racine de site web sur IIS
J'ai donc créé une Implentation de
IItemTransform
encapsulé laCssRewriteUrlTransform
et utiliséVirtualPathUtility
pour corriger le chemin d'accès et composez le code existant:Semble bien fonctionner pour moi?
Bien que Chris Baxter réponse de l'aide avec un problème, il ne fonctionne pas dans mon cas lorsque l'application est hébergée dans le répertoire virtuel. Après avoir examiné les options, j'ai fini avec de BRICOLAGE solution.
ProperStyleBundle
classe comprend le code emprunté à partir de l'originalCssRewriteUrlTransform
correctement transformer les chemins relatifs dans le répertoire virtuel. Il jette également si le fichier n'existe pas et empêche la réorganisation des fichiers dans le bundle (code d'BetterStyleBundle
).L'utiliser comme
StyleBundle
:De v1.1.0-alpha1 (avant la version package) le framework utilise le
VirtualPathProvider
pour accéder à des fichiers plutôt que de toucher le système de fichier.La mise à jour du transformateur peut être vu ci-dessous:
Ici est un ensemble de Transformation qui va remplacer css url avec des urls relatives à ce fichier css. Il suffit de l'ajouter à votre bundle et il devrait résoudre le problème.
cannot convert type from BundleFile to FileInfo
Une autre option serait d'utiliser IIS module de Réécriture d'URL à la carte virtuelle bundle dossier de l'image de la physique de dossier de l'image. Ci-dessous est un exemple d'une règle de réécriture à partir de ce que vous pourriez utiliser pour un faisceau appelé "~/bundles/yourpage/styles" - notez l'expression régulière correspond à des caractères alphanumériques ainsi que des traits d'union, des traits de soulignement et des périodes, qui sont communes dans les noms de fichier d'image.
Cette approche crée un peu de surcharge, mais vous permet d'avoir plus de contrôle sur votre bundle noms, et réduit également le nombre de paquets que vous pouvez avoir à faire référence, sur une page unique. Bien sûr, si vous devez faire référence à plusieurs 3ème partie css fichiers qui contiennent relative chemin de l'image des références, vous ne pouvez toujours pas obtenir autour de la création de plusieurs faisceaux.
Grinn solution est grande.
Toutefois, il ne fonctionne pas pour moi quand il y a des dossier parent références relatives dans l'url.
c'est à dire
url('../../images/car.png')
Donc, j'ai légèrement modifié la
Include
méthode afin de résoudre les chemins d'accès pour chaque regex match, permettant à des chemins relatifs et aussi pour éventuellement intégrer les images dans les css.J'ai aussi changé la SI DEBUG pour vérifier
BundleTable.EnableOptimizations
au lieu deHttpContext.Current.IsDebuggingEnabled
.Espérons que cela aide, cordialement.
Vous pouvez simplement ajouter un autre niveau de profondeur à votre virtuel bundle chemin
C'est un super low-tech réponse et une sorte de hack, mais il fonctionne et ne nécessitent aucun pré-traitement. Compte tenu de la longueur et de la complexité de certaines de ces réponses, je préfère le faire de cette façon.
J'ai eu ce problème avec des faisceaux d'avoir chemin d'accès incorrect à des images et des
CssRewriteUrlTransform
pas la résolution relative parent chemins..
correctement (il y avait également des problèmes avec les ressources externes comme les webfonts). C'est pourquoi j'ai écrit cette transformation personnalisée (semble faire tout ce qui précède correctement):Edit: je ne le savais pas, mais j'ai utilisé une extension personnalisée des méthodes dans le code. Le code source est:
Bien sûr, il devrait être possible de remplacer
String.StartsWith(char)
avecString.StartsWith(string)
.m.Groups[2].Value.Count("..")
ne fonctionne pas.) EtValue.StartsWith('/')
ne fonctionne pas, soit parce StartsWith attend une chaîne au lieu d'un char.Après petite enquête, j'ai conclu ce qui suit:
Vous avez 2 options:
aller avec des transformations. Très utile paquet pour cette: https://bundletransformer.codeplex.com/
vous avez besoin de transformation suivante pour chaque problématique bundle:
Avantages: cette solution, vous pouvez nommer votre faisceau de tout ce que vous voulez => vous pouvez combiner des fichiers css dans un bundle à partir de répertoires différents.
Inconvénients: Vous avez besoin de transformer chaque problématique bundle
Inconvénients: Vous avez limitation sur la combinaison de css les feuilles de différents répertoires dans un bundle.
CssRewriteUrlTransform
fixe mon problème.Si votre code ne charge pas les images après l'utilisation de
CssRewriteUrlTransform
, puismodifier votre css du nom de fichier à partir de:
À:
D'une certaine manière .(points) ne sont pas reconnaître dans l'url.