如何防止 Web 浏览器缓存 Silverlight XAP 文件?
我想这样做的原因是在开发过程中我不想手动清除浏览器缓存,我正在寻找一种编程方法服务器端。
如何防止 Web 浏览器缓存 Silverlight XAP 文件?
我想这样做的原因是在开发过程中我不想手动清除浏览器缓存,我正在寻找一种编程方法服务器端。
使用 IIS 管理添加一个自定义标头Cache-Control
,其值为no-cache
. 这将导致浏览器在使用之前检查 XAP 的任何缓存版本是否为最新版本。
将查询参数添加到 HTML 页面上元素中 XAP 的 URL:
它将被忽略并破坏缓存。在 IE8 中,有一些缓存管理工具: 打开开发者工具:
这里介绍的解决方案有点类似于 Michael 的解决方案,但它是自动的,并保证客户总是会得到一个新版本。根据您的情况,这可能效率低下。
由于 Lars 在他的评论中说他不在 Stack Overflow 上,所以我在这里复制回复。
<object id="Xaml1" data="data:application/x-silverlight-2,
"type="application/x-silverlight-2" width="100%" height="100%">
<%––<param name="source" value="ClientBin/SilverlightApp.xap"/>––%>
<%
string orgSourceValue = @"ClientBin/SilverlightApp.xap";
string param;
if (System.Diagnostics.Debugger.IsAttached)
{
param = "<param name=\"source\" value=\"" + orgSourceValue + "\" />";
}
else
{
string xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + orgSourceValue;
DateTime xapCreationDate = System.IO.File.GetLastWriteTime(xappath);
param = "<param name=\"source\" value=\"" + orgSourceValue + "?ignore=" +
xapCreationDate.ToString() + "\" />";
}
Response.Write(param);
%>
....
</object>
创建用于处理 *.xap 文件的自定义 http 处理程序,然后在处理程序中设置缓存选项。
像这样的东西...
using System;
using System.IO;
using System.Web;
public class FileCacheHandler : IHttpHandler
{
public virtual void ProcessRequest(HttpContext context)
{
if (File.Exists(context.Request.PhysicalPath))
{
DateTime lastWriteTime = File.GetLastWriteTime(filePath);
DateTime? modifiedSinceHeader = GetModifiedSinceHeader(context.Request);
if (modifiedSinceHeader == null || lastWriteTime > modifiedSinceHeader)
{
context.Response.AddFileDependency(filePath);
context.Response.Cache.SetLastModifiedFromFileDependencies();
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.TransmitFile(filePath);
context.Response.StatusCode = 200;
context.Response.ContentType = "application/x-silverlight-app";
context.Response.OutputStream.Flush();
}
else
{
context.Response.StatusCode = 304;
}
}
}
public DateTime? GetModifiedSinceHeader(HttpRequest request)
{
string modifiedSinceHeader = request.Headers["If-Modified-Since"];
DateTime modifiedSince;
if (string.IsNullOrEmpty(modifiedSinceHeader)
|| modifiedSinceHeader.Length == 0
|| !DateTime.TryParse(modifiedSinceHeader, out modifiedSince))
return null;
return modifiedSince;
}
}
我在 xap 文件的路径中添加了一个查询参数,以便我可以通过版本控制对其进行管理。
默认.aspx代码:
<param
name="source"
value="ClientBin/MySilverLightApp.xap?xapid<%=XapID %>" />
Default.aspx.cs代码:
protected string XapID
{
get
{
Version v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
if (System.Diagnostics.Debugger.IsAttached)
Response.Write(string.Format("Build: {0}.{1}.{2}.{3}", v.Major.ToString(), v.Minor.ToString(), v.Build.ToString(), v.Revision.ToString()));
return string.Format("{0}.{1}.{2}.{3}", v.Major.ToString(), v.Minor.ToString(), v.Build.ToString(), v.Revision.ToString()
}
}
好吧,上面所有的例子都依赖于浏览器没有缓存包含新技巧 xap 名称的 HTML ......所以你只需将问题转移到其他东西上。而且它们也非常复杂......
但是对于调试的情况,至少,在javascript中编写<object>和<param>标签是很容易的,这样每次使用html页面时名称都会改变,无论它是否被浏览器缓存!
<script type="text/javascript">
document.write('<object blah blah >');
document.write('<param name="Source" value="myapp.xap?'
+ new Date().getTime()+'">');
document.write('</object>');
</script>
这避免了您在控制服务器设置时可能遇到的任何麻烦,并且无论使用何种服务器技术都可以正常工作。
注意:您必须使用相同的方法编写整个对象组,因为在对象标签内放置一个脚本标签意味着“只有在浏览器不支持该对象时才这样做。
遇到 .XAP 缓存并不少见,这意味着每次部署新版本的 Silverlight 应用程序时,浏览器都不会下载更新的 .XAP 文件。
一种解决方案可能是更改 IIS 属性。您可以按照以下步骤为您的 .XAP 文件打开“启用内容过期 HTTP 标头”选项:
这样,当您刷新页面时,无需关闭浏览器即可下载最新的 .XAP(仅当有最新的 .XAP 文件时)。
希望这可以帮助!