2012-09-02 27 views
40

Tôi tự hỏi những gì tôi không làm đúng ở đây. Tôi đang sử dụng ASP.NET C# MVC4 và tôi muốn sử dụng tính năng tối ưu hóa css/js mới.MVC4 - Bundling không hoạt động khi tối ưu hóa được đặt thành true

Dưới đây là một phần HTML của tôi

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

Dưới đây là một phần BunduleConfig.cs tôi

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

// BundleTable.EnableOptimizations = true; 

Output (hoạt động):

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

Tuy nhiên khi tôi bỏ ghi chú BundleTable.EnableOptimizations = true; sản lượng html trông như thế này

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

Và đây là, tất nhiên là 404. Tôi không biết mình đã làm gì sai, xin hãy giúp đỡ, lần đầu tiên làm việc với MVC4.

+0

Điều gì xảy ra nếu bạn tạo các tệp ~ content/css/reset.min.css và bla.min.css mà EnableOptimizations = true có xu hướng tìm kiếm? – Phil

+0

@Phil vẫn 404. – sed

+0

Tôi vừa tạo dự án trống và thử với hai tệp 'css' và cùng một điều đã xảy ra. Có lẽ đó là vì tôi đặt các tệp css của tôi trong thư mục '/ content/css /' chứ không phải chỉ là '/ content /' tuy nhiên tôi nghi ngờ ... – sed

Trả lời

64

Tôi tưởng tượng vấn đề là bạn đặt gói tại URL ảo thực sự tồn tại, nhưng là một thư mục.

MVC đang tạo tệp ảo từ gói của bạn và phân phát tệp đó từ đường dẫn bạn chỉ định làm đường dẫn gói.

Giải pháp đúng cho vấn đề đó là sử dụng đường dẫn gói không trực tiếp ánh xạ tới thư mục hiện có và thay vào đó sử dụng tên tệp ảo (cũng không ánh xạ tới tên tệp thực) bên trong thư mục đó.

Ví dụ:

Nếu trang web của bạn có một thư mục có tên/content/css, làm bó css của bạn như sau:

Trong BundleConfig.cs:

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

Và trên trang:

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

Lưu ý rằng điều này giả định bạn KHÔNG có tệp có tên AllMyCss.css trong css f của bạn lớn hơn.

+0

Vâng, đây là vấn đề, cảm ơn. – sed

+6

Sẽ không đặt gói tại một thư mục không tồn tại gây ra các vấn đề với các tham chiếu tương đối trong CSS? http://devwhib.blogspot.com/2012/08/mvc-4-bundles-where-are-my-css.html – gidmanma

+0

+1 Cảm ơn. Chỉ cần giải quyết vấn đề của tôi là tốt. – ryanulit

3

Điều đó có vẻ đúng với tôi. Khi tối ưu hóa được kích hoạt, bạn sẽ chỉ có một ref duy nhất và nó sẽ là tên bạn đã chỉ định trong StyleBundle (/ content/css). Trong chế độ gỡ lỗi (hoặc cụ thể hơn với debug = false trong cấu hình web của bạn), bạn sẽ nhận được các tệp không được tối ưu hóa như bình thường. Nếu bạn nhìn, bạn sẽ thấy chúng chỉ là văn bản thuần túy khi bạn nhập chúng. Tuy nhiên, khi tối ưu hóa được bật (thường là khi bạn chạy trong chế độ phát hành), bạn sẽ nhận được một URL tìm kiếm đáng sợ thay thế.

Nếu bạn nhìn vào đầu ra của nó, nó sẽ được rút gọn. Chuỗi truy vấn? V = 5KLoJ .... dựa trên giá trị băm của các tệp trong gói. Điều này là để tham chiếu có thể được lưu trữ HTTP một cách an toàn cho tới chừng nào bạn muốn. Mãi mãi nếu bạn ưa thích, nhưng tôi nghĩ rằng mặc định là một năm. Tuy nhiên, nếu bạn sửa đổi bất kỳ bảng định kiểu nào của bạn, nó sẽ tạo ra một băm mới và đó là "bộ nhớ cache-busting", do đó bạn sẽ nhận được một bản sao mới trên trình duyệt.

Có nói tất cả điều đó, tôi không chắc chắn lý do tại sao bạn nhận được 404. Tôi nghi ngờ có liên quan đến cấu hình định tuyến hoặc thiết lập IIS của bạn. Bạn đang chạy trong Visual Studio với IISExpress?

+0

Tôi đang chạy VS2010 bằng máy chủ phát triển ASP.NET (tích hợp một để thử nghiệm/gỡ lỗi). – sed

