wake-up-neo.net

MVC4 - Bundling funktioniert nicht, wenn Optimierungen auf true gesetzt sind

Ich frage mich, was ich hier nicht richtig mache. Ich verwende ASP.NET C # MVC4 und möchte die neue Funktion zur Optimierung von css/js nutzen.

Hier ist mein HTML-Teil

@Styles.Render("~/content/css")

Hier ist mein BunduleConfig.cs Teil

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

// BundleTable.EnableOptimizations = true;

Ausgabe (Werke):

<link href="/content/css/reset.css" rel="stylesheet"/>
<link href="/content/css/bla.css" rel="stylesheet"/>

Wenn ich BundleTable.EnableOptimizations = true; html ausgab, sieht das jedoch so aus

<link href="/content/css?v=5LoJebKvQJIN-fKjKYCg_ccvmBC_LF91jBasIpwtUcY1" rel="stylesheet"/>

Und das ist natürlich 404. Ich habe keine Ahnung, wo ich etwas falsch gemacht habe.

42
stan

Ich kann mir vorstellen, dass das Problem darin besteht, dass Sie das Bundle an eine virtuelle URL stellen, die tatsächlich existiert, aber ein Verzeichnis ist.

MVC erstellt aus Ihrem Bundle eine virtuelle Datei und stellt sie über den Pfad bereit, den Sie als Bundle-Pfad angeben.

Die richtige Lösung für dieses Problem ist die Verwendung eines Bundle-Pfads, der nicht direkt einem vorhandenen Verzeichnis zugeordnet ist, sondern stattdessen einen virtuellen Dateinamen (der auch keinem realen Dateinamen entspricht) in diesem Verzeichnis verwendet.

Beispiel:

Wenn Ihre Site über einen Ordner mit dem Namen/content/css verfügt, erstellen Sie Ihr CSS-Paket wie folgt:

In BundleConfig.cs:

