ASP.NET-Bündelung - Bundle wird nicht aktualisiert, nachdem die enthaltene Datei geändert wurde (Rückgabe 304 nicht geändert)

72

Ich probiere ASP.NET Bundling mit der Anwendung ASP.NET MVC 4 aus. Die Situation ist, dass ich einen Dienst im CDN-Stil erstellen möchte, der JS- und CSS-Dateien enthält, an die Sie von anderen Websites mit dieser Typadresse adressieren können: http://www.mycdn.com/scripts/plugin/js , die gebündelt werden und minimiert alle enthaltenen .js-Dateien.

Meine Bundle-Konfiguration für eine Datei sieht folgendermaßen aus:

bundles.Add(new ScriptBundle("~/Scripts/plugin/pluginjs").Include("~/Scripts/plugin/jquery.plugin.js"));

Wenn ich dies tue, werden die Bundles jedoch nicht aktualisiert, selbst nachdem ich die ursprünglichen js-Dateien geändert habe. Ich erhalte weiterhin 304 Not Modified, wenn ich meinen Browser aktualisiere und der Inhalt der minimierten Datei nicht aktualisiert wird. Wie kann ich Bundles aktualisieren, da es nutzlos ist, Bundles mit alten Inhalten zu haben? Ich habe alles ausprobiert, konnte aber keine Lösung finden.

Danke im Voraus!

Tommi Gustafsson
quelle
Eine mögliche Antwort auf dieses Problem finden Sie unter stackoverflow.com/a/34508048/1545567 (dh Verwendung eines Bundles von einer anderen Site oder von einfachem HTML)
Christophe Blin
Berühren Sie sowohl normale als auch minimierte Dateien, um sie neu zu laden.
Mariusz

Antworten:

82

Ich hatte genau das gleiche Problem. Ich habe einen Ordner mit 2 CSS-Dateien:

  • ~ / Content / main.css
  • ~ / Content / main.min.css (bereits vorhanden aus meinem vorherigen manuellen Minimierungsprozess)

Mein Bündelungscode lautet:

bundles.Add(new StyleBundle("~/css/main").Include("~/content/main.css"));

Egal wie sehr ich meine geändert habe, main.cssdie Ausgabe war dieselbe URL mit demselben Inhalt:

<link href="/css/main?v=6Xf_QaUMSlzHbXralZP7Msq1EiLTd7g1vId6Vcy8NJM1" rel="stylesheet"/>

Die einzige Möglichkeit, das Bundle zu aktualisieren, bestand darin, meine Lösung neu zu erstellen - offensichtlich nicht der beste Ansatz.

Doch sobald ich gelöscht main.min.css, alles gut funktionieren begann. Spielen ein wenig mehr entdeckte ich , dass , wenn es beide main.cssund main.min.cssdann die Aktualisierung main.min.csstatsächlich aktualisieren das Bündel ... Verrücktheit, aber zumindest vorhersehbar.

niaher
quelle
26
Dokumentation Das Bündelungsframework folgt mehreren gängigen Konventionen, z. B.: Auswählen der Datei ".min" zur Freigabe, wenn "FileX.min.js" und "FileX.js" vorhanden sind. Auswahl der Nicht-Min. -Version zum Debuggen. Ignorieren von "-vsdoc" -Dateien (z. B. jquery-1.7.1-vsdoc.js), die nur von IntelliSense verwendet werden.
Felickz
1
Unter stackoverflow.com/a/14967754/682105 finden Sie eine Antwort darauf, wie Sie die Ignorierliste konfigurieren können.
Khellang
Dies hat das Problem behoben ... wirklich gute Antwort ... danke, auch in meinem Fall von Verrücktheit hatte ich eine technische Verschuldung von main.js und main.min.remove.js (es hat die main.min.remove.js aufgenommen) von einer anderen Person, die ich danach gereinigt habe, war alles süß
Egli Becerra
1
Ich finde es lächerlich, dass Microsoft beschlossen hat, meine sorgfältig codierten Bundles zu ignorieren und nur die "min" -Datei verwendet, die im selben Verzeichnis enthalten ist. Wenn ich die "min" -Datei verwenden wollte, würde ich die "min" -Datei SPEZIFIZIEREN. FFS.
Zerohero
33

Nachdem ich gekämpft hatte, um herauszufinden, wie der Bundle-Cache aktualisiert wird, kam ich zu einigen Schlussfolgerungen, die hoffentlich anderen helfen werden:

