2014-05-22 11 views
12

Sadece eksik bir javascript dosyası nedeniyle bir hata takip ettim, sessizce başarısız oldu.Asp.Net MVC Bundling, eksik dosyayı tespit etmek için en iyi yol

Dosyanın küçültülmüş sürümü mevcuttu, ancak tam sürüm değil, istemcide bir bağlantı oluşturulmadı (beklediğim) ancak bir istisna da bulamıyorum. Dosyanın mevcut olmadığını bilmek istiyorum.

(minified versiyonunu dahil etmeye çalışmadı demeti, bu tam sürümünü içerecek şekilde çalıştı, ama küçültülmüş versiyonu komut dizininde mevcuttu açık konuşmak gerekirse)

ben yazmak zorunda mı Bunu saptamak için özel bir şey mi var, yoksa MVC'nin bunu rapor etmek için herhangi bir şeyi var mı?

sayesinde

+0

İstemcide hangi bağlantı oluşturulmadı? Paketleme noktası, dosya sayısını azaltmaktır, böylece 'BundleTable.EnableOptimizations = false;' ile tanılama modunu etkinleştirmedikçe, istemcide her grupta bir dosya alırsınız. Bu ayar ile istekleri Fiddler2 ile görüntüleyebilir ve eksik komut dosyalarını görebilirsiniz. –

+0

Bu http://stackoverflow.com/questions/20869907/ adresini deneyin. Mesele, küçültülmüş versiyonu olmamalıdır. En azından bir, '.min.js' olmadan.Bildiğim kadarıyla, demletme zamanı ** asla ** min kullanır, her zaman –

+0

Radim'e ait minicing yapar, ama bu linkin söylediği şey değil, "... aranacak ve bulunamadıysa, akım minimize edilecektir ", eğer mevcut ise – tony

cevap

23

Ben Bundle için aşağıdaki uzatma yöntemleri kullanarak geldi: Eğer yok

public static class BundleHelper 
{ 
    [Conditional("DEBUG")] // remove this attribute to validate bundles in production too 
    private static void CheckExistence(string virtualPath) 
    { 
     int i = virtualPath.LastIndexOf('/'); 
     string path = HostingEnvironment.MapPath(virtualPath.Substring(0, i)); 
     string fileName = virtualPath.Substring(i + 1); 

     bool found = Directory.Exists(path); 

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

     if (!found) 
      throw new ApplicationException(String.Format("Bundle resource '{0}' not found", virtualPath)); 
    } 

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

     return bundle.Include(virtualPaths); 
    } 

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

Bu şekilde yardımcın yöntemi PreCheck() açıkça çağırmak için. Ayrıca ASP.NET en joker karakterler {version} ve * destekler:

bundles.Add(new ScriptBundle("~/test") 
    .IncludeExisting("~/Scripts/jquery/jquery-{version}.js") 
    .IncludeExisting("~/Scripts/lib*") 
    .IncludeExisting("~/Scripts/model.js") 
    ); 
+0

Yararlı şeyler yaptı! One remark: '(Dosya => re.IsMatch (dosya)) yerine FirstOrDefault() '' FirstOrDefault (dosya => re.IsMatch (dosya)) 'ile değiştirebilirsiniz. – user1068352

0

Bu "anti-pattern" var inanamıyorum! Hata görmüyorsanız, hata yoktur! Her neyse, yukarıdaki çözümü beğeniyorum. Başka bir BundleTable.EnableOptimizations yanlış olduğunda eksik olsa bile link/script çıktı olurdu - bu hata ayıklama yaparken denemek için çok açık bir şey, ve daha sonra hangi tarayıcılar üzerinde çeşitli denetçiler/hata ayıklayıcılar tarayıcılarda açık olacak eksik. Bu, eksik dosyalar olduğunu fark etmeden saatlerce uğraştığım hata ayıklama için böyle bariz bir şey gibi görünüyordu. Başka bir şekilde, paketin eksik kısımlarını sessizce görmezden gelmek o kadar yanlış ki, korkunç hata ayıklama oturumumu güçlendirdi. Travmalar, iki kere ısırmaz - travmalar devam eder.

0

Kodu biraz değiştirdim. Bir hata atmak yerine herhangi bir paket dosyası eklemez.

public class VirtualPathProviderExt : VirtualPathProvider 
{ 
    private readonly VirtualPathProvider _provider; 

    public VirtualPathProviderExt(VirtualPathProvider provider) 
    { 
     _provider = provider; 
    } 

