4

This is the exact same question as this unanswered one from May.

(edit) Note: this unanswered post exactly describes the behavior - extra scripts being added in the <head> by ScriptManager.RegisterClientScriptBlock in a usercontrol, in an UpdatePanel, is causing duplicates. C# .NET 4.0. The page is structured like this:

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

The first time the script is added as expected, in the body. The code, simply, in the UserControl2 OnInit:

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

I've also tried referencing "this" instead of page, which doesn't really make sense since I don't want the same script keys duplicated on the page if the usercontrol is loaded multiple times on a page, but it didn't work anyway.

After a partial postback, the script is added again - but curiously in the <head> of the page, not the body, and interestingly, lacking the normal //<![CDATA[...//]]> wrapper that asp.net usually adds.

Another script which is added by UserControl1 is duplicated exactly the same way after a partial postback.

Does anyone know why this is happening?

7
  • how do you want your script to be registered? when the whole page is generated only? Commented Dec 3, 2010 at 15:38
  • Jsut as a note that question you linked seems to be answered... Commented Dec 3, 2010 at 15:51
  • @Chris sorry you're right it is answered, but that's not my problem, maybe it was his though it wasn't accepted. I am using the same type and key. I did find others asking about this problem elsewhere but no explanations or answers. Commented Dec 3, 2010 at 15:57
  • @akonsu: the script should be registered only when the page is first generated. But since this is inside an updatepanel, the code gets run on every partial postback. I can't just check for "IsPostback" because the usercontrol can be initially loaded on a postback since this is part of a form with other controls, it is most likely going to be loaded on a postback the first time. Commented Dec 3, 2010 at 15:59
  • did you try ScriptManager.RegisterStartupScript? Commented Dec 3, 2010 at 16:50

3 Answers 3

3

You can add a check to confirm if the script has been registered before registering it again.

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

I hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Isn't the whole point of ScriptManager that it does that automatically? And if I registered it with Page.GetType() then Me (I assume you mean "this") would not match the initial registration. I'll try it but doesn't seem to make sense..
no go. checking for registration says it's not already registered. I'm not actually calling the function more than once on any given page load so that makes sense, somehow the registration from the previous partial postbacks is being persisted.
3

Though I can't find much discussion about this one way or the other it seems that ScriptManager is stateless. So adding a script with the same tag across partial postbacks will result in duplicates. In practice (for me) this is not desired behavior a lot of the time, since one would assume that any script you register more than once inside a UserControl with the same tag would be a duplicate and should not be re-registered. If you really wanted to register a new script (as a result of what happened after the partial postback, e.g.) I would think you should be required to give it a new tag for ScriptManager to register it again.

My solution is to create a custom ScriptManager for use in UserControls that has methods that will register a script only the first time the control is loaded and maintain state information with ViewState. That is, I keep a list of tags for scripts intended to be registered only the first time and persist it across postbacks, and only re-register scripts that aren't found in that list. Scripts which are just general support for the usercontrol and should only be registered once are tracked this way.

The reason I can't just use IsPostBack is that I load usercontrols dynamically using Page.LoadControl sometimes. It is not guaranteed that the control will be loaded the first time the whole page is loaded. That is, it could be loaded for the first time on a postback. So if I just used IsPostBack the scripts may never be registered.

Comments

2

Have you tried wrapping your code with simple IsPostBack clause inside the page's Init/Load/PreRender/Render function? This will prevent it from registering the script after the first page load.

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

3 Comments

I can't do this, because a UserControl could be loaded dynamically on the page for the first time after a postback.
Though I can't seem to find any positive documentation of this I believe that this is actually the design of ScriptManager - it doesn't maintain state so "tag" would only prevent duplicates for a given page load. The solution is to extend it with methods that maintain state, but basically you're right.
How does this work if one is using @Scripts.Render("MyASPNETMVC5Bundle")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.