Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

Script Callbacks in ASP.NET 2.0 - interesting, but lacking


:P
On this page:

 

Script callbacks basically allow us to make server side callbacks from client side code dynamically updating the client side HTML document without reposting the entire page. It’s Microsoft mangled vision of AJAX <g>…

 

The concept is pretty cool – the idea is that ASP.NET 2.0 implements an ICallbackEvent interface that can be implemented by a Page or Control which is called back when an event is fired from the client.

 

The simplest implementation of this interface can be handled entirely server side and looks something like the following C# code:

 

public partial class SimpleCallBack : System.Web.UI.Page, ICallbackEventHandler

{

    protected void Page_Load(object sender, EventArgs e)

    {

        this.SetCallBackString();

    }

 

    protected void SetCallBackString()

    {

        // *** Attach the callback handler to the server event

        // *** via Client Event

        string ScriptRef = this.ClientScript.GetCallbackEventReference(

                    this,

                    "document.forms[0].txtCustomerPk.value",

                    "OnCallback",

                    "’MyCallContext’",

                    "OnCallback",

                    true);

        this.txtCustomerPk.Attributes.Add("onchange", ScriptRef);

 

        // *** Create the script that fires in response to the call back on the client

        // *** Normally you'd create this in the HTML code

        this.ClientScript.RegisterClientScriptBlock(this.GetType(),"ClientCallback",

@"

<script type='text/javascript'>

function OnCallback(Result,Context)

{

   alert(Result);

}

</script>

");

       

    }

 

    string ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)

    {

        return "Hello from the Server. Time is: " + DateTime.Now.ToString() +

               "\r\nSelected Pk: " + eventArgument;

    }

}

 

You basically declare the Page or Control to implement the ICallbackEventHandler interface. You then implement the RaiseCallbackEvent method that is called when the client side code fires the event. The method is called in the context of the page so you get all the post data from the client side form sent back to you. The idea is that an event on the client page is delegated back to RaiseCallBackEvent.

 

You also need to call ClientScript.GetCallbackEventReference() which sets up the client script code and attaches the callback handler to the specified control and event. The call above binds the context to this form, sets the parameter that is passed to the server to the client side txtCustomerPK value, to call the OnCallback method in the client script on return, and pass ‘MyCallContext’ as a Context parameter to the OnCallbackmethod, which receives both the result from the server and this context value. Finally I can specify the client function fired if an error occurs (in this case the same function) and whether I want the operation to be asynchronous.

 

 

The flow then goes something like this:

On the HTML form I can select a new a item and onchange fires, which is hooked up to an ASP.NET generated event method which looks like this:

 

onchange="WebForm_DoCallback('__Page',document.forms[0].txtCustomerPk.value,OnCallback,
                             'MyCallContext',OnCallback,true)"

 

 

This method then calls ASP.NET passing the Customer PK as a parameter. On the server side RaiseCallBackEvent fires and receives this single eventArgument as a parameter. From there you can parse the value and return a string result of any sort. In this case I’m simply returning a Hello World message along with the PK.

 

On the client you then have a script method that handles the return value. Here I simply use an alert box to return the result, but you could obviously pass back more complex data, either to parse on the client side or as HTML to be embedded into the document. I placed the script code in the server side code here, but more likely you would actually stick it into the ASPX code so it’s easier to work with especially if there’s a lot of it.

 

Multiple Callbacks

Things get a little more complicated when we’re dealing with multiple callbacks. The problem is that the ICallbackEventHandler interface has a single method and any callback to the page goes back to this single handler. Worse on the server side there's no way to tell which control originated the callback except the control reference passed to GetCallbackEventReference, which routes to the call back to that particular control. In other words, a single handler has no context to tell which control it's dealing with. So if you have multiple events firing on a page it’s quite difficult to differentiate which event or object fired it when using a Page level Callback handler only.


Let’s look at a little more complicated scenario. Let’s say we have a form where we display a customer list. When we select a customer we want to see a list of invoices from that customer in list. And when we click on an invoice we want to see the lineitem detail for the invoice. So this means two script callback handlers.

 

