2010-06-09 54 views
7

我們正在試圖讓下面的情況下工作:追加VERSIONNUMBER到ASP:ScriptManager的compositescript標籤

我們用asp:ScriptManager的/ CompositeScripts到我們的腳本合併爲幾個腳本塊,但每次使用後部署到測試系統,我們沒有得到更新版本的css和javascript(瀏覽器緩存)的測試人員遇到麻煩。對於CSS,我們定義了我們自己的CSS用戶控件,它將一個Siteversion參數「?v = 1.0.190」添加到css url中。此站點版本在web.config/appsettings中定義,並且在每次部署時都會遇到。

我們希望能夠對JavaScript使用相同的策略,但到目前爲止我還沒有取得任何成功。 呈現腳本標記時。使用ScriptManager呈現

<script src="/ScriptResource.axd?d=..." type="text/javascript"></script> 

鑑於當前配置siteversion爲1.0.190,我希望它渲染

<script src="/ScriptResource.axd?d=...&v=1.0.190" type="text/javascript"></script> 

我如何從腳本管理器「腳本」輸出HTML,所以我可以改變它? 它似乎並不存在於渲染渲染的東西,RenderChildren和RenderControl

此致 安德烈亞斯

+0

-1你打開一個賞金,你甚至不選擇一個答案,即使有工作!態度很糟糕。 – Aristos 2010-06-21 13:22:03

回答

3

在你的頁面的onload一個更簡單的解決方案的工作對我蠻好:

ScriptManager.GetCurrent(this).CompositeScript.Path += "?v=" + MyBuildNumber.Value; 
+0

先生,您是天才 – AndreasKnudsen 2011-01-19 07:12:21

1

我會建議一個diferent aproche。 chache是​​你的問題,然後改變緩存Header。 這是我製作和測試它的一個例子,它的作品很好。在對呼叫的最開始在Global.asax ...

protected void Application_BeginRequest(Object sender, EventArgs e) 
{ 
    HttpApplication app = (HttpApplication)sender; 

    string cTheFile = HttpContext.Current.Request.Path; 

    if (cTheFile.EndsWith("ScriptResource.axd", StringComparison.InvariantCultureIgnoreCase)) 
    { 
     // here is the trick with your version ! 
     string etag = "\"" + app.Context.Request.QueryString.ToString().GetHashCode().ToString() + "1.0.190" + "\""; 
     string incomingEtag = app.Request.Headers["If-None-Match"]; 

     app.Response.Cache.SetETag(etag); 

     if (String.Compare(incomingEtag, etag) == 0) 
     { 
      app.Response.StatusCode = (int)System.Net.HttpStatusCode.NotModified; 
      app.Response.StatusDescription = "Not Modified";        
     } 
     else 
     { 
      app.Response.Cache.SetExpires(DateTime.UtcNow.AddMinutes(1)); 
      app.Response.Cache.SetMaxAge(new TimeSpan(0, 1, 0)); 
      app.Response.Cache.SetCacheability(HttpCacheability.Public); 
     } 
    } 
} 
+1

該方法的問題在於,那麼瀏覽器最終只會在Web服務器上進行大量不必要的往返操作,以確定該文件自上次以來未被修改。在一個非平凡的網站上,這可能會對網站的性能產生重大影響(往返=差)。使用版本化url的好處是你可以非常積極地緩存腳本,並且只在腳本更新時(通過增加版本號)強制瀏覽器往返。 – Andy 2010-06-22 03:52:36

4

我在反射周圍挖了一下,看起來這是不幸中添加一件棘手的事情。 MS沒有提供我能找到的任何好的擴展點。但是,如果你願意訴諸一個很好的反思黑客,加入以下的ControlAdapter爲ScriptManager的應該做的伎倆:

public class VersionedScriptManagerAdapter : ControlAdapter 
{ 
    protected new ScriptManager Control 
    { 
     get { return (ScriptManager) base.Control; } 
    } 

    protected override void OnPreRender(System.EventArgs e) 
    { 
     base.OnPreRender(e); 

     var compositeScriptField = Control.GetType().GetField("_compositeScript", 
                   BindingFlags.NonPublic | BindingFlags.Instance); 
     var currentCompositeScript = Control.CompositeScript; 
     var versionedCompositeScript = new VersionedCompositeScriptReference(); 
     CopyCompositeScript(currentCompositeScript, versionedCompositeScript); 
     compositeScriptField.SetValue(Control, versionedCompositeScript); 
    } 

    private void CopyCompositeScript(CompositeScriptReference sourceCompositeScript, CompositeScriptReference targetCompositeScript) 
    { 
     targetCompositeScript.Path = sourceCompositeScript.Path; 
     targetCompositeScript.ResourceUICultures = sourceCompositeScript.ResourceUICultures; 
     targetCompositeScript.ScriptMode = sourceCompositeScript.ScriptMode; 
     foreach (var scriptReference in sourceCompositeScript.Scripts) 
     { 
      targetCompositeScript.Scripts.Add(scriptReference); 
     } 
    } 

    private class VersionedCompositeScriptReference : CompositeScriptReference 
    { 
     protected override string GetUrl(ScriptManager scriptManager, bool zip) 
     { 
      string version = ConfigurationManager.AppSettings["ScriptVersion"]; 
      return base.GetUrl(scriptManager, zip) + "&v=" + version; 
     } 
    } 
} 

然後掛接該控制適配器,您將需要創建一個Web.browser文件並將其放入網站上的App_Browsers文件夾中。該Web.browser文件應該是這樣的:

<browsers> 
    <browser refID="Default"> 
     <controlAdapters> 
     <adapter controlType="System.Web.UI.ScriptManager" 
      adapterType="MyNamespace.VersionedScriptManagerAdapter"> 
     </adapter> 
     </controlAdapters> 
    </browser> 
</browsers> 

我測試了這一點,它爲我工作。我希望它對你有幫助。

+0

+1 Andy我投你的答案,因爲它更接近問題,並且因爲如果忘記選擇一個,它會更好。 – Aristos 2010-06-21 11:25:47

+0

不知何故,我的Web.browser片段沒有成爲我原來的帖子。下面是它會是什麼樣子: \t <瀏覽器REFID = 「默認」> \t \t \t \t \t <適配器controlType = 「System.Web.UI.ScriptManager」 適配器類型=「myNameSpace對象。 VersionedScriptManagerAdapter「/> \t \t \t Andy 2010-06-21 15:54:09

+0

這個代碼終於它不工作!我認爲它需要更多的工作和測試。 – Aristos 2010-06-24 07:06:21