因為最近jquery頻頻更新,每次使用Nuget更新完後,又要改一些_Layout,忘了改又會照成頁面錯誤,而且我們的專案是使用預編譯,所以_Layout也是在dll中,為了更新View使用的javascript版本,我要改View、編譯、佈署dll與js檔,實在有夠麻煩的,所以就想了一個小方法,只要把js檔放在~/Scripts下,程式執行時,就會搜尋資料夾使用最新版的js檔,減少更新的步驟,也減少出錯的可能。
因為最近jquery頻頻更新,每次使用Nuget更新完後,又要改一些_Layout,忘了改又會照成頁面錯誤,而且我們的專案是使用預編譯,所以_Layout也是在dll中,為了更新View使用的javascript版本,我要改View、編譯、佈署dll與js檔,實在有夠麻煩的,所以就想了一個小方法,只要把js檔放在~/Scripts下,程式執行時,就會搜尋資料夾使用最新版的js檔,減少更新的步驟,也減少出錯的可能。
使用範例
用法跟MVC一模一樣,只要將@Url.Content換成@Url.Script,將檔名版本部分的地方用替換成 * 符號,且不用打~/Scripts/因為程式預設(本來想寫多載的,但後來想想在MVC下不會換路徑,就不寫活了)。
<!--使用jquery的min版最新版-->
<script src="@Url.Script("jquery-*.min.js")" type="text/javascript"></script>
<!--使用jquery的min版最新版,但限定在1.6中最新版-->
<script src="@Url.Script("jquery-1.6.*.min.js")" type="text/javascript"></script>
<!--使用fancyboxy的pack版最新版-->
<script src="@Url.Script("jquery.fancybox-*.pack.js")" type="text/javascript"></script>
MVC 2.0寫法
<script src="<%=Url.Script("jquery-1.6.*.min.js")%>" type="text/javascript"></script>
注意:找不到檔案我是丟Expection。
原始碼
using System.Text.RegularExpressions;
using System.Runtime.Caching;
namespace System.Web.Mvc
{
public static class JavascriptExtensions
{
/// <summary>
/// 使用最新版的Script,規則是name-version.extension,輸入時請轉成name-*.extension,如jquery-*.min.js。
/// 只會找Scripts資料夾下
/// </summary>
/// <param name="helper"></param>
/// <param name="script">Script名稱,如:jquery-*.min.js</param>
/// <returns></returns>
public static string Script(this UrlHelper helper, string scriptPattern)
{
//TODO 下一版 要監視資料夾,有變動要清快取
//使用.Net 4.0的System.Runtime.Caching,記得加入參考
string path = MemoryCache.Default[scriptPattern] as string;
if (path == null)
{
//如果沒有就不需要換
if (scriptPattern.IndexOf('*') > -1)
{
string scriptRegex = scriptPattern.Replace("*", "[.0-9]+");
string root = helper.RequestContext.HttpContext.Server.MapPath("~/Scripts/");
foreach (var filePath in Directory.EnumerateFiles(root, scriptPattern, SearchOption.AllDirectories))
{
//先用Directory過濾後再用Regex過濾
string filename = filePath.Remove(0, root.Length);
filename = filename.Replace(@"\\", "/"); //怕有子目錄
if (!Regex.IsMatch(filename, scriptRegex))
{
continue;
}
if (path == null)
{
path = filename; //第一次
}
else if (path.CompareTo(filename) < 0)
{
path = filename; //比大小
}
}
if (path == null)
{
throw new ArgumentException("找不到檔案,Pattern為:" + scriptPattern);
}
//換成虛擬路徑
path = helper.Content("~/Scripts/" + path);
}
else
{
path = scriptPattern;
}
var policy = new CacheItemPolicy();
policy.AbsoluteExpiration = DateTime.Now.AddHours(1);
MemoryCache.Default.Set(scriptPattern, path, policy);
}
return path;
}
}
}
有任何使用上的問題歡迎告訴我。