Wednesday, September 26, 2007

Client Callbacks in ASP.NET 2.0

OK, I was looking for a way to call code behind from javascript and a ASP.NET 2.0 Web Page. I know, I know... I am a little behind on the whole AJAX thing, but I am trying to catch up quickly. Believe it or not, I am also just now learning javascript. It is interesting because I have been programming for over 5-6 years now and I have been messing with computers and web design since roughly 1998 and all this time, I never learned javascript. You can see how amusing I was finding all the comments all over the internet that javascript is very easy to learn, especially compared to real programming languages. Anywho, I naturally wanted to learn how to call my C# code from java script and readthis awesome article on the code project.
I find it much better than this one from MSDN

I am going to paste the article here, for the sake of me finding it later when I search for it, in case the original web page moves.

Introduction
Client Call back is an interesting feature of ASP.NET which allows call of server code from Client side Java Script through XmlHTTP so called AJAX in this article I will discuss client callback first and lets will compare its benefits with the AJAX.



Using AJAX in ASP.NET 1.1 is quite tedious task first you need to copy the AJAX dll into the bin folder than register it as an HttpHandler in Web.Config, things not finished here because for every page which your planning to use AJAX needs to be register as well by calling AJAXUtility.RegisterForAJAXType (this.GetType ()) and then comes the writing of actual client and server side code.

In ASP.NET 2.0 Runtime takes this responsibility of registering http handler, page types etc and simplified the process of client script callbacks so in this article I will discuss the details of it.

ASP.NET introduce the new interface named ICallBackEventHandler, page needs to implement this interface in order to support client call backs. It has two methods

* RaiseCallbackEvent: Processes a callback event that targets a control, this method is the execution point when server code is call from client script,
* GetCallbackResult: Returns the results of a callback event that targets a control, the result is usually returned by RaiseCallBackEvent and stored in some class member.

Client Call Backs in Action
Lets take a look at very basic example of Client Callbacks in which clicking of client side button triggers server code which returns a simple text message for display in the textbox at client side

Implementing ICallbackEventHandler



   1:  public partial class _Default :

   2:   

   3:  System.Web.UI.Page, ICallbackEventHandler  

   4:   

   5:  {

   6:   

   7:      string callbackResult;

   8:   

   9:      protected void Page_Load(object sender, EventArgs e)

  10:   

  11:      {

  12:   

  13:          // will discuss this later

  14:   

  15:      }

  16:   

  17:   

  18:   

  19:      public void RaiseCallbackEvent(string eventArgument)

  20:   

  21:      {

  22:   

  23:          // perform some real operation

  24:   

  25:          callbackResult = "DotNET Rocks!";

  26:   

  27:      }

  28:   

  29:    

  30:   

  31:      public string GetCallbackResult()

  32:   

  33:      {

  34:   

  35:          return callbackResult;

  36:   

  37:      }

  38:   

  39:  }



The above code is quite simple RaiseCallbackEvent performs some operation and store result in callbackresult variable which is returned by GetCallbackResult method. Now the next step is to have some JavaScript code which till trigger this callback.



   1:  <script type="text/javascript">

   2:   

   3:      function GetMessageFromServer()

   4:   

   5:      {

   6:   

   7:          UseCallBack();

   8:   

   9:      }

  10:   

  11:     

  12:   

  13:      function JSCallback(TextBox1, context)

  14:   

  15:      {

  16:   

  17:          // when callback finishes execution this method will called

  18:   

  19:          document.forms[0].TextBox1.value = TextBox1;

  20:   

  21:      }

  22:   

  23:  </script>



GetMessageFromServer will trigger the server code using UseCallback method this is dynamic method generated from the code behind more on this later. JSCallback is the client method which will call when server callback completes its execution

So what I did here is just copy the server message in the textbox.



Click of Following html button will invoke the method



   1:  <input type="button" id="Button1" runat="server" value="Get Message" onclick="GetMessageFromServer()"/>