The best way to implement this is to forego a page level CallbackEventHandler and instead use a custom class for each of the events and then delegate the call back to the page. Start by creating a class that implements ICallbackEventHandler and implements a ScriptCallback event (you can add this in the same class file as the ASPX codebehind or create it as a separate reusable class:

 

public delegate string delScriptCallBack(string eventArgument);

 

public class EventControl : Control, ICallbackEventHandler

{

    public event delScriptCallBack ScriptCallback;

 

    string ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)

    {

        if (this.ScriptCallback != null)

            return this.ScriptCallback(eventArgument);

 

        return "Not Implemented";

    }

}

Then for each event you want to handle add a property of this type to the Page:

 

public EventControl InvoiceEventControl = new EventControl();

public EventControl CustomerEventControl = new EventControl();

 

Next we need to hook up the events to client side event handlers. This is the same as in the first example, except that we’re pointing the CallbackEventReference not at the form but at these custom controls:

 

protected void SetupScriptCallback()

{

    // *** Add the Event controls that implement ICallbackEventHandler

    // *** and attach the ScriptCallback event to pass us notifications into this form

    this.CustomerEventControl.ScriptCallback += new delScriptCallBack(CustomerEventControl_ScriptCallback);

    this.AddParsedSubObject(this.CustomerEventControl);

 

    // *** Attach the callback handler to the server event

    // *** via Client Event

    string ScriptRef = this.ClientScript.GetCallbackEventReference(

                this.CustomerEventControl,

                "document.forms[0].txtCustomerPk.value",

                "OnCustomerSelectionCallback",

                "'Customer'",

                "OnCustomerSelectionCallback",

                true);

    this.txtCustomerPk.Attributes.Add("onchange", ScriptRef);

 

    // *** add the Invoice Event Control so we have a separate handler

    this.InvoiceEventControl.ScriptCallback += new delScriptCallBack(InvoiceEventControl_ScriptCallback);

    this.AddParsedSubObject(this.InvoiceEventControl);

 

    ScriptRef = this.ClientScript.GetCallbackEventReference(

            this.InvoiceEventControl,

            "document.forms[0].txtInvoiceList.value",

            "OnInvoiceSelectionCallback",

            "'Invoice'",

            "OnInvoiceSelectionCallback",

            true);

    this.txtInvoiceList.Attributes.Add("onchange", ScriptRef);

}

The code starts by attaching the ScriptCallback event from the control, which routes the script callback from the control back to the form. We want to do this so that we have access to form level members and so that we don’t have to create new controls for each event and handle the event code in the controls (although that is an option if you want to do this to isolate code). In general I like to keep the code inside of the scope of the Page which is one of the advantages of using this mechanism with ASP.NET in the first place.

 

Finally implement the event methods themselves which look just like ICallbackEventHandler methods except that now we’re not implementing the interface, but merely handling the events fired from the eventControl:

 

string CustomerEventControl_ScriptCallback(string eventArgument)

{

    int pk = 0;

 

    int.TryParse(eventArgument, out pk);

    if (pk == 0)

        return "";

 

    string ConnString = ConfigurationManager.ConnectionStrings["WebStoreClient"].ConnectionString;

    SqlCommand Command = wwDataUtils.GetSqlCommand(ConnString, "select pk, invno,invtotal,invdate from wws_invoice where Custpk=@Pk order by InvDate DESC");

    Command.Parameters.AddWithValue("@pk", pk);

    SqlDataReader Reader = Command.ExecuteReader();

 

    StringBuilder Result = new StringBuilder();

    while (Reader.Read())

    {

        // *** Write out the PK

        Result.AppendLine(Reader.GetInt32(0).ToString());

 

        // *** Write out the Text String to display

        Result.AppendLine(Reader.GetDateTime(3).ToString("yyyy-MM-dd") + "   " +

            Reader.GetString(1) + "     " +

            Reader.GetDecimal(2).ToString("c"));

    }

    Reader.Close();

 

    return Result.ToString();

}

 

string InvoiceEventControl_ScriptCallback(string eventArgument)

{

    return "Hello from InvoiceEventControl_ScriptCallback" + DateTime.Now.ToString();

 

}

 

The event handling code from the Customer lookup goes out to the database and retrieves all invoices for a given customer. In this case the invoice data is returned as a list of string pairs where carriage returns break the strings and there are two strings per entry: The Pk string and the Text string which are used for value and text values in the listbox that gets populated. Note that I build the string completely on the server side as it’s easier to return the data ready for use to the client here, rather than parsing the data on the client.

 