bundles.Add(new StyleBundle("~/content/css/AllMyCss.css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

Und auf der Seite:

@Styles.Render("~/content/css/AllMyCss.css")

Beachten Sie, dass Sie davon ausgehen, dass sich NICHT eine Datei mit dem Namen AllMyCss.css in Ihrem css-Ordner befindet.

67
dodexahedron

Ich bin mir nicht sicher, ob es die Weboptimierung oder WebGrease ist, die so wählerisch ist, aber eine (oder beide) davon ist und Sie müssen äußerst vorsichtig sein. 

Zuallererst stimmt Ihr Code nicht:

bundles.Add(new StyleBundle("~/content/css").Include(
                        "~/content/css/reset.css",
                        "~/content/css/bla.css"));

Tatsächlich ist dies genau das, was Microsoft tut. Der Hauptgrund, aus dem nicht~/bundles für css verwendet, ist, dass relative Pfade für Bilder falsch dargestellt werden. Denken Sie darüber nach, wie Ihr Browser ein Bundle sieht - genauso wie andere URLs. Außerdem gelten alle normalen Pfadregeln in Bezug auf relative Pfade. Stellen Sie sich vor, Ihre CSS hätte einen Image-Pfad zu ../images/bullet.png. Wenn Sie ~/bundles verwenden, sucht der Browser in einem Verzeichnis oberhalb von bundles, das tatsächlich nicht vorhanden ist. Es wird wahrscheinlich am Ende in ~/images suchen, wo Sie es wahrscheinlich in ~/content/images haben. 

Ich habe ein paar Dinge gefunden, die es wirklich brechen und 404-Fehler verursachen können:

  • Zu Ihrer Information: Meine Verzeichnisstruktur ist Content/CSS, die einen images-Ordner für CSS-Bilder enthält.
  • Ich habe EnableOptimizations=true, um die Verwendung von Bundles beim Testen zu erzwingen
  • Das erste, was Sie tun sollten, ist "Quelltext anzeigen" und klicken Sie einfach auf die CSS-Links, um zu sehen, ob sie funktionieren

Nehmen wir an, wir entwickeln eine Website über Katzen. Sie können dies haben

 @Styles.Render("~/Content/css/cats.css")    // dont do this - see below why

 bundles.Add(new StyleBundle("~/content/css/cats.css").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

Dies erzeugt einen CSS-Link zu diesem Pfad in Ihrem HTML-Code:

/Content/css/cats.css?v=JMoJspikowDah2auGQBfQAWj1OShXxqAlXxhv_ZFVfQ1

Dies wird jedoch eine 404 ergeben, da ich eine Erweiterung .css eingebe und IIS (denke ich) verwirrt wird.

Wenn ich es so ändere, funktioniert es gut:

 @Styles.Render("~/Content/css/cats")

 bundles.Add(new StyleBundle("~/content/css/cats").Include(
                    "~/content/css/reset.css",
                    "~/content/css/bla.css"));

Ein anderes Problem, auf das bereits andere hingewiesen haben, ist, dass Sie dies nicht tun dürfen

 @Styles.Render("~/Content/css")

wenn Sie über ein CSS-Verzeichnis oder eine CSS-Datei verfügen (unwahrscheinlich haben Sie eine Datei namens css ohne Erweiterung) in Ihrem Content-Verzeichnis.

Ein zusätzlicher Trick ist, dass Sie sicherstellen müssen, dass der generierte HTML-Code eine Versionsnummer hat

<link href="/Content/css/cats?v=6GDW6wAXIN5DJCxVtIkkxLGpojoP-tBQiKgBTQMSlWw1" rel="stylesheet"/>

Wenn dies nicht der Fall ist und so aussieht, haben Sie wahrscheinlich keine genaue Übereinstimmung mit dem Bundle-Namen zwischen Ihrer Bundle-Tabelle und Ihrer cshtml-Datei.

<link href="/Content/css/cats" rel="stylesheet"/>
26
Simon_Weaver

Vergessen Sie nicht, sicherzustellen, dass das HttpModule-Paket vorhanden ist.

<modules>  
  <remove name="BundleModule" />  
  <add name="BundleModule" type="System.Web.Optimization.BundleModule" />  
</modules>

Das hat mich beim ersten Mal gestochen. Ich bin nicht sicher, ob die erforderliche Konfiguration vom NuGet-Paket hinzugefügt werden sollte, aber es war nicht in meinem Fall.

4
Andy McCluggage

Das sieht für mich richtig aus. Wenn Optimierungen aktiviert sind, haben Sie nur einen einzelnen Ref. Dies ist der Name, den Sie in Ihrem StyleBundle (/ content/css) angegeben haben. Im Debug-Modus (oder genauer gesagt mit Debug = false in Ihrer Web-Konfiguration) erhalten Sie die nicht optimierten Dateien wie gewohnt. Wenn Sie nachsehen, werden Sie sehen, dass sie nur Text sind, wenn Sie sie eingeben. Wenn Optimierungen aktiviert sind (normalerweise im Release-Modus), erhalten Sie stattdessen eine seltsam aussehende URL.

Wenn Sie die Ausgabe davon betrachten, wird es minimiert. Die Abfragezeichenfolge? V = 5KLoJ .... basiert auf einem Hash der Dateien im Bundle. Dies ist so, dass die Referenz so lange sicher zwischengespeichert werden kann, wie Sie möchten. Für immer, wenn Sie Lust haben, aber ich denke der Standardwert ist ein Jahr. Wenn Sie jedoch eines Ihrer Stylesheets ändern, wird ein neuer Hash generiert. Dies ist "Cache-Busting", sodass Sie eine neue Kopie des Browsers erhalten.

Ich bin mir nicht sicher, warum Sie eine 404 erhalten. Ich vermute, das hat etwas mit Ihrer Routing-Konfiguration oder Ihrem IIS Setup zu tun. Führen Sie in Visual Studio mit IISExpress aus?

3
cirrus

Ich habe gerade ein ähnliches Problem gelöst. Das Problem war wie folgt: Ich habe "gewählt" über NuGet..__ installiert. In der BundleConfig-Klasse sah die Zeile mit der CSS -Datei folgendermaßen aus:

bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css",)); 
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/chosen.css"));

Einige waren in dieser Klasse unten und ich hatte diese Zeile:

BundleTable.EnableOptimizations = true;

Die Lösung bestand darin, die 2 bundles.Add() so zu kombinieren:

bundles.Add(new StyleBundle("~/Content/css").Include(
                            "~/Content/site.css", 
                            "~/Content/chosen.css"
                        ));

Und das hat es für mich behoben.

3
Yustme

Dies kann auch daran liegen, dass Sie die bundleconfig.json aus irgendeinem Grund nicht auf dem Server bereitgestellt haben.

0
DJA