因此,我读到了这个堆叠溢出柱关于CSS/JS文件的ASP.NET MVC中的“自动版本控制”的内容,并想知道什么是“最好”的策略。
所提供的解决方案插入一个程序集编号--这意味着每次发布时--它将更改每个不理想的文件,因为如果您只修改了一个*.css或*.js,那么它将更改每个文件。
1)如何仅针对“单个文件”而不使用修改日期或在IIS7上使用站点范围的程序集?
2)另外,如果我有某种“静态”资产,比如- http://static.domain.com/js/123.js --如果有人将静态链接集成到他们的站点上,我如何使用重写来发送请求的最新文件?
也就是说,http://static.domain.com/js/123.js是链接,当请求出现时-检查并发送最新的文件?
发布于 2013-03-02 17:08:49
ASP.NET 4.5+提供了一个 内置捆绑和小型化框架 ,旨在解决这个问题。
如果您绝对需要一个简单的滚动自己的解决方案,您可以使用下面的答案,但我总是说正确的方式是使用捆绑和缩小框架。
您可以修改AssemblyInfo.cs文件如下:
Change
[assembly: AssemblyVersion("1.0.0.0")]
to
[assembly: AssemblyVersion("1.0.*")]
这意味着每次构建该项目时,它都会有一个比前一个版本更高的新的程序集版本。现在您有了唯一的版本号。
创建一个UrlHelperExtension类,在视图中需要时帮助获取该信息:
public static class UrlHelperExtensions
{
public static string ContentVersioned(this UrlHelper self, string contentPath)
{
string versionedContentPath = contentPath + "?v=" + Assembly.GetAssembly(typeof(UrlHelperExtensions)).GetName().Version.ToString();
return self.Content(versionedContentPath);
}
}
现在,您可以轻松地以下列方式向视图添加版本号:
<link href="@Url.ContentVersioned("style.css")" rel="stylesheet" type="text/css" />
当查看您的页面源时,您现在将看到如下所示
<link href="style.css?v=1.0.4809.30029" rel="stylesheet" type="text/css" />
发布于 2015-12-08 07:48:41
更新:以前的版本没有在Azure上工作,我已经简化并修正了下面的内容。(注意,要想在IIS的开发模式下工作,您需要安装来自http://www.iis.net/downloads/microsoft/url-rewrite的WebPi重写2.0 -它使用WebPi安装程序,确保首先关闭Visual )
如果您想要更改文件的实际名称,而不是附加一个查询字符串(静态文件的某些代理/浏览器忽略它),您可以遵循以下步骤:(我知道这是一个旧帖子,但我在开发解决方案时遇到了它:
如何做到这一点:每次构建项目时,自动增加程序集版本,并将该数字用于要刷新的特定资源上的路由静态文件。(因此,something.js作为一些东西包含在v1234.js中,在每次生成项目时,1234都会自动更改)--我还添加了一些额外的功能,以确保在生产中使用.min.js文件,在调试时使用regular.js文件(我正在使用WebGrease来自动化细化过程)这个解决方案的一个好处是它可以在本地/ dev模式以及生产模式下工作。(我正在使用Visual 2015 /NET4.6,但我相信这在早期版本中也适用。
步骤1:当在AssemblyInfo.cs文件中构建程序集时,启用了程序集上的自动增量(可在项目的“属性”部分中找到,更改如下行:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
至
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
步骤2:在web.config中为带有嵌入版本段塞的文件重新编写url (参见步骤3)
在web.config (项目的主要部分)中,在<system.webServer>
部分中添加以下规则,我将其直接放在</httpProtocol>
结束标记之后。
<rewrite>
<rules>
<rule name="static-autoversion">
<match url="^(.*)([.]v[0-9]+)([.](js|css))$" />
<action type="Rewrite" url="{R:1}{R:3}" />
</rule>
<rule name="static-autoversion-min">
<match url="^(.*)([.]v[0-9]+)([.]min[.](js|css))$" />
<action type="Rewrite" url="{R:1}{R:3}" />
</rule>
</rules>
</rewrite>
步骤3:安装应用程序变量以读取当前程序集版本,并在js和css文件中创建版本段塞。
在Global.asax.cs中(在项目的根目录中找到),将以下代码添加到受保护的Application_Start()中(在寄存器行之后)
// setup application variables to write versions in razor (including .min extension when not debugging)
string addMin = ".min";
if (System.Diagnostics.Debugger.IsAttached) { addMin = ""; } // don't use minified files when executing locally
Application["JSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.','0') + addMin + ".js";
Application["CSSVer"] = "v" + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString().Replace('.', '0') + addMin + ".css";
步骤4:使用我们在Global.asax.cs中设置的应用程序变量更改Razor视图中的src链接
@HttpContext.Current.Application["CSSVer"]
@HttpContext.Current.Application["JSVer"]
例如,在我的_Layout.cshtml中,在head部分,我为样式表提供了以下代码块:
<!-- Load all stylesheets -->
<link rel='stylesheet' href='https://fontastic.s3.amazonaws.com/8NNKTYdfdJLQS3D4kHqhLT/icons.css' />
<link rel='stylesheet' href='/Content/css/main-small.@HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/medium.@HttpContext.Current.Application["CSSVer"]' />
<link rel='stylesheet' media='(min-width: 700px)' href='/Content/css/large.@HttpContext.Current.Application["CSSVer"]' />
@RenderSection("PageCSS", required: false)
这里需要注意以下几点: 1)文件上没有扩展名。2)也不存在.min。这两者都是由Global.asax.cs中的代码处理的。
同样,(也用_Layout.cs)在我的javascript部分:我有以下代码:
<script src="~/Scripts/all3bnd100.min.js" type="text/javascript"></script>
<script src="~/Scripts/ui.@HttpContext.Current.Application["JSVer"]" type="text/javascript"></script>
@RenderSection("scripts", required: false)
第一个文件是我用WebGrease手动创建的所有第三方库的包。如果我添加或更改包中的任何文件(这是非常罕见的),则手动将文件重命名为all3bnd101.min.js、all3bnd102.min.js等.此文件与重写处理程序不匹配,因此将一直在客户端浏览器上缓存,直到手动重新绑定/更改名称为止。
第二个文件是ui.js (它将以ui.v12345123.js或ui.v12345123.min.js的形式编写,取决于您是否在调试模式下运行),它将被处理/重写。(您可以在Application_OnBeginRequest of Global.asax.cs中设置一个断点来观察它的工作情况)
关于此问题的详细讨论见:简化ASP.NET MVC 5中Javascript / CSS的自动版本控制,以停止缓存问题(适用于Azure和本地),无论是否重写 (包括一种无需URL重写的方法)
发布于 2011-09-23 04:14:05
1)使用文件修改时间。下面是一个例子:
public static string GeneratePathWithTime(string cssFileName)
{
var serverFilePath = server.MapPath("~/static/" + cssFileName);
var version = File.GetLastWriteTime(serverFilePath).ToString("yyyyMMddhhmmss");
return string.Format("/static/{0}/{1}", version, cssFileName);
}
这将为"style.css
“生成像”style.css
“这样的路径(假设style.css
位于static
目录中)。然后在IIS中添加重写规则,将"/static/201109231100/style.css
“重写为"/static/style.css
”。版本号仅在css文件被修改后才会更改,并且仅适用于已修改的文件。
2)您可以通过HttpModule将请求处理到123.js并发送其最新内容,但我认为您不能保证请求获得最新版本。这取决于浏览器如何处理其缓存。您可以在响应头中设置一个较早的过期时间(例如,一分钟前),告诉浏览器始终重新下载文件,但这完全取决于浏览器本身是否重新下载该文件。这就是为什么每次更新您的问题1中的文件时,我们都需要为修改过的文件生成不同的路径),如果以前从未访问过URL,浏览器总是会尝试下载该文件。
https://stackoverflow.com/questions/5818799
复制相似问题