+0

Bạn có đang gọi EnableDefaultBundles() không? Nếu không, có vẻ như các URL của bạn không được chuyển qua - hãy thử thay đổi chế độ của hồ bơi ứng dụng thành "tích hợp". – cirrus

26

Tôi không chắc liệu đó có phải là tối ưu hóa web hay WebGrease rất cầu kỳ nhưng một (hoặc cả hai) trong số đó là và bạn cần phải hết sức cẩn thận.

Trước hết không có gì là sai với mã của bạn:

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

Trong thực tế đây là chính xác những gì Microsoft làm. Lý do chính họ không sử dụng ~/bundles cho css là đường dẫn tương đối bị làm hỏng hình ảnh. Hãy suy nghĩ về cách trình duyệt của bạn nhìn thấy một gói - chính xác giống như cách nó thấy bất kỳ URL nào khác và tất cả các quy tắc liên quan đến đường dẫn thông thường vẫn áp dụng đối với các đường dẫn tương đối. Hãy tưởng tượng css của bạn có đường dẫn hình ảnh đến ../images/bullet.png. Nếu bạn đang sử dụng ~/bundles trình duyệt sẽ tìm trong một thư mục ở trên bundles không thực sự tồn tại. Nó có thể sẽ kết thúc tìm kiếm trong ~/images nơi bạn có thể có nó trong ~/content/images.

Tôi đã tìm thấy một vài điều mà thực sự có thể phá vỡ nó và gây ra 404 lỗi:

  • FYI: cấu trúc thư mục của tôi là Content/CSS trong đó có một thư mục images cho hình ảnh CSS.
  • Tôi có EnableOptimizations=true để buộc sử dụng các bó trong khi thử nghiệm
  • Điều đầu tiên bạn nên làm là 'View Source' và chỉ cần nhấp vào các liên kết css để xem họ làm việc

Hãy nói rằng chúng tôi đang phát triển một trang web về mèo. Bạn có thể có điều này

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

này tạo ra một liên kết CSS để con đường này trong HTML của bạn:

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

Tuy nhiên điều này sẽ cung cấp cho 404 vì tôi đặt một .css mở rộng và IIS (tôi nghĩ) được bối rối.

Nếu tôi thay đổi nó để này sau đó nó hoạt động tốt:

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

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

Một vấn đề khác đã chỉ ra bởi những người khác là bạn không phải làm

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

nếu bạn có một thư mục css hoặc tập tin (có khả năng bạn không có tệp có tên là css không có tiện ích mở rộng) trong thư mục Content của bạn.

Một mẹo nữa là bạn cần phải chắc chắn HTML được tạo của bạn có một số phiên bản

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

Nếu không và trông như thế này, thì có thể bạn không có một kết hợp chính xác cho tên gói giữa bảng Bundle và trong tệp cshtml của bạn.

<link href="/Content/css/cats" rel="stylesheet"/> 
+0

tôi 'không chắc chắn nếu tôi đang đọc sai ở đây, nhưng có vẻ như bạn đang đề xuất 'mới StyleBundle (" ~/content/css ")' là tốt và được đề nghị, nhưng cũng không phải là tốt nếu bạn có một ' Thư mục css' trong thư mục 'content' của bạn (đó là một thiết lập khá chuẩn) –

+1

Đó là câu trả lời đúng –

+0

@MattMitchell thực sự đó là những gì OP nói, vì vậy tôi đã giải thích lý do tại sao nó gây ra lỗi và tại sao bạn không nên 't có nó được đặt tên như vậy. –

3

Tôi vừa giải quyết một vấn đề tương tự. Vấn đề là như sau, tôi đã cài đặt 'đã chọn' qua NuGet. Và trong lớp BundleConfig, dòng bao gồm các tập tin CSS trông như thế này:

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

Một số nơi xuống trong lớp học mà tôi đã có dòng này:

BundleTable.EnableOptimizations = true; 

Việc sửa chữa là để kết hợp 2 bundles.Add() giống như vậy:

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

Và điều đó đã sửa nó cho tôi.

+0

'BundleTable.EnableOptimizations = true;' đã làm các trick! – rotgers

4

Đừng quên đảm bảo gói HttpModule có sẵn.

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

Điều này khiến tôi lần đầu tiên xung quanh. Bạn không chắc chắn liệu cấu hình cần thiết có nên được thêm vào bởi gói NuGet hay không, nhưng nó không nằm trong trường hợp của tôi.

0

Cũng có thể do bạn chưa triển khai bundleconfig.json cho máy chủ vì một số lý do.

Các vấn đề liên quan