The client code contains the following script blocks to handle the events:

 

<script type='text/javascript'>

function OnServerCallback (Result,Context)

{

    //alert(Context + "\r\n\r\n" + Result);

   

    List = document.getElementById('txtInvoiceList')

    if (List)

    {

            while (List.length > 0)

            {   List.remove(0);   }

       

            if( Result.substr(0,6) == 'Error:' )

            {

                alert(Result);

                return; 

            }

           

            //alert("Result:\r\n" + Result);

           

            StringList = Result.split('\r\n');

 

            x = 0;

            while(x < StringList.length) 

            {

                  Pk = StringList[x];

                  if (Pk == '')

                    break;

                  

                  Text = StringList[x+1];

                  AddItem(Text,Pk,List);

                 

                  // *** Skip to the next array item

                  x = x +2;         

            }

    }

}

function AddItem(Text,Value,List)

{

    var opt;

    opt = document.createElement('option');

    opt.value = Value;

    opt.innerText = Text

    List.appendChild(opt);

}

function OnInvoiceSelectionCallback(Result,Context)

{

    Detail = document.getElementById('InvoiceDetail')

    Detail.style.display='';

    Detail.innerHTML = '<pre>' + Result + '</pre>';

   

    //alert("Invoice Callback\r\n" + Result);

}

</script>

 

Script callbacks rely on some sort of client side script code interaction to do something with the data, so the first list parses data out of a 'pseudo-array' returned via strings and then stepping through this array manually peeling out values and stuffing them into the listbox. Certainly this works, but it's time consuming to write even this little bit of Java script code.

 

What kind of data do we send

All of this begs the question how do we efficiently interact between client and server sides? This ‘protocol’ is a pain because it isn’t one! As such the decision on how to pass the data is entirely left up to you - which means lots of us will be reinventing the wheel, going down the wrong paths until we figure out an efficient way to do this.

 

So how do we pass data? Here are a few ideas and  alternatives:

 

Pass custom string formats

This is probably the most labor and error prone mechanism, but likely the route that most people will take given limited tools to pass data around in a more structured manner. This means returning stuff like delimited string lists and converting the to arrays and parsing the data. This is basically the approach I took above with the invoice data. We have the server generate list based data and send it back to the client, then let the client parse it and update the document via DOM access.

 

The biggest issue with this approach is that of error management and sending multiple messages. You need to manage logic both on the client and the server, which may be a good or bad thing.

 

Pass HTML strings from the server

After playing around with this stuff for a while, I’m starting to think that one of the easiest way to pass data back from the server is to simply generate the HTML on the server and have the client page simply inject the HTML into the page using the HTML DOM scripting model.

 

This makes some sense as it allows you to more easily create the content in an environment that’s debuggable and can be maintained reasonably. If necessary you can even use things like Server.Execute() or dynamic ASP.NET control creating to generate the HTML for you and then return it.

 

The downside is that it’s potentially passing more data over the wire than necessary. Obviously HTML is more bulky than plain strings of data.

 

XML

XML is also a good choice if you do need control on the client side in how the data is loaded and presented dynamically. Unfortunately, as mentioned above if you use XML you’re responsible for setting up XML usage in script code in a browser agnostic mechanism. Recent browsers support XMLDOM functionality finally but the syntax to get the objects loaded is different, so this is not transparent. The Client Script engine doesn't provide support for this.

 

 

Create a Serialization Sublayer

Bertrand Le Roy has advocated using a layer ontop of ClientCallbacks in ASP.NET to provide a more high level interface on how to pass data around with a crude serization layer that can manage to serialize parameters and even some objects between client and server. But the solution presented is somewhat complex and requires use of additional controls and classes. This sort of thing should have been baked into ASP.NET 2.0 directly and much more transparently.

It works but…

This sort of thing is really nothing new. I demo’d stuff like this using XMLHttp back in 1999 doing dynamic SQLdata insertion in pages. What’s new is that this layer and many of the AJAX libraries out there abstract away a lot of the monotonous and repetitive code so the inner workings are hidden away from you.

 

On a very simple level the ASP.NET 2.0 implementation succeeds, but I think that this implementation has some major shortcomings.

 

First, although the example above is pretty simple implementation, more complex solutions get quite a bit more involved very quickly. The example above is simple because there’s only a single callback involved. Once you start using multiple callbacks the single handler approach gets much more tricky.

 