Now comes the final and most important step of using client callbacks this step is actually responsible for emitting the java script which will call the Framework method so make actual XmlHttp, normally this code fragment comes in Page_Load event i.e.



   1:  protected void Page_Load(object sender, EventArgs e)

   2:   

   3:  {

   4:   

   5:      // get reference of call back method named JSCallback

   6:   

   7:      string cbref = Page.ClientScript.GetCallbackEventReference(this, "arg", "JSCallback", "context");

   8:   

   9:   

  10:   

  11:      // Generate JS method trigger callback

  12:   

  13:      string cbScr = string.Format("function UseCallBack(arg, context) {{ {0}; }} ", cbref);

  14:   

  15:   

  16:   

  17:      Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "UseCallBack", cbScr, true);

  18:   

  19:  }

  20:   

  21:   

  22:   

  23:  The above C# code generates the following Java script at run time

  24:   

  25:  function UseCallBack(arg, context)

  26:   

  27:  {

  28:   

  29:      WebForm_DoCallback('__Page',arg,JSCallback,context,null,false);

  30:   

  31:  }



This is actually the calls the XmlHttp behind the scene which will ultimately result callback of server code. So that’s it after server code finishes its execution Framework will call the specified Java script method to notify the completion of callback in this case which is function JSCallback(TextBox1, context).


Internals of Client Callbacks

You might be wondering where XmlHttp object is and how framework calls the server callback behind the scene, well of you look at the generated html for the page you will see an interesting script declaration i.e.



   1:  <script src="/&lt;AppName>/WebResource.axd?d=v…&amp;t=63…0" type="text/javascript"></script>



If you open the above URL in browser you will see the complete definition of library functions and objects responsible for server calls and client notifications.



Another interesting thing in the previous code was ClientScript property of page class this property represents the instance of ClientScriptManager class which contains all the concerns of client side scripting and contain lots of methods useful in client side scripting. GetCallbackEventReference is one of the methods which returns reference to a client-side function that, when invoked, initiates a client call back to a server-side event.



Page Cycle in Client Callback Scripts

One of the interesting and unique feature of client callback script is that when calling server callback the aspx page loads into memory and executes normal page cycle events such as Page_Init, Page_Load etc. this is where client callback runs away from AJAX because in AJAX aspx page is not loaded in memory so you cannot access viewstate, page controls but this is not the case in client callbacks.



However in client callbacks partial page cycle executes and events such as Pre_Render, Render doesn’t fire and it’s logical enough because we don’t want the complete page refresh. Following diagrams will describe the page life cycles in both scenarios

To add to the above, he talks about passing parameters to the callback and how you do it, but is not very clear. You can pass only one parameter to the server and it is only a script data type. That means that you could concatenate the parameters in a comma delimited string and just parse in the code behind. Pretty cool I would say...

Friday, September 21, 2007

Data Layer testing

Data layer testing has been an issue for me for quite some time. All tests need to be atomic, that is a fundamental rule when it comes to testing and is especially important and difficult to achieve in the database testing. Some things that come to mind are Identity fields. Every time you insert a record, the database gets changed, even if you delete the record manually at the end of the test. Also cleaning up manually a distributed database could be quite hectic, same applies when you need to insert a lot of data to efficiently test your functionality (consider a tree-like structure that is stored in SQL). The best way to solve all of the above mentioned problems and still ensure atomicity is transactions. Here is more on the topic:
COM+ 1.5 Transactions
The article uses Enterprise Services.
One waring though, the tests will randomly fail if your testing code has a transaction that is supposed to fail (Exceptions, boundary cases, faulty input ... etc) When you say Transaction.Rollback() which one is the one that gets rolled back?
I have spent numerous hours trying to figure out randomly failing unit tests.
If you have had code that randomly fails and passes under the same conditions, you know very well this is not a very pleasant situation.

So keeping all that in mind, the article is pretty good.