9

Tôi đang làm việc với một số gói động có thêm tệp CSS và JS dựa trên cấu hình.Web.Optimizations - bất kỳ cách nào để có được tất cả bao gồm từ một gói Style/Script?

Tôi quay lên một StyleBundle mới như rằng:

var cssBundle = new StyleBundle("~/bundle/css"); 

Sau đó lặp qua cấu hình và thêm bất kỳ Đã tìm thấy bao gồm:

cssBundle.Include(config.Source); 

Sau khi vòng lặp Tôi muốn kiểm tra xem thực sự có bất kỳ tập tin/thư mục bao gồm. Tôi biết có EnumerateFiles() nhưng tôi không nghĩ rằng 100% này phục vụ cho mục đích.

Bất kỳ ai khác đã thực hiện bất kỳ điều gì tương tự trước đây?

Trả lời

13

Lớp Bundle sử dụng danh sách các mục nội bộ không được tiếp xúc với ứng dụng và không nhất thiết có thể truy cập được qua phản chiếu (Tôi đã thử và không thể lấy bất kỳ nội dung nào) . Bạn có thể lấy một số thông tin về vấn đề này bằng cách sử dụng lớp BundleResolver như vậy:

var cssBundle = new StyleBundle("~/bundle/css"); 
cssBundle.Include(config.Source); 

// if your bundle is already in BundleTable.Bundles list, use that. Otherwise... 
var collection = new BundleCollection(); 
collection.Add(cssBundle) 

// get bundle contents 
var resolver = new BundleResolver(collection); 
List<string> cont = resolver.GetBundleContents("~/bundle/css").ToList(); 

Nếu bạn chỉ cần một số sau đó:

int count = resolver.GetBundleContents("~/bundle/css").Count(); 

Chỉnh sửa: sử dụng phản ánh

Rõ ràng tôi đã làm một cái gì đó sai với thử nghiệm phản chiếu của tôi trước đây.

này thực sự hoạt động:

using System.Reflection; 
using System.Web.Optimization; 

... 

int count = ((ItemRegistry)typeof(Bundle).GetProperty("Items", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(cssBundle, null)).Count; 

Bạn có lẽ nên thêm một số kiểm tra an toàn có tất nhiên, và cũng giống như rất nhiều ví dụ về phản ánh này vi phạm an toàn đích của Items bất động sản, nhưng nó không làm việc.

+0

Cảm ơn Corey có vẻ tốt, chỉ có vấn đề tôi có là gói được thêm vào bộ sưu tập để nội dung của nó được tính. Lý tưởng nhất là tôi muốn kiểm tra nội dung để đảm bảo có> 0 TRƯỚC KHI thêm vào bộ sưu tập. Điều đó có ý nghĩa? – timothyclifford

+0

Bạn có thể sử dụng ví dụ phản chiếu để lấy số đếm, hoặc tạo một bộ sưu tập mới (và tạm thời) như tôi đã làm trong mẫu mã ban đầu ở trên và sử dụng 'BundleResolver' để lấy danh sách các tệp được bao gồm. Gói không có sẵn cho phần còn lại của hệ thống cho đến khi bạn thêm nó vào bộ sưu tập 'BundleTable.Bundles', vì vậy bạn có thể sử dụng một trong hai phương pháp để kiểm tra gói trước khi làm cho nó luôn sẵn sàng. – Corey

+0

Không phải là ItemRegistry nội bộ? – timothyclifford

1

Bạn có thể sử dụng các phương pháp khuyến nông sau cho Bundle:

public static class BundleHelper 
{ 
    private static Dictionary<Bundle, List<string>> bundleIncludes = new Dictionary<Bundle, List<string>>(); 
    private static Dictionary<Bundle, List<string>> bundleFiles = new Dictionary<Bundle, List<string>>(); 

    private static void EnumerateFiles(Bundle bundle, string virtualPath) 
    { 
     if (bundleIncludes.ContainsKey(bundle)) 
      bundleIncludes[bundle].Add(virtualPath); 
     else 
      bundleIncludes.Add(bundle, new List<string> { virtualPath }); 

     int i = virtualPath.LastIndexOf('/'); 
     string path = HostingEnvironment.MapPath(virtualPath.Substring(0, i)); 

     if (Directory.Exists(path)) 
     { 
      string fileName = virtualPath.Substring(i + 1); 
      IEnumerable<string> fileList; 

      if (fileName.Contains("{version}")) 
      { 
       var re = new Regex(fileName.Replace(".", @"\.").Replace("{version}", @"(\d+(?:\.\d+){1,3})")); 
       fileName = fileName.Replace("{version}", "*"); 
       fileList = Directory.EnumerateFiles(path, fileName).Where(file => re.IsMatch(file)); 
      } 
      else // fileName may contain '*' 
       fileList = Directory.EnumerateFiles(path, fileName); 

      if (bundleFiles.ContainsKey(bundle)) 
       bundleFiles[bundle].AddRange(fileList); 
      else 
       bundleFiles.Add(bundle, fileList.ToList()); 
     } 
    } 

    public static Bundle Add(this Bundle bundle, params string[] virtualPaths) 
    { 
     foreach (string virtualPath in virtualPaths) 
      EnumerateFiles(bundle, virtualPath); 

     return bundle.Include(virtualPaths); 
    } 

    public static Bundle Add(this Bundle bundle, string virtualPath, params IItemTransform[] transforms) 
    { 
     EnumerateFiles(bundle, virtualPath); 
     return bundle.Include(virtualPath, transforms); 
    } 

    public static IEnumerable<string> EnumerateIncludes(this Bundle bundle) 
    { 
     return bundleIncludes[bundle]; 
    } 

    public static IEnumerable<string> EnumerateFiles(this Bundle bundle) 
    { 
     return bundleFiles[bundle]; 
    } 
} 

Sau đó chỉ cần thay thế Include() cuộc gọi của bạn với Add():

var bundle = new ScriptBundle("~/test") 
    .Add("~/Scripts/jquery/jquery-{version}.js") 
    .Add("~/Scripts/lib*") 
    .Add("~/Scripts/model.js") 
    ); 

var includes = bundle.EnumerateIncludes(); 
var files = bundle.EnumerateFiles(); 

Nếu bạn cũng đang sử dụng IncludeDirectory(), chỉ cần hoàn thành ví dụ bằng cách thêm phương thức mở rộng AddDirectory() tương ứng.

+1

Phương pháp 'EnumerateFiles' thực sự được tích hợp vào lớp Bundle. Nó sẽ trả về một danh sách các đối tượng BundleFile, cung cấp cho bạn quyền truy cập không chỉ đường dẫn của mỗi tệp, mà còn cả các tệp IItemTransform của mỗi tệp, nếu có, được áp dụng. – Triynko

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