Single Event Interface and no native Event Context

The major problem I have with the ASP.NET implementation is that is a singular interface. It has a single entry point and no easy way identify and attach a context to who’s calling you. You can assign a context to the client code (in GetCallbackEventReference), but that same context is not passed back to you on the server side, so you have no way of knowing which client side event is calling you back. The above approach works just fine as long as you only have a single call back manager on a page but it gets a lot more complex when one or more are returned to you.

 

The workaround as I mentioned is to use separate controls, but this is neither obvious, and many people are likely to miss this fact. I doubt this would be documented in a meaningful way.

 

It sure would have been a lot cleaner if you could map a client side event to a server side method directly. The script code already contains the capability to passback event context references so why can't this be passed back directly to the handler simply by assigning a specific control (even one that doesn't implement ICallbackEventHandler?). As long as the form handler has it, it could route the request. Whenever multiple object are involved things get immediately more complex to set up and configure - keep it simple!

 

Plain String Interface

The other issue is the fact that this interface works with plain strings. This means we constantly will have to re-invent the wheel and figure out how to parse the data we’re passing back and forth.

 

I suspect there will be a lot of third party activity on that end as people come up with clever custom schemes to work around this limitation.

 

Microsoft Developer Bertrand Le Roy shows some examples of how to get around these limitations with some tools, but while cool and creative these sort of interfaces are complex to understand and implement.  Some rudimentary tools for passing parameter with both client and server converters would go a long way to make this technology much easier to use.

 

No access to XMLHttp

This would have been a really nice feature if somebody at Microsoft had thought of it: Expose the XMLHttp object to the client so we have a consistent way to read organized result data on the client. You can still do this I suppose by loading XML into an XMLDOM manually and then parsing, but now the Crossbrowser abstraction layer is no longer helping us and we’re responsible for setting up browser compatible XML doc loading etc. This exactly what this sort of high level tool is supposed to let us avoid.

 

Data is not POSTed to the server

Client Callbacks send data to the server via QueryStrings, which seems a really odd choice. Given that the page sends back the page state including ViewState and ControlState, it’s not going to take much to overrun browser querystring limitations. That one’s a real mystery as XMLHTTP can easily handle POSTing data.

 

Cross Browser Support – not yet

Microsoft has promised cross browser support for Mozilla and Opera style browsers, but currently in Beta 2 this is not working. This is a little scary to be looking at this technology at this point not being able to test with cross browser support. Hopefully there will be another beta/pre-release that adds this support before final realease.

 

 

Other solutions

Given some of the complexities I’ve described here I gotta wonder if it’s really worth the hassle. Doing the client to browser connection code is not that difficult to do and a few simple wrapper methods that abstract the HTTP trafficking and possible XML interaction would not be too difficult to implement.

 

I also recently took a look at Michael Shwarz’s killer Ajax.NET which just feels a lot cleaner and easier to use than ASP.NET 2.0’s script call backs. AJAX.NET uses an attribute based approach and uses nearly all server side mechanism to handle the callbacks. It works with many custom types which greatly simplifies passing data back and forth.

 

If you read Bertrand’s entries in the Blog mentioned earlier there are a few comparisons between AJAX.NET and script callbacks, but I tend to not agree with his conclusions. Ease of use is a huge feature – keeping complexity down is very important when building these kind of multi-access solutions to keep them maintainable.


The Voices of Reason


 

Rick Strahl
June 07, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Just got some feedback on my Feedback Center suggestion that this feature now POSTs data instead of using QueryStrings. Good news on that end at least.

OdeToCode Links
June 12, 2005

# OdeToCode Links For June 12


Burbujas en .net
June 14, 2005

# Ajax en .NET??


Ken Brubaker
June 24, 2005

# Intro to Ajax in ASP.NET 2.0

An article on how to do Ajax using new ASP.NET 2.0 features.

Rick Strahl's WebLog
July 12, 2005

# The joy of working with 2 versions of .NET

I've been working on my Web Store software mostly for internal stuff for a while in .NET 2.0. Recently it turned out that I needed to do some paying work with the 1.1 version and in the process I've found myself going back and forth between the two and backfitting changes from one to the other. Not a fun excercise.

Rick Strahl's WebLog
July 31, 2005

# Script Callbacks in ASP.NET 2.0 interface changes in Visual Studio July CTP

