如何强制Firefox不缓存或重新下载Silverlight XAP文件?

50

在使用 Silverlight 时,我注意到 Firefox 会缓存 XAP 文件,因此如果我进行更新,用户可能会被困在旧版本中。有没有办法强制浏览器每次重新下载 XAP 文件,或者只在发布更新后强制浏览器重新下载?还是在 Silverlight 配置中有一个停止浏览器缓存 XAP 文件的设置?

谢谢, Jeff


我也遇到了这个问题。本以为我的页面更改没有生效,结果发现我看的是缓存版本。很烦人。 - jcollum
我在SL5上使用以下缓存技巧时遇到了问题,这些技巧在SL4上是可行的,我的问题在这里:https://dev59.com/y1_Va4cB1Zd3GeqPU5ci。 - jv42
我在我的SL5问题上添加了赏金,但似乎没有引起太多关注(https://dev59.com/y1_Va4cB1Zd3GeqPU5ci)。如果有人成功地使用了类似的技巧来处理SL5运行时,我很感兴趣! - jv42
17个回答

32

查询字符串完美地工作,但我不会使用DateTime.Now,因为它会强制用户每次重新下载应用程序。相反,我们使用以下内容:

protected void Page_Load(object sender, EventArgs e)
{
    var versionNumber = Assembly.GetExecutingAssembly().GetName().Version.ToString();
    this.myApp.Source += "?" + versionNumber;
}

这样你只需要在 AssemblyInfo.cs 文件中递增版本号。


这个 Page_Load 事件处理程序是页面的事件处理程序还是 Silverlight 视图的事件处理程序? - bleepzter
这是包含Silverlight <object>的ASP.NET页面。 - jv42

12

最简单的方法:

<param name="source" value="ClientBin/App.xap?<%= DateTime.Now.Ticks %>" />

7
最好使用XAP文件的文件日期。这样,用户就不必每次下载应用程序了。 - FlappySocks
您如何在codebehind中完成此操作,并将其插入到HTML页面中替换DateTime?请提供示例。 - Stephen Price
你可以给param元素一个id和runat="server"属性,以便在代码后台中访问它。假设id="SourceParam":SourceParam.Attributes["value"] += "?" + DateTime.Today.Ticks; - Andy Mehalick

6

这是我在PHP中所做的事情。您可以读取XAP文件的日期/时间,并将其附加为下载链接的参数。通过这种方式,浏览器将新文件版本视为新链接,因此不会缓存。

<?php $fdate = date("dHis",filemtime("MyApp.xap")) ?>

<param name="source" value="MyApp.xap?=<?php echo $fdate ?>"/>

简单易用且可靠。当没有更新需要下载时,浏览器会正确缓存。


5

对我来说,最好的答案来自Chris Cairns。我稍微改编了一下,调用了ToString和GetHashCode,生成一个时间戳的ID:

<param name="source" value="ClientBin/App.xap?<%= System.IO.File.GetLastWriteTime(Server.MapPath("ClientBin/App.xap")).ToString().GetHashCode()%>" />

运行良好!


5

您可能会发现Web作者和站长的缓存教程很有帮助。该文档讨论了客户端和服务器通过哪些缓存进行交互(浏览器、代理、网关),以及如何控制缓存。


这个回答如何解决问题?它没有涉及到XAP文件的具体问题。 - KevDog
3
如果 Timothy Lee Russell 在他的回答中所说的清除 Firefox 缓存可以解决这个问题,那么这意味着 Firefox(而不是 Silverlight 插件)像任何其他 Web 资源一样通过 HTTP 请求文件并使用适用于所有内容的相同规则进行缓存。了解缓存规则可能有所帮助。 - Jason Orendorff

4

您可以发送HTTP头以防止缓存:

Cache-control: no-cache
Pragma: no-cache

这取决于您使用的Web服务器。

3
Timothy: 你必须确保这些HTTP头应用于XAP文件,而不是HTML页面。IIS允许您针对每个文件夹配置自定义头:http://support.microsoft.com/kb/247404 - Jason Orendorff
如果你让用户每次访问你的Silverlight应用程序时都下载完全相同的代码,特别是当你没有进行任何更改时,我敢说你做错了。 - felickz

2
另一种解决方案是附加XAP文件的版本而不是时间戳。时间戳会在每次更改时发生变化(最好关闭缓存)。要使其仅在更新XAP时更改,需要从XAP文件中获取一些信息。我还在研究可以使用什么,也许是XAP文件的上次修改日期戳?

这是最好的解决方案。强迫用户每次使用一个随机的URL下载应用程序,简直太疯狂了。 - FlappySocks

2

对于我来说,为XAP添加时间戳是有效的(我正在使用JavaScript添加SL控件,但这也可以轻松地在内联中完成):

var appTimestamp = '<%= System.IO.File.GetLastWriteTime(Server.MapPath("ClientBin/MyApp.xap")) %>';
var source = 'ClientBin/MyApp.xap?appTimestamp=' + appTimestamp;

2

这经过测试并且可行:

放置这个:

<%
    const string sourceValue = @"ClientBin/MyXapFile.xap";
    string param;

    if(System.Diagnostics.Debugger.IsAttached)
        param = "<param name=\"source\" value=\"" + sourceValue + "\" />";
    else
    {
        var xappath = HttpContext.Current.Server.MapPath(@"") + @"\" + sourceValue;
        var xapCreationDate = System.IO.File.GetLastWriteTime(xappath);

        param = "<param name=\"source\" value=\"" + sourceValue + "?ignore="
        + xapCreationDate + "\" />";
    }
    Response.Write(param);
%>

不要这样:

<param name="source" value="ClientBin/MyXapFile.xap" />

1

您可以在对象标记中附加XAP文件的最后编写日期,以源URL。请查看我的博客上的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接