14

Below is the code I've currently implemented.

if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey))
{
  ScriptManager scriptManager = ScriptManager.GetCurrent(page);
  if (scriptManager != null && scriptManager.IsInAsyncPostBack)
  {
    //if a MS AJAX request, use the Scriptmanager class
    ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true);
  }
  else
  {
    //if a standard postback, use the standard ClientScript method
    Page.ClientScript.RegisterStartupScript(Page.GetType(), scriptKey, script, true);
  }
}

I'm doing as suggested in this answer so that I can register startup script on both times i.e. when there is partial postback and a full postback.

The problem is Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey) always (even when the script is registered before) returns false when it is partial postback. And I couldn't find ScriptManager.IsStartupScriptRegistered (static) method. As a result of this, additional script is emitted on all partial/async postbacks.

Please note that I'm using script manager of AjaxControlToolkit version 4.1 i.e. ToolkitScriptManager in my masterpage. But I don't thing it has something to do with this.

UPDATE

  <asp:UpdatePanel ID="ContactDetailsUpdatePanel" UpdateMode="Conditional" runat="server">
    <Triggers>
      <asp:AsyncPostBackTrigger ControlID="UpdateContactDetailsButton" EventName="Click" />
    </Triggers>
    <ContentTemplate>
      <div id="ContactDetailsContent" class="contact_details_content">
        <div class="customer_contactdetails_left_pane">
          <div class="customer_name_field">
            <asp:Label ID="CustomerNameLabel" runat="server" Text="Customer" />
            <asp:TextBox ID="CustomerNameValue" runat="server" />
          </div>
          <div class="customer_address_field">
            <asp:Label ID="CustomerAddressLabel" runat="server" Text="Address" />
            <asp:TextBox ID="CustomerAddressValue" runat="server" />
            <asp:TextBox ID="CustomerAddressValue1" runat="server" />
            <asp:TextBox ID="CustomerAddressValue2" runat="server" />
            <asp:TextBox ID="CustomerAddressValue3" runat="server" />
          </div>
          <div class="customer_postcode_field">
            <asp:Label ID="CustomerPostcodeLabel" runat="server" Text="Postcode" />
            <asp:TextBox ID="CustomerPostcodeValue" runat="server" />
          </div>
        </div>
        <div class="customer_contactdetails_right_pane">
          <div>
            <asp:Label ID="CustomerContactLabel" runat="server" Text="Contact" />
            <asp:TextBox ID="CustomerContactValue" runat="server" />
          </div>
          <div>
            <asp:Label ID="CustomerTelephoneLabel" runat="server" Text="Telephone" />
            <asp:TextBox ID="CustomerTelephoneValue" runat="server" />
          </div>
          <div>
            <asp:Label ID="CustomerMobileLabel" runat="server" Text="Mobile" />
            <asp:TextBox ID="CustomerMobileValue" runat="server" />
          </div>
          <div>
            <asp:Label ID="CustomerFaxLabel" runat="server" Text="Fax" />
            <asp:TextBox ID="CustomerFaxValue" runat="server" />
          </div>
          <div>
            <asp:Label ID="CustomerEmailLabel" runat="server" Text="Email" />
            <asp:TextBox ID="CustomerEmailValue" runat="server" />
          </div>
          <div>
            <asp:Label ID="CustomerWebLabel" runat="server" Text="Web" />
            <asp:TextBox ID="CustomerWebValue" runat="server" />
          </div>
        </div>
      </div>
      <div class="update_button_field">
        <asp:Button ID="UpdateContactDetailsButton" runat="server" Text="Update" 
          onclick="UpdateContactDetailsButton_Click" />
      </div>          
    </ContentTemplate>    
  </asp:UpdatePanel>

Thanks in advance.

NOTE: To be able to understand the progress on this problem, please see the comments on this answer before replying.

UPDATE
I have implemented a temporary solution to this problem by putting a check in javascript that if the script is already executing then do not execute twice. Javascript is still being spitted multiple times on every partial postback. Couldn't prevent it.

As the views to this post are increasing, I can see that there are other people who might also want answer to this problem.

Community
  • 1
  • 1
IsmailS
  • 10,797
  • 21
  • 82
  • 134

6 Answers6

10

If you are using this;

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "noPasswordMatch", script, true);

Then to check if it has been registered you must use this:

if (Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "noPasswordMatch"))

if (Page.ClientScript.IsClientScriptBlockRegistered("noPasswordMatch")) doesn't work!

IsmailS
  • 10,797
  • 21
  • 82
  • 134
Dave
  • 101
  • 1
  • 3
4

I ran into this same issue when writing a composite control in ASP.Net. When the control was inside an update panel Page.ClientScript.IsStartupScriptRegistered didnt work. From within the method protected override void CreateChildControls() i was doing something like

ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true);

Hence I ran into a situation similar to what you describe here. What solved my problem was passing the control and its type instead of the page and page type to ScriptManager.RegisterStartupScript. Hence the code now looks,

ScriptManager.RegisterStartupScript(this, this.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true);

Once I did this change I no longer needed to check Page.ClientScript.IsStartupScriptRegistered. Now my control works with or without update panels. No unnecessary js spitouts either. Hope this helps

Harindaka
  • 4,658
  • 8
  • 43
  • 62
2

I had implemented a temporary solution to this problem by putting a check in javascript that if the script is already executing then do not execute twice. Javascript is still being spitted multiple times on every partial postback. Couldn't prevent it.

IsmailS
  • 10,797
  • 21
  • 82
  • 134
2

I've written an extension method to check whether the script has already been registered with the ScriptManager. You can use the same principle to check startup scripts:

