ScriptManager多次向页面添加脚本(重复)

时间:2010-12-03 15:27:09

标签: c# asp.net scriptmanager

这与5月份未答复的this完全相同。

(编辑)注意:this未回复的帖子准确描述了行为 - 由UpdateManager中的用户控件中的ScriptManager.RegisterClientScriptBlock在<head>中添加的额外脚本导致重复。 C#.NET 4.0。页面结构如下:

MasterPage
   Page
      UserControl1 (ascx) - loaded in code by Page
         UpdatePanel
            UserControl2 (ascx) - loaded in code by UserControl1

第一次在正文中按预期添加脚本。简单地说,代码在UserControl2 OnInit:

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);

我也尝试引用“this”而不是page,这实际上没有意义,因为如果在页面上多次加载usercontrol,我不希望在页面上重复相同的脚本键,但它无论如何都没有用。

在部分回发之后,脚本会再次添加 - 但奇怪的是在页面的<head>,而不是正文,有趣的是,缺少asp.net通常添加的普通//<![CDATA[...//]]>包装器。

UserControl1添加的另一个脚本在部分回发后的重复方式完全相同。

有谁知道为什么会这样?

3 个答案:

答案 0 :(得分:3)

您可以添加一个检查以确认脚本是否已经注册,然后再次注册。

if (!Page.ClientScript.IsClientScriptRegistered (Page.GetType(), "myscript"))
   ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);

我希望这会有所帮助。

答案 1 :(得分:3)

虽然我找不到关于这种或那种方式的讨论,但似乎ScriptManager是无状态的。因此,在部分回发中添加具有相同标记的脚本将导致重复。在实践中(对我来说)这在很多时候都不是理想的行为,因为人们会认为你在具有相同标签的UserControl中多次注册的任何脚本都是重复的,不应该重新注册。如果你真的想要注册一个新的脚本(例如,部分回发之后发生的事情),我认为你应该要求它为ScriptManager提供一个新标签,以便再次注册它。

我的解决方案是创建一个自定义ScriptManager,用于UserControls,它具有仅在第一次加载控件时注册脚本并使用ViewState维护状态信息的方法。也就是说,我保留了一个仅用于第一次注册的脚本的标签列表,并将其保留在回发中,并且仅重新注册该列表中找不到的脚本。只是对用户控件的一般支持并且只应该注册一次的脚本会以这种方式进行跟踪。

我不能只使用IsPostBack的原因是我有时使用Page.LoadControl动态加载usercontrols。无法保证在第一次加载整个页面时加载控件。也就是说,它可以在回发时第一次加载。因此,如果我刚使用IsPostBack,脚本可能永远不会被注册。

答案 2 :(得分:2)

您是否尝试使用简单的IsPostBack子句在页面的Init / Load / PreRender / Render函数中包装代码?这将阻止它在第一页加载后注册脚本。

if(!IsPostBack)
{
    ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);
}