web-dev-qa-db-ja.com

MVC4-最適化がtrueに設定されている場合、バンドリングは機能しません

ここで何が正しくないのだろうか。 ASP.NET C#MVC4を使用していますが、新しいcss/js最適化機能を使用したいと思います。

ここに私のHTML部分があります

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

これが私のBunduleConfig.csパート

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

// BundleTable.EnableOptimizations = true;

出力(機能):

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

ただし、コメントを解除するとBundleTable.EnableOptimizations = true; html出力は次のようになります

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

もちろんこれは404です。MVC4を初めて使用するときに、どこで間違ったことをしたのかわかりません。

43
sed

問題は、実際には存在するがディレクトリである仮想URLにバンドルを配置することだと思います。

MVCはバンドルから仮想ファイルを作成し、バンドルパスとして指定したパスから提供します。

その問題の正しい解決策は、既存のディレクトリに直接マッピングしないバンドルパスを使用し、代わりにそのディレクトリ内で仮想ファイル名(実際のファイル名にもマッピングしない)を使用することです。

例:

サイトに/ content/cssという名前のフォルダーがある場合、次のようにcssバンドルを作成します。

BundleConfig.cs内:

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

そしてページで:

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

これは、cssフォルダーにAllMyCss.cssという名前のファイルがないことを前提としていることに注意してください。

68
dodexahedron

Web最適化なのか、それともWebGreaseがそれほどうるさいのかはわかりませんが、どちらか(または両方)がそうであり、非常に注意する必要があります。

まず第一に、コードに問題はありません:

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

実際、これはまさにマイクロソフトが行うことです。彼らがしない cssに~/bundlesを使用する主な理由は、画像の相対パスがめちゃくちゃになることです。ブラウザがどのようにバンドルを見るかを考えてください-他のURLを見るのとまったく同じ方法で、相対パスに関してはすべての通常のパス関連ルールが適用されます。あなたのcssが../images/bullet.pngへの画像パスを持っていたと想像してください。 ~/bundlesを使用している場合、ブラウザはbundlesの上のディレクトリを探しますが、実際には存在しません。おそらくあなたはおそらく~/imagesにある_~/content/imagesを探してしまうでしょう。

私は本当にそれを壊して404エラーを引き起こす可能性のあるものをいくつか見つけました:

  • 参考:私のディレクトリ構造はContent/CSSで、CSSイメージ用のimagesフォルダーが含まれています。
  • テスト中にバンドルの使用を強制するEnableOptimizations=trueがあります
  • 最初に行うべきことは「ソースの表示」で、CSSリンクをクリックして動作するかどうかを確認する

猫に関するサイトを開発しているとしましょう。これがあるかもしれません

 @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"));

これにより、HTMLのこのパスへのCSSリンクが生成されます。

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

ただし、拡張子.cssを付けてIIS(と思う)が混乱するため、これは404になります。

これに変更すると、うまくいきます:

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

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

他の人がすでに指摘している別の問題は、あなたがしてはいけないことです

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

cssディレクトリにcssディレクトリまたはファイルがある場合(拡張子のないContentという名前のファイルはないでしょう)。

追加のトリックは、生成されたHTMLにバージョン番号があることを確認する必要があることです

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

そうでなく、このように見える場合は、おそらく、Bundleテーブルとcshtmlファイルでバンドル名が完全に一致していません。

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

バンドルされているHttpModuleがあることを忘れないでください。

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

これは初めて私を刺しました。必要な構成をNuGetパッケージで追加する必要があるかどうかはわかりませんが、私の場合はそうではありませんでした。

4
Andy McCluggage

それは私には正しいようです。最適化を有効にすると、参照は1つだけになり、StyleBundleで指定した名前(/ content/css)になります。デバッグモード(またはWeb設定でdebug = falseを指定した場合)では、最適化されていないファイルを通常どおり取得します。見ると、入力したとおりにプレーンテキストであることがわかります。ただし、最適化がオンになっている場合(通常はリリースモードで実行している場合)、代わりに奇妙なURLが表示されます。

その出力を見ると、縮小されます。クエリ文字列?v = 5KLoJ ....は、バンドル内のファイルのハッシュに基づいています。これは、参照を必要な限り安全にHTTPキャッシュできるようにするためです。あなたが空想しているが、私は永遠に思考デフォルトは年です。ただし、スタイルシートのいずれかを変更すると、新しいハッシュが生成され、それが「キャッシュ無効化」になるため、ブラウザで新しいコピーを取得できます。

そうは言っても、なぜ404が返されるのかはわかりません。これは、ルーティング構成またはIISセットアップと関係があります。VisualStudioで実行していますか? IISExpress?

3
cirrus

同様の問題を解決しました。問題は次のとおりで、NuGetを介して 'chosen'をインストールしました。 BundleConfigクラスでは、CSSファイルを含む行は次のようになりました。

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

そのクラスのどこかで私はこの行を持っていました:

_BundleTable.EnableOptimizations = true;
_

修正は、2つのbundles.Add()を次のように結合することでした:

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

そしてそれは私のためにそれを修正しました。

3
Yustme

また、何らかの理由でbundleconfig.jsonをサーバーにデプロイしていない可能性もあります。

0
DJA