The July CTP of Visual Studio 2005 changes the ICallbackEventHandler interface by splitting the single RaiseCallbackEvent method into two methods PrepareCallbackEvent and RenderCallbackResult. This doesn't buy much, except requiring us to carry the event argument between the two methods.

Viraj doshi
October 06, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

can u provide vb version for the same code ? i will be very thankful to u bcause my issue is to do multiple callbacks in the same page and i do not C#. I will be very thankful if u provide the vb code

Sosh
October 28, 2005

# Parallel callbacks?

Hi,

I'm trying to put together a proof of concept for a small using .net2 script callbacks. I have it an issue with parallel calls, by this i mean sending a new callback before the result of another has been recieved. I think I naively thought that these would be queued, and that the javascript return handler function would be called twice (if there were two calls). What seems to happen however, is that the function only recieves a result from the last call made. Am I missing something?

Thanks

Robert Gudino
November 04, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

God is this a great site with awesome info. I just wish I had the brains of all you guys in my head.

Thanks for the info

Robert

Rick Strahl
November 04, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Please note that the examples here are written for Beta 2 and things have changed for the RTM version of Script Callbacks. If you're looking for more info I wrote a pair of complete articles for ASPToday, which can be found here:

http://www.asptoday.com/Content.aspx?id=2381

The samples for this article with online code can be found here:

http://www.west-wind.com/presentations/scriptcallbacks/sample/default.aspx

+++ Rick ---



Rick Strahl
November 04, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi Sosh,

There's a bug in Script Callbacks in ASP.NET 2.0 (including release) where if you launch a callback from within another callback it will fail. Internally the JavaScript falls down when multiple requests on the same request end up in the pipeline.

The workaround is to stagger the calls with window.setTimeout(). This is a sucky bug and Microsoft knows about it but couldn't fix it for release.






Ranga
November 22, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

i am getting following error message in VS 2005

Error 1 'ICallbackEventHandler.RaiseCallbackEvent' in explicit interface declaration is not a member of interface

Error 2 'ICallbackEventHandler.GetCallbackResult' in explicit interface declaration is not a member of interface

Error 3 '_Default.EventControl' does not implement interface member 'System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent(string)'

how to fix this error ???

Harold Espinosa
November 27, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

can You provide vb version for the same code ? i will be very thankful to You bcause my issue is to do multiple callbacks in the same page and i do not C#. I will be very thankful if You provide the vb code

gregchristensen
December 04, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Ranga:

If you are using the release version of ASP.NET 2.0, then the RaiseCallbackEvent method was changed to a void return type, GetCallbackResult should return the string.

Otherwise, you will need to post an example of your application.

Abhishek
December 20, 2005

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi,
I have implemented Callback on Button Control,And Using this I want to refresh the value in Textbox,but unable to implement it
please help me with some solution

regards

abhishek

Sosh
January 03, 2006

# Authentication?

Has anybody tried using this in an application with forms authentication in place? I'm struggling to figure out how the callback mechanism deals with a timed-out authentication session. As far as I can tell callbacks just get completely ignored when the authentication session has timed out.

daniel
January 06, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi, Rick,

I tried to build your multi Callback page, but failed.

in your code, "using Westwind.Tools;" is not available. and "EventControl" can not be found....

I am not the member of asptoday.

Would you please provide the workable code?

thanks

daniel liu


Quote:
**************************************
Please note that the examples here are written for Beta 2 and things have changed for the RTM version of Script Callbacks. If you're looking for more info I wrote a pair of complete articles for ASPToday, which can be found here:

http://www.asptoday.com/Content.aspx?id=2381

The samples for this article with online code can be found here:

http://www.west-wind.com/presentations/scriptcallbacks/sample/default.aspx
*******************************

Rick Strahl
January 06, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Access to those articles on ASPToday is free. All you have to do is sign up...

Jonathan
January 08, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Does anybody have a VB.NET example or implementation of this.
Maybe even just a way to implement this part in VB.

// *** Add the Event controls that implement ICallbackEventHandler

// *** and attach the ScriptCallback event to pass us notifications into this form

this.CustomerEventControl.ScriptCallback += new delScriptCallBack(CustomerEventControl_ScriptCallback);

this.AddParsedSubObject(this.CustomerEventControl);

But I would love to have the EventControl class in VB as well.

