Answered Controlling cache expiration of Service.svc/js

  • viernes, 27 de marzo de 2009 18:09
     
     
    Hello,

    Environment VS 2008, .NET 3.5, Windows 2003 Server

    I'm calling WCF Service decorated with
    <OperationContract()> _
    <WebGet(RequestFormat:=WebMessageFormat.Xml)> _

    from web page script manager.
    <asp:ScriptManager ID="SM" runat="server" >
    <Services>                    <asp:ServiceReference Path="~/
    Service.svc" />         </Services>     </asp:ScriptManager>

    The Service proxy file http://MYSERVER/AJAXWCF/Service.svc/js is
    generated with caching header of expire immediately
    HTTP/1.0 Expires Header is present: Tue, 10 Mar 2009 22:17:49 GMT

    The web.config have debug=false

    I don't want to embed the script into my page, I want it in separate
    cached JS file with one year expiration same as scriptresource.axd JS
    files or better with configurable cache expiration. Is there any way
    to control cache expiration of Service.svc/js

    Regards

Todas las respuestas

  • lunes, 30 de marzo de 2009 10:22
     
     Respondida
    The "Expires" and "Last-Modified" headers are hardcoded by WCF, if your service is hosted inside IIS, you could try writing a custom IHttpModule to modify the HTTP response as follows:

    public sealed class JavascriptCacheabilityModule : IHttpModule
    {
        private HttpApplication app;
        public void Init(HttpApplication context)
        {
            app = context;
            app.EndRequest += new EventHandler(EndRequest);
        }

        private void EndRequest(object sender, EventArgs e)
        {
            var path = app.Context.Request.Path.ToLower().Replace('\\', '/');
            if (path.EndsWith(".svc/js"))
            {
                var lastModified = DateTime.UtcNow;
                var expires = lastModified + TimeSpan.FromDays(365);

                app.Context.Response.Cache.SetLastModified(lastModified);
                app.Context.Response.Cache.SetExpires(expires);
                app.Context.Response.Cache.SetCacheability(HttpCacheability.Public);
            }
        }

        public void Dispose()
        {
            app.BeginRequest -= EndRequest;
            app = null;
        }
    }

    You need to configure the HTTP module as follows:
    <system.web>
      <httpModules>
        <add name="JavascriptCacheabilityModule" type="RestService.JavascriptCacheabilityModule, RestService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </httpModules>
    </system.web>

    <system.webServer>
      <modules>
        <add name="JavascriptCacheabilityModule" type="RestService.JavascriptCacheabilityModule, RestService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
      </modules>
    </system.webServer>

    Hope this helps

    Another Paradigm Shift
    http://shevaspace.blogspot.com
    • Marcado como respuesta Marco Zhou jueves, 02 de abril de 2009 9:54
    •  
  • viernes, 15 de mayo de 2009 19:12
     
     
    Thank you. just verified that it really work for WCF ScriptService
    Unfortunately it doesn't work for asmx scriptservice

    The asmx script service always override expires header to one year ago as described in following post.
    http://forums.asp.net/p/1423422/3164625.aspx

    Any idea how to make it work with ASMX beside migrating to WCF?
  • martes, 13 de marzo de 2012 14:43
     
     

    Try the  below property also with the header

    context.Response.Cache.SetMaxAge(

    TimeSpan.FromDays(5));