Meine Frage ist ähnlich:
Nur dass ich bei MVCs eigener Bündelung bleiben möchte, wenn ich kann. Ich habe einen Brain Crash, bei dem versucht wird, das richtige Muster für die Angabe von Stilpaketen zu finden, sodass eigenständige CSS- und Image-Sets wie die jQuery-Benutzeroberfläche funktionieren.
Ich habe eine typische MVC-Site-Struktur, mit /Content/css/
der mein Basis-CSS wie z styles.css
. In diesem /jquery-ui
CSS- Ordner befinden sich auch Unterordner, z. B. die CSS-Datei sowie einen /images
Ordner. Bildpfade im jQuery UI CSS sind relativ zu diesem Ordner und ich möchte mich nicht mit ihnen herumschlagen.
So wie ich es verstehe, muss ich bei der Angabe von a StyleBundle
einen virtuellen Pfad angeben, der nicht auch mit einem realen Inhaltspfad übereinstimmt, da IIS (vorausgesetzt, ich ignoriere Routen zu Inhalten) dann versuchen würde, diesen Pfad als physische Datei aufzulösen. Also spezifiziere ich:
bundles.Add(new StyleBundle("~/Content/styles/jquery-ui")
.Include("~/Content/css/jquery-ui/*.css"));
gerendert mit:
@Styles.Render("~/Content/styles/jquery-ui")
Ich kann sehen, dass die Anfrage an folgende Adresse geht:
http://localhost/MySite/Content/styles/jquery-ui?v=nL_6HPFtzoqrts9nwrtjq0VQFYnhMjY5EopXsK8cxmg1
Dies gibt die korrekte, minimierte CSS-Antwort zurück. Dann sendet der Browser eine Anfrage für ein relativ verknüpftes Bild wie folgt:
http://localhost/MySite/Content/styles/images/ui-bg_highlight-soft_100_eeeeee_1x100.png
Welches ist ein 404
.
Ich verstehe, dass der letzte Teil meiner URL jquery-ui
eine URL ohne Erweiterung ist, ein Handler für mein Bundle, sodass ich sehen kann, warum die relative Anforderung für das Bild einfach ist /styles/images/
.
Meine Frage ist also, wie ich mit dieser Situation richtig umgehen kann.
quelle
Antworten:
Laut diesem Thread zur MVC4-CSS-Bündelung und zu Bildreferenzen definieren Sie Ihr Bündel wie folgt :
Wenn Sie das Bundle auf demselben Pfad wie die Quelldateien definieren, aus denen das Bundle besteht, funktionieren die relativen Bildpfade weiterhin. Der letzte Teil des Bundle-Pfads ist wirklich der
file name
für dieses bestimmte Bundle (dh/bundle
kann ein beliebiger Name sein, den Sie mögen).Dies funktioniert nur, wenn Sie CSS aus demselben Ordner bündeln (was aus Sicht der Bündelung meiner Meinung nach sinnvoll ist).
Aktualisieren
Gemäß dem Kommentar unten von @Hao Kung kann dies jetzt alternativ durch Anwenden von a
CssRewriteUrlTransformation
( Ändern der relativen URL-Verweise auf CSS-Dateien im Bundle ) erreicht werden.HINWEIS: Ich habe keine Kommentare zu Problemen beim Umschreiben in absolute Pfade innerhalb eines virtuellen Verzeichnisses bestätigt, daher funktioniert dies möglicherweise nicht für alle (?).
quelle
Die Grinn / ThePirat-Lösung funktioniert gut.
Mir hat es nicht gefallen, dass die Include-Methode für das Bundle neu ist und temporäre Dateien im Inhaltsverzeichnis erstellt wurden. (Sie wurden eingecheckt und bereitgestellt, dann wurde der Dienst nicht gestartet!)
Um dem Design der Bündelung zu folgen, habe ich mich entschieden, im Wesentlichen denselben Code auszuführen, jedoch in einer IBundleTransform-Implementierung:
Und dann packte dies in eine Bundle Implemetation:
Beispielnutzung:
Hier ist meine Erweiterungsmethode für RelativeFromAbsolutePath:
quelle
relativeToCSS
bevor man anruftPath.GetFullPath()
.Besser noch (IMHO) implementieren Sie ein benutzerdefiniertes Bundle, das die Bildpfade korrigiert. Ich habe eine für meine App geschrieben.
...
Um es zu verwenden, gehen Sie wie folgt vor:
...anstatt...
Was es tut, ist (wenn es nicht im Debug-Modus ist), es zu suchen
url(<something>)
und durch zu ersetzenurl(<absolute\path\to\something>)
. Ich habe das Ding vor ungefähr 10 Sekunden geschrieben, daher muss es möglicherweise etwas angepasst werden. Ich habe vollqualifizierte URLs und base64-DataURIs berücksichtigt, indem ich sichergestellt habe, dass der URL-Pfad keine Doppelpunkte (:) enthält. In unserer Umgebung befinden sich Bilder normalerweise im selben Ordner wie ihre CSS-Dateien, aber ich habe sie sowohl mit übergeordneten Ordnern (url(../someFile.png)
) als auch mit untergeordneten Ordnern ( ) getesteturl(someFolder/someFile.png
.quelle
Es ist nicht notwendig, eine Transformation anzugeben oder verrückte Unterverzeichnispfade zu haben. Nach langer Fehlerbehebung habe ich es auf diese "einfache" Regel isoliert (ist es ein Fehler?) ...
Wenn Ihr Bundle-Pfad nicht mit dem relativen Stamm der enthaltenen Elemente beginnt, wird der Stamm der Webanwendung nicht berücksichtigt.
Klingt für mich eher nach einem Fehler, aber so beheben Sie ihn trotzdem mit der aktuellen .NET 4.51-Version. Vielleicht waren die anderen Antworten bei älteren ASP.NET-Builds notwendig. Ich kann nicht sagen, dass Sie keine Zeit haben, dies alles nachträglich zu testen.
Zur Verdeutlichung hier ein Beispiel:
Ich habe diese Dateien ...
Dann richten Sie das Bundle wie ...
Und machen Sie es wie ...
Und erhalten Sie das "Verhalten" (Fehler), die CSS-Dateien selbst haben das Anwendungsstammverzeichnis (z. B. "http: // localhost: 1234 / MySite / Content / Site.css"), aber das CSS-Image in allen Starts "/ Content / Images / ... "oder" / Images / ... ", je nachdem, ob ich die Transformation hinzufüge oder nicht.
Ich habe sogar versucht, den Ordner "Bundles" zu erstellen, um festzustellen, ob er mit dem vorhandenen Pfad zu tun hat oder nicht, aber das hat nichts geändert. Die Lösung des Problems besteht darin, dass der Name des Bundles mit dem Pfadstamm beginnen muss.
Das heißt, dieses Beispiel wird behoben, indem der Bündelpfad wie folgt registriert und gerendert wird.
Man könnte natürlich sagen, dass dies RTFM ist, aber ich bin mir ziemlich sicher, dass ich und andere diesen "~ / Bundles / ..." - Pfad von der Standardvorlage oder irgendwo in der Dokumentation auf der MSDN- oder ASP.NET-Website oder übernommen haben Ich bin nur darauf gestoßen, weil es eigentlich ein ziemlich logischer Name für einen virtuellen Pfad ist und es sinnvoll ist, solche virtuellen Pfade zu wählen, die nicht mit realen Verzeichnissen in Konflikt stehen.
Jedenfalls ist das so. Microsoft sieht keinen Fehler. Ich bin damit nicht einverstanden, entweder sollte es wie erwartet funktionieren oder eine Ausnahme sollte ausgelöst werden, oder eine zusätzliche Überschreibung zum Hinzufügen des Bundle-Pfads, der sich dafür entscheidet, den Anwendungsstamm einzuschließen, oder nicht. Ich kann mir nicht vorstellen, warum jemand nicht möchte, dass das Anwendungsstammverzeichnis enthalten ist, wenn es eines gab (normalerweise, es sei denn, Sie haben Ihre Website mit einem DNS-Alias / Standard-Website-Stammverzeichnis installiert). Eigentlich sollte das sowieso die Standardeinstellung sein.
quelle
Ich habe festgestellt, dass CssRewriteUrlTransform nicht ausgeführt werden kann, wenn Sie auf eine
*.css
Datei verweisen und sich die zugehörige*.min.css
Datei im selben Ordner befindet.Um dies zu beheben, löschen Sie die
*.min.css
Datei entweder oder verweisen Sie direkt auf sie in Ihrem Bundle:Danach werden Ihre URLs korrekt transformiert und Ihre Bilder sollten korrekt aufgelöst werden.
quelle
Vielleicht bin ich voreingenommen, aber ich mag meine Lösung sehr, da sie keine Transformationen, Regex usw. durchführt und die geringste Menge an Code enthält :)
Dies funktioniert für eine Site, die als virtuelles Verzeichnis auf einer IIS-Website und als Root-Website auf IIS gehostet wird
Also habe ich eine Implentation von
IItemTransform
gekapseltem erstelltCssRewriteUrlTransform
und verwendetVirtualPathUtility
, um den Pfad zu reparieren und den vorhandenen Code aufzurufen:Scheint gut für mich zu funktionieren?
quelle
Obwohl die Antwort von Chris Baxter bei dem ursprünglichen Problem hilft, funktioniert sie in meinem Fall nicht, wenn die Anwendung in einem virtuellen Verzeichnis gehostet wird . Nachdem ich die Optionen untersucht hatte, beendete ich die DIY-Lösung.
ProperStyleBundle
Die Klasse enthält Code, der vom Original entlehnt wurdeCssRewriteUrlTransform
, um relative Pfade innerhalb des virtuellen Verzeichnisses ordnungsgemäß zu transformieren. Es wird auch ausgelöst, wenn keine Datei vorhanden ist, und verhindert die Neuordnung von Dateien im Bundle (Code ausBetterStyleBundle
).Verwenden Sie es wie
StyleBundle
:quelle
Ab Version 1.1.0-alpha1 (Pre-Release-Paket) verwendet das Framework das,
VirtualPathProvider
um auf Dateien zuzugreifen, anstatt das physische Dateisystem zu berühren.Der aktualisierte Transformator ist unten zu sehen:
quelle
Hier ist eine Bundle-Transformation, die CSS-URLs durch URLs relativ zu dieser CSS-Datei ersetzt. Fügen Sie es einfach Ihrem Bundle hinzu und es sollte das Problem beheben.
quelle
cannot convert type from BundleFile to FileInfo
Eine andere Option wäre die Verwendung des IIS URL Rewrite-Moduls, um den virtuellen Bundle-Image-Ordner dem physischen Image-Ordner zuzuordnen. Im Folgenden finden Sie ein Beispiel für eine Umschreiberegel, die Sie für ein Bundle mit dem Namen "~ / bundles / yourpage / styles" verwenden können. Beachten Sie die Regex-Übereinstimmungen für alphanumerische Zeichen sowie Bindestriche, Unterstriche und Punkte, die in Bilddateinamen häufig vorkommen .
Dieser Ansatz verursacht einen zusätzlichen Aufwand, ermöglicht Ihnen jedoch eine bessere Kontrolle über Ihre Bundle-Namen und reduziert auch die Anzahl der Bundles, auf die Sie möglicherweise auf einer Seite verweisen müssen. Wenn Sie auf mehrere CSS-Dateien von Drittanbietern verweisen müssen, die relative Bildpfadreferenzen enthalten, können Sie natürlich immer noch nicht um das Erstellen mehrerer Bundles herumkommen.
quelle
Grinn-Lösung ist großartig.
Es funktioniert jedoch nicht für mich, wenn die URL relative Verweise auf übergeordnete Ordner enthält. dh
url('../../images/car.png')
Daher habe ich die
Include
Methode geringfügig geändert , um die Pfade für jede Regex-Übereinstimmung aufzulösen, relative Pfade zuzulassen und die Bilder optional in das CSS einzubetten.Ich habe auch den IF DEBUG geändert, um zu überprüfen,
BundleTable.EnableOptimizations
anstattHttpContext.Current.IsDebuggingEnabled
.Hoffe es hilft, Grüße.
quelle
Sie können Ihrem virtuellen Bundle-Pfad einfach eine weitere Tiefe hinzufügen
Dies ist eine Super-Low-Tech-Antwort und eine Art Hack, aber sie funktioniert und erfordert keine Vorverarbeitung. Angesichts der Länge und Komplexität einiger dieser Antworten mache ich es lieber so.
quelle
Ich hatte dieses Problem mit Bundles, die falsche Pfade zu Bildern hatten und die
CssRewriteUrlTransform
relativen übergeordneten Pfade nicht..
korrekt auflösten (es gab auch Probleme mit externen Ressourcen wie Webfonts). Aus diesem Grund habe ich diese benutzerdefinierte Transformation geschrieben (scheint alle oben genannten Schritte korrekt auszuführen):Bearbeiten: Ich habe es nicht bemerkt, aber ich habe einige benutzerdefinierte Erweiterungsmethoden im Code verwendet. Der Quellcode von diesen ist:
Natürlich sollte es möglich sein , zu ersetzen
String.StartsWith(char)
mitString.StartsWith(string)
.quelle
m.Groups[2].Value.Count("..")
funktioniert nicht). SieValue.StartsWith('/')
funktioniert auch nicht, da StartsWith eine Zeichenfolge anstelle eines Zeichens erwartet.Nach kleinen Nachforschungen kam ich zu folgendem Schluss: Sie haben zwei Möglichkeiten:
gehe mit Transformationen. Sehr nützliches Paket dafür: https://bundletransformer.codeplex.com/ Sie benötigen die folgende Transformation für jedes problematische Bundle:
Vorteile: Mit dieser Lösung können Sie Ihr Bundle beliebig benennen => Sie können CSS-Dateien aus verschiedenen Verzeichnissen zu einem Bundle kombinieren. Nachteile: Sie müssen jedes problematische Bundle transformieren
quelle
CssRewriteUrlTransform
mein Problem behoben.Wenn Ihr Code nach der Verwendung immer noch keine Bilder lädt
CssRewriteUrlTransform
, ändern Sie den CSS-Dateinamen von:Zu:
Irgendwie (Punkte) werden in der URL nicht erkannt.
quelle
Denken Sie daran, mehrere CSS-Einschlüsse in einem Bundle zu korrigieren, z.
Sie können nicht nur hinzufügen ,
new CssRewriteUrlTransform()
bis zum Ende , wie Sie können mit einer CSS - Datei als die Methode nicht unterstützt, so dass Sie zu haben , verwendenInclude
mehrfach :quelle