-Jonathan

Roy
January 25, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Let me second the questions above concerning VB... anyone have a mirror of this functionality but written with a VB codebehind? There are some peculiar differences between the languages that become evident when trying to implement the ICallbackEventHandler. Thanks.

Joel
February 03, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

This appears to be working for me in VB. Sorry if the line breaks get messed up.

Public Class EventControl
Inherits Control
Implements ICallbackEventHandler

Private strArgument As String

Public Event ScriptCallback(ByRef str As String)

Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
RaiseEvent ScriptCallback(strArgument)

Return strArgument
End Function

Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
strArgument = eventArgument
End Sub
End Class

...and for attaching the event...


AddParsedSubObject(objCallbackHandler)
AddHandler objCallbackHandler.ScriptCallback, AddressOf Me.test

...where objCallbackHandler is an instance of EventControl, and Me.test is a function that takes a string parameter by reference.


Danko
February 27, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Good article. Thank you.

Adrian Hara
May 05, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

I'm trying to use client callbacks with cookieless Forms Authentication. However, when the forms ticket is renewed (i have sliding expiration), the client callbacks obliviously call back with the same old ticket and fail. Any ideas for this?

Leo E.
June 07, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Help!!!!
I'm trying to use multiple postback in a composite control using your pattern (create an EventControl). I'm getting this message
"the target 'CompositeControl$ctl01' for the callback could not be found or did not implement ICallbackEventHandler".

Here's the js rendered by the GetCallbackScript script.

<a onclick="WebForm_DoCallback('baxControl1$ctl01',document.all.item(&quot;baxControl1_txtUserID&quot;).value + &quot;|&quot; + document.all.item(&quot;baxControl1_txtPassword&quot;).value,OnComplete,null,onError,true);"


I defined the event control as a global variable in the composite control

public EventControl oLoginEventControl = new EventControl();
public EventControl oSubmitEventControl = new EventControl();



public string GetCallbackScript(IButtonControl buttonControl, string argument)
{
string scriptRef;
this.oLoginEventControl.ScriptCallBack += new delScriptCallBack(oLoginEventControl_ScriptCallBack);
this.AddParsedSubObject(this.oLoginEventControl);
scriptRef = Page.ClientScript.GetCallbackEventReference(this.oLoginEventControl,
"document.all.item(\"" + txtUserId.ClientID + "\").value + \"|\" + document.all.item(\"" +
txtPassword.ClientID + "\").value",
"OnComplete", "null", "onError", true);
return scriptRef
}


Leo E.
June 07, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

typo,

on the js rendered by GetCallBackScript, 'baxControl1$ctl01' should actually be 'CompositeControl$ctl01'.

cindyluke
July 27, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

I am wondering if the server handle the callback as a post request. The request still goes through Page_Load etc. Then get to RaiseCallbackEvent. I have a aspx with a callback script. When I run it in a debug mode, I saw the request went to Page_Load first Then RaiseCallbackEvent.

Rick Strahl
July 27, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Cindy, yes callbacks hit the full page cycle. POST data is sent, but it's not hte current data on the page but the original data (which frankly is worthless).

If you want the down and dirty on Script callbacks I wrote an article on that before:
http://www.asptoday.com/Content.aspx?id=2381

But frankly this technology is still born and if you want to use AJAX with ASP.NET use something else <s>...

Anthem, AJAX.NET or even my own wwHoverPanel all provide much easier usage and more functionality.

# DotNetSlackers: Script Callbacks in ASP.NET 2.0 - interesting, but lacking


Sridhar
December 02, 2006

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

The callback won't go through entire page life cycle. Only page init and page load events will be triggered. Basically, Page_render won't be called.

# microsoft.public.dotnet.framework.aspnet | Google Groups


Rick Strahl's Web Log
February 11, 2007

# Script Callbacks in ASP.NET 2.0 interface changes in Visual Studio July CTP - Rick Strahl's Web Log

The July CTP of Visual Studio 2005 changes the ICallbackEventHandler interface by splitting the single RaiseCallbackEvent method into two methods PrepareCallbackEvent and RenderCallbackResult. This doesn't buy much, except requiring us to carry the event argument between the two methods.

Fred
March 16, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

I am developing a page that utilizes multiple callbacks. Initially, I used the "ugly" solution - I coded the origin of the callback into the message. After reading this blog I tried to go with the more elegant solution as outlined above. However, I keep getting:

