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.

Sunday, August 19, 2007

Saturday, August 18, 2007

Black Metal

I have been listening to black metal for over 11 years now and I am still amazed by the richness of the genre. Sadly, there are very few new bands(if any) worth mentioning.
But to me black metal is still that hidden treasure that very few people tend to enjoy.
It is a safe haven from hip hop, pop, country, chalga and all the shit that surrounds us lately. I don't think there will ever be anything replacing the sound of Dimmu Borgir, Dissection, Burzum, Emperor, Mayhem, Immortal, Darkthrone, Old Sieben Burgen. Also other extreme bands like Amorphis (Up to Elegy), Dragonlord, newer Nordafrost. It is too sad that kids nowadays are too much into shitty crap like the junk that surrounds us. Damn I feel old and I am only 25. I remember when I used to roam the streets with soldier boots, black clothes and chains around my waist listening to enthroned or enslaved, or the latest dimmu. Those were sweet times. I wonder if things will ever be the same. Black metal has never been big in the US, but it's getting weaker even in Europe; how sad. I remember the days when there were true metalheads, willing to kill and die to protect the name of their favourite band. Oh how sad the wold has become. I can count the true metalheads that I have met in my life on the fingers of one of my hands. One of them is Mexican, one American and one Bulgarian and that is not counting me.
May the god of war bless us all,

one old and sad metalhead.

Friday, August 17, 2007

Date Parse Methods

DateTime.Parse() and SqlDateTime.Parse() methods are really cool and easy ways to convert a string with datetime format to a DateTime datatype. I wish I knew this earlier, no more manual parsing for me. :-)

Thursday, August 16, 2007

NUnit and App.config files

I was having problems getting NUnit to recognize and use the correct config files for the projects that I was running.
There were several reasons why I was getting runtime errors. Here is a list of them:

1) NUnit is looking for a config file with the same name as the assembly. - renamed the config to {assemblyname}.config
2) VS 2005 is supposed to copy over the App.config to bin/Debug(Release) at compile time and rename it to {assemblyname}.config, mine was failing to do that for some reason. - manual copy worked. Postbuild event should work too.
3) Nunit's project name has to be the same as the assembly name i.e. Project1.nunit won't cut it; it has to be named {assemblyname}.nunit- rename the project name.

After all of the above criteria are met, NUnit should be able to run tests on projects that have config files. I think this problem comes up only with dlls.

Wednesday, August 15, 2007

Using external config files for enterprise library configuration

http://blogs.msdn.com/tomholl/archive/2006/04/02/entlib2externalconfig.aspx

Tuesday, August 14, 2007

Testing Private methods w Nunit

Sometimes we run into the problem of testing private methods that are not visible from a Nunit assembly. One way that could be accomplished, without breaking the data encapsulation is to make the method in questions internal and add the following two lines to your code:


using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("PutYourTestAssemblyNameHere")]

now it will work

Friday, August 03, 2007

Enterprise Library Assemblies are Strongly Named

Alright how does that affect you? Well... in a very simple way, look at these two configuration files that are taken from Enterprise Library 2.0.0.0 and 3.1.0.0

2.0.0.0:

<text>
<configuration>
<configsections>
<section name="securityCryptographyConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Configuration.CryptographySettings, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
</section>
<securitycryptographyconfiguration defaulthashinstance="PasswordHasher">
<hashproviders>
<add algorithmtype="System.Security.Cryptography.SHA1Managed, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" saltenabled="true" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.HashAlgorithmProvider, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name="PasswordHasher">
</add>
</hashproviders>
<enterpriselibrary.configurationsource selectedsource="System Configuration Source">
<sources>
<add name="System Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
<add name="userStore" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" filepath="..\..\UserStore.config">
</add>
</add>
</sources>
</enterpriselibrary.configurationsource></securitycryptographyconfiguration></section></configsections></configuration>

3.1.0.0:


