24

如何防止 Web 浏览器缓存 Silverlight XAP 文件?

我想这样做的原因是在开发过程中我不想手动清除浏览器缓存,我正在寻找一种编程方法服务器端。

4

7 回答 7

26

使用 IIS 管理添加一个自定义标头Cache-Control,其值为no-cache. 这将导致浏览器在使用之前检查 XAP 的任何缓存版本是否为最新版本。

于 2010-02-17T15:58:53.157 回答
8

将查询参数添加到 HTML 页面上元素中 XAP 的 URL:

  • clientBin/MyApp.xap?rev=1
  • clientBin/MyApp.xap?rev=2

它将被忽略并破坏缓存。在 IE8 中,有一些缓存管理工具: 打开开发者工具:

  • 尝试缓存...始终从服务器刷新
  • 尝试缓存...清除此域的浏览器缓存...
于 2010-02-17T15:41:08.533 回答
6

这里介绍的解决方案有点类似于 Michael 的解决方案,但它是自动的,并保证客户总是会得到一个新版本。根据您的情况,这可能效率低下。

由于 Lars 在他的评论中说他不在 Stack Overflow 上,所以我在这里复制回复。

<object id="Xaml1" data="data:application/x-silverlight-2,
    "type="application/x-silverlight-2" width="100%" height="100%">

  <%––&lt;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>
于 2011-05-25T19:31:43.137 回答
5

创建用于处理 *.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;
    }
}
于 2011-02-14T21:17:34.830 回答
5

我在 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()
    }
}
于 2013-01-29T16:55:01.683 回答
2

好吧,上面所有的例子都依赖于浏览器没有缓存包含新技巧 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>

这避免了您在控制服务器设置时可能遇到的任何麻烦,并且无论使用何种服务器技术都可以正常工作。

注意:您必须使用相同的方法编写整个对象组,因为在对象标签内放置一个脚本标签意味着“只有在浏览器不支持该对象时才这样做。

于 2011-06-23T20:59:09.950 回答
2

遇到 .XAP 缓存并不少见,这意味着每次部署新版本的 Silverlight 应用程序时,浏览器都不会下载更新的 .XAP 文件。

一种解决方案可能是更改 IIS 属性。您可以按照以下步骤为您的 .XAP 文件打开“启用内容过期 HTTP 标头”选项:

  1. 打开 IIS 管理器
  2. 转到“默认网站”并为您的 Silverlight 项目找到网站。
  3. 在 ClientBin 下找到 .XAP 文件。
  4. 转到 .XAP 文件的属性页面,在 HTTP Headers 选项卡上,打开“Enable Content Expiration”,单击“Expire Immediately”单选按钮。
  5. 保存更改。

这样,当您刷新页面时,无需关闭浏览器即可下载最新的 .XAP(仅当有最新的 .XAP 文件时)。

希望这可以帮助!

于 2013-08-19T06:55:39.060 回答