The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>).

I've tried substituting <%=blah%> with <%#blah%>, but to no avail.

What gives? Or, should I just go back to the ugly solution until Orca comes out...?

Thanks in advance.

Rick Strahl
March 16, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Fred check this post for the reasons and workarounds for the Control Collection modification issues:

http://west-wind.com/weblog/posts/6104.aspx

Fred
March 17, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Rick,

Thank you for the reference. It was helpful in that I now understand the concepts in a general way, though I'm having trouble implementing them for this particular purpose.

I couldn't get the markup to add an EventControl programmatically (not your fault, I just don't know how to adapt the example code). So instead, I manually registered EventControl and added one to the page. It populated the event argument as expected but the ScriptCallback remains null, so all I can see is "Not Implemented."

Thank you for any further guidance.

Hemant Kanoujiya
April 14, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Thanks for the nice article. Very useful

# JavaScript with ASP.NET 2.0 Pages - Part 2

ASP.NET provides a number of ways of working with client-side script. This article explores the usage and drawbacks of ASP.NET script callbacks, and briefly presents a bird's view of ASP.NET AJAX.

Manny Khasria
April 27, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Thanks for this class Rick. I am pasting the same code in C# with GetCallbackResult implemented ... I hope this will help some of our friends.

public delegate string delScriptCallBack(string eventArgument);

public class EventControl : Control, ICallbackEventHandler
{
public event delScriptCallBack ScriptCallback;
private string strArgument;

public void RaiseCallbackEvent(string eventArgument)
{
strArgument = eventArgument;
}

string ICallbackEventHandler.GetCallbackResult()
{
if (this.ScriptCallback != null)
{
return this.ScriptCallback(strArgument);
}
return "PROBLEM!!!";
}
}

happy coding,
Manny Khasria

# ** 방실이의 홈피 BETA Version **


miky
October 08, 2007

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

rick,
thanks for your article. i just recently started delving into this and your article helped clarify some of the concepts. a question came to mind though when i thought about your implementation. since viewstate and post data are no help, how does one know the state of other controls, which may be needed for a particular action?

how about using the argument parameter in the script reference definition? something like this:

string ScriptRef = this.ClientScript.GetCallbackEventReference(
this,
"'<CUSTOMERID>' + document.forms[0].txtCustomerPk.value + '</CUSTOMERID>'",
"OnCallback",
"’MyCallContext’",
"OnCallback",
true);


this way, you know which value you're being passed. one could add to the parameter other nodes (if one chooses to use nodes) such as "ACTION" or the values of other controls:

string ScriptRef = this.ClientScript.GetCallbackEventReference(
this,
"'<CUSTOMERID>' + document.forms[0].txtCustomerPk.value + '</CUSTOMERID>
<ACTION>GETINVOICE</ACTION><INVOICEID>' + document.forms[0].txtInvoiceList.value + '</INVOICEID>'",
"OnCallback",
"’MyCallContext’",
"OnCallback",
true);


is this what you meant by some of the custom formats? are there changes to this problem scenario since the writing of this article?

thanks again for your expertise.

Vishal Sharma
May 15, 2008

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi,
I have read ur many posts and guess u have interest in low level details of topics and really i need such details so appreciate ur work on these details .
Keep it up.
Vishal...

trikam
June 03, 2008

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi,

I keep getting "WebForm_DoCallback is undefined"?
Why do i keep getting this error?

trikam
June 03, 2008

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Hi,

I keep getting "WebForm_DoCallback is undefined"?
Why do i keep getting this error?

I have also noticed that webresource.axd is not even rendered on the page.

Dan
April 11, 2009

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

Just a quick note- partial page rendering is much better now in 3.5:
http://msdn.microsoft.com/en-us/library/bb386573.aspx

T.Hamilton
April 25, 2010

# re: Script Callbacks in ASP.NET 2.0 - interesting, but lacking

If the context parameter is set to "context"

ClientScriptMananger.GetCallbackEventReference( this, "arg", cbHandler, "context" );

Then the element that fired the event will be the "context" parameter in the resulting script callback handler.

"function " + cbHandler + "( arg, context ) {\n"

This is a useful feature. But haven't seen it documented. Is it a valid behavior to use and expect to continue?

West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2024