<configuration>
<configsections>
<section name="securityCryptographyConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.Configuration.CryptographySettings, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
</section>
<securitycryptographyconfiguration defaulthashinstance="PasswordHasher">
<hashproviders>
<add algorithmtype="System.Security.Cryptography.SHA1Managed, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" saltenabled="true" type="Microsoft.Practices.EnterpriseLibrary.Security.Cryptography.HashAlgorithmProvider, Microsoft.Practices.EnterpriseLibrary.Security.Cryptography, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" name="PasswordHasher">
</add>
</hashproviders>
<enterpriselibrary.configurationsource selectedsource="System Configuration Source">
<sources>
<add name="System Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<add name="userStore" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" filepath="..\..\UserStore.config">
</add>
</add>
</sources>
</enterpriselibrary.configurationsource></securitycryptographyconfiguration></section></configsections></configuration>

Do you see the difference? Yes, the config files are referring to different version of the Enterprise Library and also the 3.1.1.0 version has a public key token.

The reason for that is because the first config file is taken from the Enterprise Library hands on lab and has no public token, because it's supposed to easily work on any machine; however it is still looking for version 2.0.0.0. So whenever you try to build the solution from the hands on labs, you would get some weird exception and usually when you catch the inner exception, you would be able to see the actual problem. In my case, Visual Studio was unable to load Microsoft.Practices.EnterpriseLibrary.Common, but for enterprise library 2.0.0.0. I don't have that animal installed on my machine, so I was getting the error.

It won't even help if you try to open the App.config file with the Enterprise Library Configuration Tool, as it will try to open it with the old version of the ent. Lib assemblies bleh...
The only solution is to get the token and version from another config file and manually replace each entry.

Voila problem solved...

Indenting Partial Classes in VS

I am not going to go over something that is explained pretty well somewhere else. Nevertheless, I would like to flag the issue here. From experience I know that you don't always put the Dependent Upon tag where you would think of, but with trial and error anyone could find the right place.
Read the posted link for more info.

Enterprise Library Performance counters

I decided to get back to blogging, not so much because I am thinking that people will actually read my junk, but more so because I caught myself quickly forgetting things that I have done and need to relearn how to do them again.
My first post will be about using performance counters with Microsoft Enterprise Library 3.1 and Windows Vista. In order for you(or me) to be able to follow the example I will post here, you will have to have Enterprise Library 3.0 installed. You can download it here

After installing, make sure that you run the install instrumentation bat file with administrator privileges. You can do so by going to start->all programs->Microsoft patterns and practices->Enterprise Library then right click on Install Instrumentation and select Run as Administrator.



Now you are ready to use performance counters with your application.

Next step is to actually write your performance counter. I used Chris Burrows' .Net blog post as a basis for accomplishing this, but ran into a few problems that I feel should be documented. The code I will post here is identical to the one on his post, but I will add a few additional comments.

So let's start by creating a new Visual Studio Console Application project and naming it SamplePerformanceCounter.

Add a class to your solution called SimplestPerformanceClass and paste the following code in it:

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation;
using System.Diagnostics;


namespace SamplePerformanceCounter
{
[HasInstallableResources]
[PerformanceCountersDefinition(PerformanceCategory, "SampleInstrumentationCounterHelp")]
public class SimplestPerformanceClass
{
private const string PerformanceCategory = "Simplest Performance Category";

[PerformanceCounter("Operations Started/sec", "OperationStartedHelpResource", PerformanceCounterType.RateOfCountsPerSecond32)]

private EnterpriseLibraryPerformanceCounter _operationStarted = new EnterpriseLibraryPerformanceCounter(PerformanceCategory, "Operations Started/sec");

public void OperationStarted()
{
_operationStarted.Increment();

}

}
}


Also add a partial class called ProjectInstaller.cs with the following code:

using System.ComponentModel;
using System.Configuration.Install;
using System.Management.Instrumentation;
using Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation;
using System;
using System.Management;

