Click here to Skip to main content
Click here to Skip to main content
Go to top

AJAX UpdatePanel With Inline Client Scripts Parser

, 9 Oct 2008
Rate this:
Please Sign up or sign in to vote.
AJAX UpdatePanel with inline client scripts parser.

Introduction

This control solves the problem when you need inline client scripts within an ASP.NET UpdatePanel to work. Inline scripts, to my knowledge, are not registered to the Script Manager when the "AJAX call" is made. The problem occurs if you have a UserControl, containing an inline script that is dynamically added into an UpdatePanel after an AJAX postback.

Background

If you, like me, already have (had) an existing Web application that's cluttered with inline scripts, and want to take advantage of the features that ASP.NET AJAX provides, you might find yourself with a tedious refactoring job. I managed to solve 99% (1% was invalid markup) of all my inline script problems by using this control.

Hopefully, it can do the same for you!

Using the Code

The control inherits from the original UpdatePanel and uses a Regex to parse for client scripts. You use it just like the original UpdatePanel, and can switch on/off the parsing for inline scripts by setting the property RegisterInlineClientScripts to false.

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Text.RegularExpressions;
using System.IO;

namespace Tuna.Web.Controls
{
public class TunaUpdatePanel : UpdatePanel
{
    private static readonly Regex REGEX_CLIENTSCRIPTS = new Regex(
    "<script\\s((?<aname>[-\\w]+)=[\"'](?<avalue>.*?)[\"']\\s?)*\\s*>(?<script>.*?)</script>",
    RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled |
    RegexOptions.ExplicitCapture);
    private bool m_RegisterInlineClientScripts = true;

    /// <span class="code-SummaryComment"><summary></span>
    /// If the updatepanel shall parse and append inline scripts, default true
    /// <span class="code-SummaryComment"></summary></span>
    public bool RegisterInlineClientScripts
    {
        get
        {
            return this.m_RegisterInlineClientScripts;
        }
        set
        {
            this.m_RegisterInlineClientScripts = value;
        }
    }

    protected virtual string AppendInlineClientScripts(string htmlsource)
    {
        if (this.ContentTemplate != null && htmlsource.IndexOf(
            "<script", StringComparison.CurrentCultureIgnoreCase) > -1)
        {
            MatchCollection matches = REGEX_CLIENTSCRIPTS.Matches(htmlsource);
            if (matches.Count > 0)
            {
                for (int i = 0; i < matches.Count; i++)
                {
                    string script = matches[i].Groups["script"].Value;
                    string scriptID = script.GetHashCode().ToString();
                    string scriptSrc = "";

                    CaptureCollection aname = matches[i].Groups["aname"].Captures;
                    CaptureCollection avalue = matches[i].Groups["avalue"].Captures;
                    for (int u = 0; u < aname.Count; u++)
                    {
                        if (aname[u].Value.IndexOf("src",
                            StringComparison.CurrentCultureIgnoreCase) == 0)
                        {
                            scriptSrc = avalue[u].Value;
                            break;
                        }
                    }

                    if (scriptSrc.Length > 0)
                    {
                        ScriptManager.RegisterClientScriptInclude(this,
                            this.GetType(), scriptID, scriptSrc);
                    }
                    else
                    {
                        ScriptManager.RegisterClientScriptBlock(this, this.GetType(),
                            scriptID, script, true);
                    }

                    htmlsource = htmlsource.Replace(matches[i].Value, "");
                }

            }
        }
        return htmlsource;
    }

    protected override void RenderChildren(HtmlTextWriter writer)
    {
        ScriptManager sm = ScriptManager.GetCurrent(Page);
        if (this.RegisterInlineClientScripts && sm != null && sm.IsInAsyncPostBack)
        {
            using (HtmlTextWriter htmlwriter = new HtmlTextWriter(new StringWriter()))
            {
                base.RenderChildren(htmlwriter);

                string html;
                int outputSize;

                //Get the actual rendering and size
                html = htmlwriter.InnerWriter.ToString();
                outputSize = html.Length;

                //Append inlinescripts and fetch the new markup and size
                html = this.AppendInlineClientScripts(html);
                outputSize -= html.Length;

                //Replace ContentSize if there are any gains
                if (outputSize > 0)
                {
                    html = this.SetOutputContentSize(html, outputSize);
                }

                writer.Write(html);
            }
        }
        else
        {
            base.RenderChildren(writer);
        }
    }

    private string SetOutputContentSize(string html, int difference)
    {
        string[] split = html.Split('|');
        int size = int.Parse(split[0]);
        split[0] = (size - difference).ToString();
        return string.Join("|", split);
    }
}
}

Optimization suggestions are welcome!

Enjoy!

Thanks to Rogic for solving the issue I hade with replacing the response context to opitmize traffic!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Baxterboom

Sweden Sweden
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 PinmemberMember 825063916-Mar-14 23:31 
GeneralMy vote of 5 PinmemberCyberLight28-Aug-12 1:55 
This realisation of updatepanel was helped me to solve my problem with inline script which is included into updatepanel! Greate! Thx a lot!
Questionthanks Pinmemberparsamiga31-Oct-11 21:12 
GeneralSome improvements PinmemberRogic22-Sep-08 1:37 
GeneralRe: Some improvements PinmemberBaxterBoom7-Oct-08 3:00 
GeneralRe: Some improvements [modified] PinmemberBaxterBoom8-Oct-08 5:34 
AnswerRe: Some improvements PinmemberRogic21-Oct-08 0:49 
GeneralSo close..... PinmemberOwen3713-Dec-07 7:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 9 Oct 2008
Article Copyright 2007 by Baxterboom
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid