我剛剛追趕了一個由於缺少JavaScript文件而導致的錯誤,這是一次失敗的沉默。Asp.Net MVC捆綁,檢測丟失文件的最佳方式
該文件的縮小版本存在,但不是完整版本,客戶端上沒有呈現鏈接(我期待)但我也沒有得到例外。我想知道該文件是否不存在。
(僅僅是明確的,捆綁沒有嘗試包括縮小的版本,它試圖包含完整版,但縮小的版本是在腳本目錄存在)
我必須寫自定義來檢測這個或MVC是否有內置的報告?
感謝
我剛剛追趕了一個由於缺少JavaScript文件而導致的錯誤,這是一次失敗的沉默。Asp.Net MVC捆綁,檢測丟失文件的最佳方式
該文件的縮小版本存在,但不是完整版本,客戶端上沒有呈現鏈接(我期待)但我也沒有得到例外。我想知道該文件是否不存在。
(僅僅是明確的,捆綁沒有嘗試包括縮小的版本,它試圖包含完整版,但縮小的版本是在腳本目錄存在)
我必須寫自定義來檢測這個或MVC是否有內置的報告?
感謝
我想出了使用下面的擴展方法Bundle
:
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);
}
}
這樣你就不必打電話給你的helper方法PreCheck()
明確。它還支持ASP.NET的通配符{version}
和*
:
bundles.Add(new ScriptBundle("~/test")
.IncludeExisting("~/Scripts/jquery/jquery-{version}.js")
.IncludeExisting("~/Scripts/lib*")
.IncludeExisting("~/Scripts/model.js")
);
有用的東西!一個備註:你可以用'FirstOrDefault(文件=> re.IsMatch(文件))''替換其中(文件=> re.IsMatch(文件))FirstOrDefault()'。 – user1068352
我無法相信這個「反模式」的存在!如果您看不到任何錯誤,那就沒有錯誤!
無論如何,我喜歡上面的解決方案。另一種方法是輸出鏈接/腳本,即使它在BundleTable.EnableOptimizations爲false時丟失 - 在調試時這是非常明顯的事情,然後在瀏覽器上的各種檢查器/調試器中顯而易見,哪些文件是失蹤。這似乎是一件很明顯的事情,我花了幾個小時纔沒有意識到丟失了文件。另一種方式,默默地忽略了缺失的部分,是非常錯誤的,它加強了我可怕的調試過程。那麼,這不會咬我兩次 - 創傷持久。
我改變了一下代碼。不會拋出錯誤,它不會添加任何包文件。
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();
}
}
捆綁幫手:
public static class BundleHelpers
{
public static void InitBundles()
{
if (!(BundleTable.VirtualPathProvider is VirtualPathProviderExt))
{
BundleTable.VirtualPathProvider = new VirtualPathProviderExt(BundleTable.VirtualPathProvider);
}
}
}
而且在BundleConfig.cs
運行BundleHelpers.InitBundles()
是,如果你使用的是相同的公共束配置多個項目
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;
}
}
另一種方法使用BundleTable.VirtualPathProvider
包裝要求:
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
BundleHelpers.InitBundles();
...
哪個鏈接未在客戶端上呈現?捆綁的重點在於減少文件數量,因此除非您使用'BundleTable.EnableOptimizations = false;'啓用診斷模式,否則客戶端上每捆只能獲取一個文件。通過該設置,您可以使用Fiddler2查看請求並查看任何缺少的腳本。 –
試試這個http://stackoverflow.com/questions/20869907/。關鍵是你應該沒有縮小版本。至少是那個,沒有'.min.js'。據我所知,捆綁運行** **從未使用分鐘,它總是不minifing它itslef –
拉迪姆,謝謝,不過這不是說鏈接什麼,」 ......將被搜索,如果沒有找到,電流將精縮「這表明,如果它的存在將使用它 – tony