namespace SamplePerformanceCounter
{
///

/// Let the system know that the InstallUtil.exe tool will be run against this assembly
///

[RunInstaller(true)]
public partial class ProjectInstaller :System.Management.Instrumentation.DefaultManagementProjectInstaller
{
///
/// Represents the installer for the instrumentation events. Not intended for direct use.
///


public ProjectInstaller()
{
Installers.Add(new ReflectionInstaller());
}
}



}



Here is one place that personally got me here, namely this line:
public partial class ProjectInstaller :System.Management.Instrumentation.DefaultManagementProjectInstaller

I had the System.Management.Instrumentation, System.Configuration.Install and Microsoft.Enterprise.Practices.EnterpriseLibrary.Common assemblies referenced in my project, and I thought everything should work fine. However Visual Studio was finding only System.Management.Instrumentation.DefaultManagementInstaller, so when I was trying to install my assembly using installutils, things didn't work right. It turns out that I had to reference System.Management as well, despite the fact that that class resides in System.Management.Instrumentation.
After getting that done, I added the following code to Program.cs:

using System;
using System.Collections.Generic;
using System.Text;

namespace SamplePerformanceCounter
{
class Program
{
static void Main(string[] args)
{
SimplestPerformanceClass performance = new SimplestPerformanceClass();

for (int i = 0; i < 1000000; i++)
{
performance.OperationStarted();
}
}
}
}


and compiled my solution.

Now is a good time to ensure that all the enterprise library default performance counters are added to perfmon. you can do so by calling the performance and reliability tool from Administrative tools, or just typing perfmon in Start->Run.

After doing that, you will see this:



You can click on the performance monitor under the monitoring tools folder and select the green cross at the top of the window and you should be presented the "Add Counters" screen. If you scroll the list, you should be able to see Enterprise Library counters, provided you installed instrumentation correctly. If you don't see anything ent. lib. related stuff that means you need to go back and figure out what went wrong with the install. Most likely you had permission problems and will have to run the script again with admin privileges.
So now that we have our solution complete and we have ensured that the ent. lib. instrumentation stuff is installed correctly, we will have to install our process counters with installutil.
Start the visual studio command prompt that you can find under Visual Studio 2005-> command tools. Make sure that you start it with admin privileges and navigate to your default project directory, then navigate to your bin/Debug folder and execute
installutil SamplePerformanceCounter.exe.
Now when you go back to the add counters screen in perfmon, you should see Simplest Performance Category as an option


Go ahead and open up the category by clicking the little triangular thingy to the right of it and select the text that will show up. It's something like Operations/sec. Then click on add to bring it to the right side of the split screen and select OK. If you are unable to see it under your graph, you will have to add a Thread.Sleep method in order to have instance of the application running, while you add the category. Once you have it added to your monitor, you can go back and remove the Thread.Sleep call. You should be able to see something similar after you have done all that:



I definitely think that Microsoft could have done a better job addressing performance counters in the enterprise library considering how little is the documentation on the web. I also think that Microsoft could do a much better job at documenting the enterprise library, considering that the enterprise library hands on labs are not detailed enough, the documentation on MSDN is virtually non-existent and a developer has to rely solely on the community out there for help.
After all this is not a few month old project, but some years now.

Happy programming.

P.S. Almost forgot, You will have to add an App.config file to your solution that has instrumentation specified in it. Here is how you can do that:

Open the Enterprise Library Configuration tool by going to All Programs->Microsoft Patterns and Practices-> Ent. Lib. -> Enterprise Library Configuration tool.




Right Click on the blue cubes that say Ent. Lib. Configuration-> Add new application.

Now Right click on the Application Configuration Icon and add new Instrumentation block. Now select true for Performance counters enabled and save the newly created config file as App.config inside your project directory. Now all you have to do is go back to your project and add existing file, pointing to the newly created App.config and you are set.