Wenn .min-Dateien als Teil des Bundles enthalten sind:

  • Freigabemodus + Änderung min js Code = Cache-Aktualisierung
  • Freigabemodus + Nicht-Min-JS-Code ändern = keine Cache-Aktualisierung
  • Debug-Modus + min js-Code ändern = keine Cache-Aktualisierung
  • Debug-Modus + Nicht-Min-JS-Code ändern = keine Cache-Aktualisierung

Wenn .min-Dateien NICHT im Bundle enthalten sind:

  • Debug-Modus + js-Code ändern = keine Cache-Aktualisierung
  • Freigabemodus + js Code ändern = Cache aktualisieren

Anmerkungen

  • Mit Debug-Modus meine ich die Kompilierung von web.config debug = true (und BundleTable.EnableOptimizations = false oder wird weggelassen)
  • Mit Release-Modus meine ich web.config compilation debug = false (und BundleTable.EnableOptimizations = true oder wird weggelassen
  • Stellen Sie sicher, dass Sie tatsächlich Codeänderungen vornehmen. Änderungen wie Leerzeichen und Kommentare wirken sich nicht auf die resultierenden minimierten js aus, sodass der Server korrekt ist, da keine Änderungen vorgenommen wurden (sodass der Bundle-Cache nicht aktualisiert wird).
Bolo
quelle
Was ist, wenn wir im Debug-Modus veröffentlichen? Bedeutet dies, dass die Bündelung in der Produktion unterbrochen wird und immer das erste Bündel geliefert wird, das nach dem Neustart von IIS erstellt wurde?
Brandon
Sie können die Bündelung mit web.config debug = "true" weiterhin verwenden, wenn Sie auch BundleTable.EnableOptimizations = true festlegen
Bolo
9

Okay, hier ist meine Geschichte. Ich habe die Generierung von Min-Dateien für weniger Dateien in Web Essentials deaktiviert. Alte Min-Dateien wurden nicht gelöscht, und Bundle-Dinger sahen diese anstelle von aktualisiertem CSS. Viel Glück!

BEARBEITEN

Einige Zeit später verbrachte ich weitere gute 2 Stunden mit dem gleichen Thema. Diesmal war es wohl meine Schuld - ich habe die führende Tilde vergessen, dh ich habe geschrieben

Scripts.Render("/js/script")

anstelle

Scripts.Render("~/js/script")

Aus irgendeinem Grund funktionierte es manchmal und manchmal tat es so etwas nicht.

Gleno
quelle
Das Entfernen von .min-Dateien löste das Bündelungsproblem auch für mich. In meinem Fall ist es wahrscheinlich nach dem Zusammenführen zwischen Zweigen aufgetreten.
Hanno
6

Beachten Sie, dass das Caching bei Verwendung von Google Chrome recht aggressiv ist. Um sicherzustellen, dass nichts zwischengespeichert wird, können Sie Ctrl-Shift-Iden Entwicklerbereich aufrufen. Gehen Sie zu Networkund klicken Sie auf Disable Cache. Stellen Sie sicher, dass Sie dies offen halten. Aktualisieren Sie nun die Seite. Ihr Cache sollte geleert werden und die Dateiänderungen sollten jetzt wiedergegeben werden.

Deaktivieren Sie den Cache in Google Chrome

coolboyjules
quelle
3

Ich habe mich tatsächlich entschieden, System.Web.Optimization für diese Aufgabe nicht zu verwenden, aber ich habe Microsoft Ajax Minifier gefunden, das auch in WebGrease.dll enthalten ist, das mit der MVC4 System.Web.Optimization-Bibliothek geliefert wird. Ich habe die folgende Funktion geschrieben, die ich dann in Application_Start für jede minimierte Datei aufgerufen habe:

    public static void MinifyFile(string virtualPath)
    {
        string fullPath = HttpContext.Current.Server.MapPath(virtualPath);
        string extension = Path.GetExtension(fullPath).ToLower();
        string targetPath = fullPath.Substring(0, fullPath.Length - extension.Length) + ".min" + extension;
        if(File.Exists(fullPath) == false) 
        {
            throw new FileNotFoundException("File not found: " + fullPath);
        }
        string input = File.ReadAllText(fullPath);
        string output;
        if (extension == ".js")
        {
            Microsoft.Ajax.Utilities.Minifier jsmin = new Microsoft.Ajax.Utilities.Minifier();
            output = jsmin.MinifyJavaScript(input);
        }
        else if (extension == ".css")
        {
            Microsoft.Ajax.Utilities.Minifier jsmin = new Microsoft.Ajax.Utilities.Minifier();
            output = jsmin.MinifyStyleSheet(input);                
        }
        else
        {
            throw new NotSupportedException(extension + " is not supported for minification.");
        }
        File.WriteAllText(targetPath, output);
    }

Jetzt minimiert meine Anwendung alle Dateien auf Application_Start.

Tommi Gustafsson
quelle
Sie haben also keine Lösung gefunden. Ich habe das gleiche Problem, das Hintergrundbild in der CSS-Datei geändert, das Debuggen in der Dev Station funktioniert gut, nach der Veröffentlichung erscheint ein alter Hintergrund. Es wurde keine minimierte Datei aktualisiert. :(
Ricker Silva
3

Bei der Bündelung wird zwischen Groß- und Kleinschreibung unterschieden. Stellen Sie sicher, dass der Dateiname den richtigen Fall hat.

Ich musste eine Zeile in meiner BundleConfig.cs ändern:

bundles.Add(new StyleBundle("~/Content/css").Include(
    "~/Content/bootstrap.css",
    "~/Content/Site.css"));  <-- Uppercased.
Doug Mair
quelle
1

Ich bin mir nicht sicher, ob die derzeitige Funktion ein CDN wirklich unterstützt, da sie implizit auf der URL beruht, die einen Hashcode enthält, um das Zwischenspeichern des Browsers zu verhindern.

Aber ich kann versuchen, Ihnen zu helfen, dorthin zu gelangen, und vielleicht ist es heute möglich ... Ein Problem, das möglicherweise eine Straßensperre darstellt, ist, dass der BundleHandler bei Bundle-Anforderungen, die den IfLastModified-Header enthalten, 304 zurückgibt, da davon ausgegangen wird Der Browser-Cache ist aufgrund des Fingerabdrucks in der URL immer gültig.

Können Sie einige Details hinzufügen, wie Sie Verweise auf die Bundles rendern? Verwenden Sie so etwas wie Scripts.Render ("~ / Scripts / plugin / pluginjs")?

Ihr Bundle-Skript-Tag sollte ungefähr so ​​aussehen:

Good: <script src="/fbt/bundles/js?v=wvLq7H7qEZB2giyIRn7aEZAxhHOb2RfTYYh2HMd9EqM1"></script>

Wenn Ihre Skript-Tags ohne Versionszeichenfolge auf das Raw-Bundle verweisen, erklärt dies wahrscheinlich die angezeigten Caching-Probleme:

Not good: <script src="/fbt/bundles/js></script>
Hao Kung
quelle
Das Problem ist, dass dies ein Dienst vom Typ CDN ist, also Dateien für andere Websites hostet und die Dateien selbst nicht verwendet. Die referenzierenden Sites können also alles sein und nicht unbedingt ASP.NET-Sites. Ich bin auch auf die Tatsache gestoßen, dass Bundling eine sogenannte CDN-Unterstützung hat.
Tommi Gustafsson
asp.net/mvc/tutorials/mvc-4/bundling-and-minification (siehe Abschnitt CDN) Könnte es möglich sein, dass ich die Dateien einfach normal hoste, ohne sie zu bündeln und zu minimieren, und dann möglicherweise von anderen ASP.NET-Sites auf diese verweise Dateien im CDN-Format: bundles.UseCdn = true; // CDN-Unterstützungszeichenfolge aktivieren cdnPath = " mycdn.com/scripts/plugin/myplugin-xyzmin.js "; bundles.Add (neues ScriptBundle ("~ / bundles / jquery", cdnPath) .Include ("~ / Scripts / myplugin- {version} .js"));
Tommi Gustafsson
Ja, wenn dies eine praktikable Option ist, ist dies höchstwahrscheinlich die beste Option. Lassen Sie einfach die ASP.NET-Sites Ihr CDN verwenden, auf dem sich das Bundle befindet.
Hao Kung
0

Ich weiß, dass es eine Weile her ist, seit dies aktualisiert wurde, aber ich habe festgestellt, dass ich nur ein paar Sekunden warten muss, damit das Bundle meine CSS-Änderungen nachholen kann. Ich habe die Bootstrap-weniger Dateien in eine CSS und Min.CSS kompiliert und es ist definitiv nicht sofort, meine Änderungen zu sehen. Für mich waren es ungefähr 10 Sekunden auf einem schnellen PC mit einer SSD. Ihre Meilen können je nach Systemspezifikation variieren.

LasstLos
quelle
0

Ich habe diese Antwort gesehen, aber keine davon war für mich der Fall. Es gab bestimmte CSS-Regeln, die dazu führten, dass der Styles-Bundler fehlschlug, und ich bekam den gleichen Hash, selbst wenn ich Änderungen an der CSS-Datei vorgenommen habe. Für mich hat alles richtig funktioniert.

In meinem Fall war die verletzende CSS-Auswahlregel -

#globalSearch.searching { ... }

Wenn ich das nur gemacht hätte

.searching { ... }

Alles beginnt wieder zu funktionieren und alle Änderungen, die ich an meiner CSS-Datei vornehme, werden vom Bundler-Hash korrekt geändert. Fügen Sie einfach diese Antwort hinzu, da dies jemandem helfen könnte.

MoXplod
quelle
0

Aktualisieren Sie einfach Ihre System.Web.Optimization von NuGet Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Emanuel Lima
quelle
0

Für das, was es wert ist, hatte ich gerade das gleiche Problem mit einer js-Datei, die sich unerklärlicherweise weigerte, zu aktualisieren, egal was passiert (Neuerstellung, erzwungenes Löschen des Caches usw.). Nach einer Weile schaltete ich die Client-Debug-Tools im IE ein (F12), um den Netzwerkverkehr zu überwachen, und allein dieser Vorgang zwang die JS-Datei zur Aktualisierung. Gehen Sie Figur, aber es hat funktioniert.

Wächter
quelle
0

Das Problem für mich war, dass ich Fiddler laufen ließ. Nachdem ich dit geschlossen und meine Lösung neu erstellt hatte, wurden die Änderungen in der js-Datei für mich geladen.

TruthOf42
quelle
0

Ich hatte ein ähnliches Problem. In meiner Situation hatte ich eine CSS-Datei, auf die in einem Stilpaket verwiesen wurde, und dieses Paket, auf das in meiner MVC-Ansicht verwiesen wurde. Ich hatte auch das Flag "EnableOptimizations" im Bundle-Code auf false gesetzt.

Trotz alledem weigerte sich die Ansicht, die neue CSS-Datei zu aktualisieren.

Meine Lösung bestand darin, eine minimierte Version der CSS-Datei zu erstellen und in das Projekt aufzunehmen, und es begann zu funktionieren. Ich habe keine Ahnung, warum dies der Fall sein sollte, da auf diese minimierte Datei nirgendwo verwiesen wird (auch nicht nach Aktualisierung der Ansicht) und nicht einmal berücksichtigt werden sollte, da der Code so eingestellt ist, dass er nicht optimiert wird. Dies ist höchstwahrscheinlich ein Fehler (oder eine Funktion) der Bündelungsfunktion. Ich hoffe, dies hilft jemand anderem, der auf dieses Problem stößt.

mfranchi
quelle
0

Stellen Sie sicher, dass Ihre App wirklich im Release-Modus bereitgestellt wird und Ihr Host an den Einstellungen herumfummelt. Ich hatte dieses Problem, aber nach einer Untersuchung stellte ich fest, dass meine Dateien nicht wirklich gebündelt wurden. Ich habe im Release-Modus bereitgestellt, aber aus irgendeinem Grund (ich vermute Host) wurde meine App tatsächlich im Debug-Modus bereitgestellt.

Ich musste am Ende der Datei BundleConfig.cs Folgendes festlegen, um die Bündelung zu erzwingen, was wiederum dazu führte, dass die aktualisierte Datei endlich im Browser angezeigt wurde.

BundleTable.EnableOptimizations = true;
Glück. Experte
quelle
0

Ich hatte dieses Problem heute und habe alle Antworten durchgesehen, aber mein Problem wurde durch keine der hier aufgeführten Lösungen gelöst. Später stellte ich fest, dass dies geschah, weil in meinem CSS ein Fehler aufgetreten war. Eine der URLs wurde nicht geschlossen (das letzte einfache Zitat fehlte).

Dies führte dazu, dass die CSS-Datei einen Syntaxfehler aufwies und nicht für die Bundleconfig kompiliert wurde. Ich nehme an, es hätte eine Nachricht im Ausgabeprotokoll gegeben, aber ich hatte es nicht überprüft.

Wenn Ihnen dies im Jahr 2020 passiert, stellen Sie sicher, dass Ihr CSS keinen Syntaxfehler aufweist.

Cyril Gupta
quelle