public static bool IsClientScriptBlockRegistered(this ScriptManager sm, string key)
        {
            ReadOnlyCollection<RegisteredScript> scriptBlocks = sm.GetRegisteredClientScriptBlocks();

            foreach (RegisteredScript rs in scriptBlocks)
            {
                if (rs.Key == key)
                    return true;
            }

            return false;
        } 
Phil Hale
  • 3,453
  • 2
  • 36
  • 50
  • +1 Looks good. But I don't know if it will work even if client scripts are previously registered in AsyncPostBacks with the same key. I will have to check before I accept it as answer. – IsmailS Nov 17 '10 at 11:38
  • I tried it and it does not remember ones from previous partialpostacks. – jheizer Nov 20 '14 at 19:41
1

Keep in mind your first line of code is the inverse of the method return value because of the !.

if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey))

If IsStartupScriptRegistered is returning false as you say, then the if statement should evaluate true because of the !. This should cause the script to be registered as expected.

Your code is based on my answer here, which was based on ASP.NET AJAX 1.0 and ASP.NET 2.0. It may have something to do with .NET 3.5, although I believe I've used the above already in a newer project we did under 3.5 and it worked fine...

Can you post some markup to go with the code?

EDIT: Thanks for posting the markup.

I notice 2 things now:

You mentioned you are using ToolkitScriptManager. It is a control that inherits from ScriptManager. I didn't notice this before, but your code is still referencing ScriptManager directly. You said it was during async postbacks that the script isn't working, which leads me to believe it is an issue with your reference to ScriptManager. I've never used ToolkitScriptManager before so I can't give you exact code, but I can tell you that you'll likely need to update your code-behind, changing all references to ScriptManager and its methods/properties to the equivalent in ToolkitScriptManager.

Try adding a breakpoint on the if statement and make sure it's evaluation to true. I wouldn't be surprised if scriptManager is null, or scriptManager.IsInAsyncPostBack is false because you're using ToolkitScriptManager.

ScriptManager scriptManager = ScriptManager.GetCurrent(page);
if (scriptManager != null && scriptManager.IsInAsyncPostBack)
{
  //if a MS AJAX request, use the Scriptmanager class
  ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true);
}

Lastly - Your markup looks okay, other than you don't need the <Triggers> section. Triggers allow you to specify control which are outside of your update panel to cause partial renders. Any child control of the update panel within the <ContentTemplate> section will do this automatically. The button you are targeting in the Triggers section is already within the updatepanel. While I don't think this is the cause of your issue, I'd remove it anyway.

Hope this helps.

Community
  • 1
  • 1
KP.
  • 13,218
  • 3
  • 40
  • 60
  • I think there isn't any problem with `!` as I only want to register the script when it is **not** registered already. Yes my code is based on your answer. It's already mentioned in my question. Thanks for the assistance again. I will post markup when I go to office on Monday. I don't have it right now. Basically post back is done by a button within an update panel which is inside TabContainer of AjaxControlToolkit. – IsmailS May 15 '10 at 07:02
  • @Ismail ok I've posted an update to my answer. I think your problem is you are referencing ScriptManager when you're using ToolkitScriptManager. (see above) – KP. May 19 '10 at 18:00
  • @KP! I think you are getting confused. `scriptManager.IsInAsyncPostBack` is working fine but `Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey)` is always returning false in a partial post back. I kept a break point and have seen the evaluation also. I can change the logic appropriately later but the main problem here is I need to find out within a partial post back that my script is already registered or not. And that is when it is always saying me that its not registered even when it is actually registered. – IsmailS May 20 '10 at 06:22
  • When i say `ScriptManager scriptManager = ToolkitScriptManager.GetCurrent(page);` , Resharper gives me a warning `Access to a static member of a type via a derived type`. I hope you got what it means. – IsmailS May 20 '10 at 06:25
  • @Ismail - `Page.ClientScript.IsStartupScriptRegistered` should be returning false. This is the expected behavior. I was just noting it because in your original question, you were pointing to it as a potential problem for why the script wasn't working. If the script isn't registered, then the registration happens. – KP. May 20 '10 at 15:51
  • The warning is because you are calling the static method `GetCurrent` via ToolkitScriptManager, however that method is a static method of the base ScriptManager. – KP. May 20 '10 at 15:54
  • This answer has also not helped me. – IsmailS Jul 01 '10 at 06:17
  • Sorry then there is nothing else I can do to help. As I said, I believe the fact you are using the AjaxToolkit's script manager is the issue. Your first code snippet in your question I believe is taken from another answer I posted to another question. That code block was written for use with the standard ScriptManager, not ToolkitScriptManager. You need to either fall back to using the standard asp.net scriptmanager, or modify the code to work with the ToolkitManager. – KP. Jul 02 '10 at 13:23
  • This one specifically: http://stackoverflow.com/questions/1952817/asp-net-javascript-inside-ajax-updatepanel/1953122#1953122. Again it's not designed for ToolkitScriptManager and needs to be altered to do so. – KP. Jul 02 '10 at 13:26
0

Did you mean this: ClientScriptManager.IsStartupScriptRegistered Method

egrunin
  • 24,650
  • 8
  • 50
  • 93
  • Please go to http://stackoverflow.com/questions/1952817/asp-net-javascript-inside-ajax-updatepanel/1953122#1953122 to understand the whole problem. Page.ClientScript.IsStartupScriptRegistered() gives me this http://msdn.microsoft.com/en-us/library/62d1676x.aspx only. And it always returns false in case of partial post backs. – IsmailS May 13 '10 at 13:15
  • This didn't helped me. I don't know who voted this up. I'm already using this method and it is mentioned in my question. – IsmailS Jul 01 '10 at 06:16