7

我们正在尝试使以下方案正常工作:

我们使用 asp:scriptmanager / CompositeScripts 将我们的脚本组合成几个脚本块,但是在每次部署到测试系统之后,我们都会遇到测试人员无法获得更新版本的 css 和 javascript(浏览器缓存)的问题。对于 CSS,我们定义了自己的 css 用户控件,该控件将 Siteversion 参数“?v=1.0.190”附加到 css url 中。此站点版本在 web.config / appsettings 中定义,并且在每次部署时都会受到影响。

我们希望能够对 javascripts 使用相同的策略,但到目前为止我还没有取得任何成功。渲染脚本标签时。Scriptmanager 呈现

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

鉴于当前配置的站点版本是 1.0.190,我希望它呈现

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

如何从脚本管理器获取“脚本”html 输出,以便进行更改?它似乎不存在于 Render、RenderChildren 或 RenderControl 中呈现的内容中

你的 安德烈亚斯

4

3 回答 3

4

我在反射器中挖了一会儿,不幸的是,这似乎是一件棘手的事情。MS 没有提供我能找到的任何好的扩展点。但是,如果您愿意使用一个不错的反射技巧,那么为 ScriptManager 添加以下 ControlAdapter 应该可以解决问题:

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>

我对此进行了测试,它对我有用。我希望它对你有帮助。

于 2010-06-17T05:22:24.900 回答
3

页面加载中的一个更简单的解决方案对我来说很好:

ScriptManager.GetCurrent(this).CompositeScript.Path += "?v=" + MyBuildNumber.Value;
于 2011-01-19T00:30:08.930 回答
1

我会建议一个不同的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);
        }
    }
}
于 2010-06-14T14:03:02.127 回答