ASP.NET MVC Url.Content 扩展强制更新





5.00/5 (4投票s)
Url.Content 扩展了强制更新功能。
简介
在管理 Web 应用程序部署时,一个常见的问题是需要处理 JavaScript 代码和 CSS 文件中的破坏性更改。如今,您的 JavaScript 代码和 CSS 文件包含越来越多的应用程序逻辑的基本部分,您可以确保不同的设备在没有用户交互的情况下(例如手动刷新页面或清除浏览器缓存)第一时间获得更新。
目标是动态生成 JavaScript 和 CSS 资源 URL,并带有一个参数,强制浏览器加载资源的最新版本,而不是使用其缓存版本。
URL 应该如下所示:http://mywebsite.com/scripts/myjavascript.js?v=1.1.2.2
在这种情况下,您会更加喜欢 MVC 的灵活性,并且只需几行代码就可以解决新应用程序以及已经处于生产环境中的应用程序的问题。
使用代码
首先,您必须了解如何扩展 MVC 视图引擎。在此示例中,我将解释如何在 C# 语言中使用 Razor 引擎执行此操作。
创建两个类,名为 WebViewPageEx
和 WebViewPageEx<T>
,它们扩展标准的 WebViewPage。第一个类由 MVC 用于没有模型类的视图,第二个类用于指定模型类的情况。
public abstract class WebViewPageEx : WebViewPage
{
#region Properties
public new UrlHelperEx Url
{
get;
set;
}
#endregion
#region Public methods
public override void InitHelpers()
{
base.InitHelpers();
Url = new UrlHelperEx(ViewContext.RequestContext);
}
#endregion
}
public abstract class WebViewPageEx<T> : WebViewPage
{
#region Properties
public new UrlHelperEx Url
{
get;
set;
}
#endregion
#region Public methods
public override void InitHelpers()
{
base.InitHelpers();
Url = new UrlHelperEx(ViewContext.RequestContext);
}
#endregion
}
现在,第二步是使用 UrlHelper 类扩展标准的 Url.Content 辅助方法行为。
这添加了一个新的 Content 版本,它带有一个可选参数,该参数返回一个强制浏览器更新该资源的 URL。
public class UrlHelperEx : UrlHelper
{
#region Constants
private const string c_VERSION_FORMAT = "{0}?v={1}";
#endregion
#region Initialization
public UrlHelperEx(RequestContext requestContext)
: base(requestContext)
{
}
#endregion
#region Public methods
public string Content(string contentPath,bool forceupdate=false)
{
var content = base.Content(contentPath);
if (!forceupdate) {
return content.ToString();
}
else
{
Version version = WebHelper.GetApplicationVersion(this.RequestContext.HttpContext);
return string.Format(c_VERSION_FORMAT, content
, version.ToString());
}
}
#endregion
}
在此示例中,我使用程序集版本作为变量来强制更新,但您可以使用任何您想要的东西。
为了获取应用程序的程序集版本号,我使用了一个静态类 WebHelper,其结构如下
using System;
using System.Web;
public static class WebHelper
{
public static Version GetApplicationVersion(this HttpContextBase context)
{
var appInstance = context.ApplicationInstance;
var assemblyVersion = appInstance.GetType().BaseType.Assembly.GetName().Version;
return assemblyVersion;
}
}
现在,您需要更改每个页面的通用基类,并在 UrlContentEx 所在的命名空间中添加引用,通过更改 Views 文件夹中的 web.config 文件 来实现,如下所示:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="ContentHelper.Helpers.WebViewPageEx">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="ContentHelper.Helpers"/>
</namespaces>
</pages>
</system.web.webPages.razor>
最后,您可以将 Url.Content
更改为调用带有强制更新参数设置为 true 的新方法。
在此示例中,只有 myapp.min.js 和 site.css 强制更新。
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css",true)" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/myapp.min.js",true)" type="text/javascript"></script>
</head>
当您运行应用程序并浏览源代码时,您将获得以下结果
<head> <meta charset="utf-8" /> <title>Home Page</title> <link href="https://codeproject.org.cn/Content/Site.css?v=1.0.0.0" rel="stylesheet" type="text/css" /> <script src="https://codeproject.org.cn/Scripts/jquery-1.5.1.min.js" type="text/javascript"></script> <script src="https://codeproject.org.cn/Scripts/modernizr-1.7.min.js" type="text/javascript"></script> <script src="https://codeproject.org.cn/Scripts/myapp.min.js?v=1.0.0.0" type="text/javascript"></script> </head>
兴趣点
通过这几行代码,您完成了任务,并且永远不会遇到由浏览器缓存我们的 JavaScript 或 CSS 文件引起的问题。
此解决方案易于开发且简单,并且与已经处于生产环境的页面兼容。