    public override string CombineVirtualPaths(string basePath, string relativePath) 
    { 
     return _provider.CombineVirtualPaths(basePath, relativePath); 
    } 

    public override ObjRef CreateObjRef(Type requestedType) 
    { 
     return _provider.CreateObjRef(requestedType); 
    } 

    public override bool DirectoryExists(string virtualDir) 
    { 
     return _provider.DirectoryExists(virtualDir); 
    } 

    public override bool Equals(object obj) 
    { 
     return _provider.Equals(obj); 
    } 

    private static readonly Regex _ignorePathsRegex = new Regex(@"\.debug\.\w+$|^~/bundle.config$", RegexOptions.IgnoreCase | RegexOptions.Compiled); 

    public override bool FileExists(string virtualPath) 
    { 
     var result = _provider.FileExists(virtualPath); 
     if (!result && !_ignorePathsRegex.IsMatch(virtualPath)) 
     { 
      Logger.Instance.Log(RecType.Error, "Bundle file not found: " + virtualPath); 
     } 

     return result; 
    } 

    public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies, DateTime utcStart) 
    { 
     return _provider.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart); 
    } 

    public override string GetCacheKey(string virtualPath) 
    { 
     return _provider.GetCacheKey(virtualPath); 
    } 

    public override VirtualDirectory GetDirectory(string virtualDir) 
    { 
     return _provider.GetDirectory(virtualDir); 
    } 

    public override VirtualFile GetFile(string virtualPath) 
    { 
     return _provider.GetFile(virtualPath); 
    } 

    public override string GetFileHash(string virtualPath, IEnumerable virtualPathDependencies) 
    { 
     return _provider.GetFileHash(virtualPath, virtualPathDependencies); 
    } 

    public override int GetHashCode() 
    { 
     return _provider.GetHashCode(); 
    } 

    public override object InitializeLifetimeService() 
    { 
     return _provider.InitializeLifetimeService(); 
    } 

    public override string ToString() 
    { 
     return _provider.ToString(); 
    } 
} 

Bundle yardımcı:

public static class BundleHelpers 
{ 
    public static void InitBundles() 
    { 
     if (!(BundleTable.VirtualPathProvider is VirtualPathProviderExt)) 
     { 
      BundleTable.VirtualPathProvider = new VirtualPathProviderExt(BundleTable.VirtualPathProvider); 
     } 
    } 
} 

Ve BundleConfig.cs yılında BundleHelpers.InitBundles() çalıştırmak Eğer BundleTable.VirtualPathProvider sarmalayıcı kullanarak birden fazla proje

public static class BundleHelper 
{ 
    private static bool CheckExistence(string virtualPath) 
    { 
     int i = virtualPath.LastIndexOf('/'); 
     string path = HostingEnvironment.MapPath(virtualPath.Substring(0, i)); 
     string fileName = virtualPath.Substring(i + 1); 

     bool found = Directory.Exists(path); 

     if (found) 
     { 
      if (fileName.Contains("{version}")) 
      { 
       var re = new Regex(fileName.Replace(".", @"\.").Replace("{version}", @"(\d+(?:\.\d+){1,3})")); 
       fileName = fileName.Replace("{version}", "*"); 
       found = Directory.EnumerateFiles(path, fileName).Where(file => re.IsMatch(file)).FirstOrDefault() != null; 
      } 
      else // fileName may contain '*' 
       found = Directory.EnumerateFiles(path, fileName).FirstOrDefault() != null; 
     } 
     return found; 
     //if (!found) 
     //throw new ApplicationException(String.Format("Bundle resource '{0}' not found", virtualPath)); 
    } 

    public static Bundle IncludeExisting(this Bundle bundle, params string[] virtualPaths) 
    { 
     foreach (string virtualPath in virtualPaths) 
      if (CheckExistence(virtualPath)) 
      { 
       bundle.Include(virtualPath); 
      } 

     return bundle; 
    } 

    public static Bundle IncludeExisting(this Bundle bundle, string virtualPath, params IItemTransform[] transforms) 
    { 
     if (CheckExistence(virtualPath)) 
      bundle.Include(virtualPath, transforms); 
     return bundle; 
    } 
} 
1

bir başka yolu için aynı ortak paket yapılandırma kullanıyorsanız bu gereklidir:

public class BundleConfig 
{ 
    public static void RegisterBundles(BundleCollection bundles) 
    { 
     BundleHelpers.InitBundles(); 
     ... 
İlgili konular