Asp.net 主题中CSS文件的缓存问题
在Asp.net中,如果使用了主题,在CSS文件变化的后,如果文件没有变更名称,浏览器还是使用旧的CSS文件,造成页面变形,只有手动清理浏览器缓存来解决这个问题。
有没有办法使主题中css文件动态加入一个版本号呢?
有人可能说,手动在链接上加个版本号不就解决了。
但是,如果网站已经上线了,要修改链接很困难,有很多地方已经引用。
经过搜索还真有这样的解决方案,使用Asp.net 2.0 提供的扩展动PageAdapter,使用这个方式动态注入代码到页面的生命周期中,代码如下:
Code Snippet
- protectedoverridevoid OnPreRender(EventArgs e)//css,htmllink
- {
- foreach (var link in Page.Header.Controls.OfType<HtmlLink>().ToList()
- .Where(link => link.Attributes["type"].EqualsIgnoreCase("text/css"))
- .Where(link => link.Attributes["href"].ContainsIgnoreCase("/App_Themes/{0}/".Fill(Page.Theme))))
- {
- link.Href += string.Format("?t={0}", Version);
- }
- foreach (var link in Page.Header.Controls.OfType<LiteralControl>().ToList()) //script,LiteralControl
- {
- if (link.Text.ContainsIgnoreCase("text/javascript"))
- if (link.Text.ContainsIgnoreCase("<script"))
- link.Text = link.Text.ReplaceIgnoreCase(".js", ".js?t={0}".Fill(Version));
- }
- base.OnPreRender(e);
- }
其实上面实现很简单,就是查询出页面控件“header”中,加入的CSS文件和JS文件动态的在文件尾部一个版本号。
完成代码如下:
Code Snippet
- publicclassScriptCssPageAdapter : System.Web.UI.Adapters.PageAdapter
- {
- static ScriptCssPageAdapter()
- {
- Version = System.Configuration.ConfigurationManager.AppSettings["ResourceVersion"];
- if (string.IsNullOrEmpty(Version))
- {
- Version = DateTime.Now.Ticks.ToString(CultureInfo.InvariantCulture);
- }
- }
- privatestaticreadonlystring Version;
- protectedoverridevoid OnPreRender(EventArgs e)//css,htmllink
- {
- foreach (var link in Page.Header.Controls.OfType<HtmlLink>().ToList()
- .Where(link => link.Attributes["type"].EqualsIgnoreCase("text/css"))
- .Where(link => link.Attributes["href"].ContainsIgnoreCase("/App_Themes/{0}/".Fill(Page.Theme))))
- {
- link.Href += string.Format("?t={0}", Version);
- }
- foreach (var link in Page.Header.Controls.OfType<LiteralControl>().ToList()) //script,LiteralControl
- {
- if (link.Text.ContainsIgnoreCase("text/javascript"))
- if (link.Text.ContainsIgnoreCase("<script"))
- link.Text = link.Text.ReplaceIgnoreCase(".js", ".js?t={0}".Fill(Version));
- }
- base.OnPreRender(e);
- }
- }
- publicstaticclassStringExtent
- {
- publicstaticbool EqualsIgnoreCase(thisstring str, string tagert)
- {
- returnString.Compare(str, tagert, StringComparison.OrdinalIgnoreCase) == 0;
- }
- publicstaticbool ContainsIgnoreCase(thisstring str, string target)
- {
- return str.ToUpperInvariant().Contains(target.ToUpperInvariant());
- }
- publicstaticstring Fill(thisstring str, paramsobject[] formats)
- {
- returnstring.Format(str, formats);
- }
- publicstaticbool EndWithIgnoreCase(thisstring str, string target)
- {
- return str.ToUpper().EndsWith(target.ToUpper());
- }
- publicstaticbool StartWithIgnoreCase(thisstring str, string target)
- {
- return str.ToUpper().StartsWith(target.ToUpper());
- }
- publicstaticstring ReplaceIgnoreCase(thisstring str, string source, string target)
- {
- return str.ToLower().Replace(source.ToLower(), target.ToLower());
- }
- }
在web页面中使用方法:
首先在其中加入一个浏览设置文件(a.browser):
内容如下:
<!-- You can find existing browser definitions at <windir>\Microsoft.NET\Framework\<ver>\CONFIG\Browsers --> <browsers> <browser refID="Default"> <controlAdapters> <adapter controlType="System.Web.UI.Page" adapterType="AspNetScriptCssVersionControl.ScriptCssPageAdapter,AspNetScriptCssVersionControl" /> </controlAdapters> </browser> </browsers>
完成配置。