RSS

Monthly Archives: May 2009

ASP.NET event delegation

Did you ever wonder what is going on behind the scene of ASP.NET events? When you add an onclick event to, say, button how and when is this event executed?

If you drop a button control on your form and double click on it, .NET framework automatically generates both HTML presentation of the button and its OnClick event handler. The .aspx and .cs files will be updated with the following lines of code

//.aspx file


//code behind .cs file
protected void Button1_Click(object sender, EventArgs e){    }

When the button is clicked, how does .NET know what method to call? Obviously it’s specified in OnClick attribute of the button. Yes, but it doesn’t make it any clearer how the whole mechanism works. To make developers life easier, .NET framework hides the details of implementation.

Look at the following example.

Button1.Click += new EventHandler(Button1_Click);

This code does absolutely the same as OnClick attribute we saw before – it assigns an event handler to the button control. The only difference is that the last approach helps to keep presentation separate from implementation. The best place to add this code to is Page_Init method, which is called when the server loads the page.

You could ask why we didn’t assign the event handler directly like this:

Button1.Click = Button1_Click;

Actually this code has even two mistakes. First, C# language doesn’t have function pointers as C or C++ does. Instead C# provides us with delegates.

Delegates

So what is a delegate? As I have already mentioned, a delegate in C# is similar to a function pointer in C or C++. But unlike function pointers, delegate is a class that can hold a reference to a method. Unlike other classes, a delegate class has a signature, and it can hold references only to methods that match its signature. As this match is checked by compiler, delegates are type-safe and secure.

Another difference between delegates and function pointers is that a function pointer can only reference static functions, whereas a delegate can reference both static and instance methods. When the delegate references an instance method, it stores a reference to the method entry point and also a reference to an object instance on which to invoke this method (target object). For static methods only reference to a method is stored.

In the previous example

Button1.Click += new EventHandler(Button1_Click); 

EventHandler class is a delegate that encapsulates Button1_Click method. The signature of System.EventHandler class specifies that the methods it encapsulates must return void and take two parameters (by convention event delegates in the .NET have two parameters, the source that raised the event and the data for the event). So in our example we created a new EventHandler object containing Button1_Click method and added it to button’s Click event.

If you look at the code ASP.NET automatically generated for Button1_Click in .cs file

protected void Button1_Click(object sender, EventArgs e){    }  

you will notice it has exactly the same signature as EventHandler class defines.

ASP.NET controls use delegate of type System.EventHandler, but it’s possible to define your own custom type delegate. MSDN explains when custom delegates as useful:

Custom event delegates are needed only when an event generates event data. Many events, including some user-interface events such as mouse clicks, do not generate event data. In such situations, the event delegate provided in the class library for the no-data event, System.EventHandler, is adequate.

I will show how to create and use custom type delegates later in this post.

MultiCast delegates

If you remember I said there were two mistakes in that code in the beginning of this article. The second mistake is that all delegates that we use in ASP.NET as so-called MultiCast delegates. What is the difference?

A single delegate can invoke several methods at a time with the return type viod. Such delegates are called Multicast delegates. Multicast delegates inherit from System.MulticastDelegate class, rather than System.Delegate.

You may subscribe as many methods as you want to an event. Say, you want several objects to “know” that checkbox was checked/unchecked. All you need is to subscribe these objects to checkbox CheckedChanged event.

If you look at that code again you will see that we used “=” operator for adding a delegate. This will cause a compilation error. As we already know all delegates we can create in ASP.NET are MultiCast, that’s why “+=” operator must be used instead of “=”. It’s also possible to remove event handler with “-=” operator.

Note, when invoking MultiCast delegates if any of the encapsulated methods throws an exception it will prohibit the pending methods from invocation.
A way around this is to explicitly iterate the delegates and invoke them inside a try-catch block. To get the list of all assigned delegates we will use GetInvocationList method. What is the invocation list? MSDN gives a complete and easy to understand description

The invocation list of a delegate is an ordered set of delegates in which each element of the list invokes exactly one of the methods invoked by the delegate. An invocation list can contain duplicate methods. During an invocation, a delegate invokes methods in the order in which they appear in the invocation list. A delegate attempts to invoke every method in its invocation list; duplicates are invoked once for each time they appear in the invocation list. Delegates are immutable; once created, the invocation list of a delegate does not change.

So the code to execute all delegates in the invocation list will look like this:

foreach (myDelegateType dgt in myEventHandler.GetInvocationList()){
    try {
        dgt (null EventArgs.Empty));
    }
    catch{ } 
}

Custom events

Now when we know how delegates work we can try to create our own custom events.

Event functionality is provided by three interrelated elements:

  • a class that provides event data
  • an event delegate
  • the class that raises the event

The object that raises an event is called the event sender (Button in previous examples). The object that captures the event and responds to it is called the event receiver (Page).

The ASP.NET has a convention for naming classes and methods related to events.

  • Class that holds the data that is sent to event handler should have a name EventNameEventArgs. For example, WarningEventArgs. This class must derive from System.EventArgs;
  • A delegate called EventNameEventHandler. We have already seen this in the previous examples – EventHandler class;
  • Event defined in Sender with the name EventNameEventHandler;
  • A method named OnEventName that raises the event.

The last two items are hidden in the implementation of controls, that’s why we haven’t seen them before.

Event example

For better understanding let’s start coding. I will create a colony of nice ants (AntColony) and a colony of angry termites (TermitColony). Each time ant colony produces a new ant, termite colony will try to kill the baby. But they won’t attack unless the number of ants in the colony is more than three. Yeah, small colony 🙂

First we need to decide how we are going to let termites know that ant colony has created a new ant. We will raise an event and call a method of termite’s colony object. In this event we will pass the current number of ants and the reference to the newly created ant object.

To pass a custom parameter to the event I need to declare a class that will contain these parameters. This class derives from System.EventArgs. Accordingly to naming convention I will call it NotifyEventArgs. Here is the code:

class NotifyEventArgs:EventArgs {
        private int antCount;

        public int AntCount {
            get { return this.antCount; }
        }

        public NotifyEventArgs(int antCount) {
            this.antCount = antCount;
        }
}

The NotifyEventArgs class has a private field antCount that stores the count of ants in the colony, public AntCount property to make the value of antCount accessible and a constructor that sets antCount to the value passed as a parameter. Very simple.

Now let’s create an AntColony class. Mine looks the following way

class AntColony   {
    //number of ants in a colony
    private int antCount;
    
    public int AntCount{
            get { return antCount; }
            set { antCount = value; }
    }

    //method that Termites will call to kill a baby ant	
    public void beatAnt(){
            AntCount--;
    }
    
    //method to create a new ant
     public void bornAnt() { 
          AntCount++; 
          Console.WriteLine("Count of ants: " + AntCount); 
     }

     //When colony is created there it has one ant already
     public Ant() { AntCount++; }
}

Now add a TermiteColony class

class TermiteColony  {
     public Termites() { }
}

Very simple! Now let’s add the most interesting part – events!

First as we already know we need to declare a delegate. For our example we need a custom type delegate as we want to pass the count of ants as a parameter for the event.

Delegate should be declared outside of the class but in the same namespace as other classes. Otherwise you will have to specify the full name of delegate including the namespace. Here is my delegate called NotifyEventHandler.

public delegate void NotifyEventHandler (object sender, NotifyEventArgs e );

Note, the type of e parameter is a custom NotifyEventArgs class.

Now when we have a delegate, we need to add an event and event handler. Go back to AntColony and add a Notify event.

public event NotifyEventHandler Notify;

And a function that will invoke Notify event with parameters of NotifyEventArgs type. It should look like this

public event NotifyEventHandler Notify;

protected void onNotify(NotifyEventArgs antCount) { 
     if (Notify != null) Notify(this, antCount); 
}

The first line describes an event of NotifyEventHandler type. This means that all methods that this delegate will invoke must have the same signature as NotifyEventHandler.
The second line defines a method that invokes an event with parameters of a valid NotifyEventArgs type. It also checks if any method has subscribed to the event. If there is such a method then the event is invoked.

I want to add a method to TermiteColony that will kill a just born ant. If you remember this should only happen if the total count of ants is more than three. Have a look at the code:

public void WarNotify(object sender, NotifyEventArgs arg) {
    if (arg.AntCount > 3) BeatAnt((Ant)sender);
}

The WarNotify method will be called each time a new ant is born – it will run every time the event fires.

protected void BeatAnt(AntColony ant){
     ant.beatAnt();
     Console.WriteLine("I've killed the ant, Sir!");
}

This method gets a reference to AntColony object and calls its beatAnt method.

Job done! Add the following lines of code to your main execution class:

Ant antColony = new Ant();
            
Termites termiteColony = new Termites();
            
antColony.Notify += new NotifyEventHandler(termiteColony.WarNotify);

antColony.bornAnt();
antColony.bornAnt();
antColony.bornAnt();

And enjoy! You should see the following output when you run the program

Count of ants: 2
Count of ants: 3
Count of ants: 4
I've killed the ant, Sir!
Press any key to continue . . .

I hope this post helped you understand events and delegates in ASP.NET a little better.

P.S. source code can be found here.

 
1 Comment

Posted by on May 31, 2009 in ASP.NET

 

Tags: , ,

SQL Injection examples

Very interesting post about practical SQL Injection – http://www.securiteam.com/securityreviews/5DP0N1P76E.html. Very useful for testing your code.

 
Leave a comment

Posted by on May 29, 2009 in SQL

 

cloning a node

Day 2 of my “active” learning has begun and as item 2 of my TO DO list says I have to write at least one blog post a day – here it is!

Today I was adding some JavaScript functionality to the following form.

form

As you can see on the image at the moment of writing it was possible to enter details only of a single person. So let’s try and let our traveller have a company 😉

The idea is to repeat “Personal Details” section N times. N is a number of people in a group. There are two ways I can think of to make this work – either to clone a fieldset node or to create a each node manually using document.createNode method. The second solution I won’t even try as there are about half of a hundred different HTML elements to create. For this example I chose cloneNode method. Cloning an element has its drawbacks too. Let’s look at examples.

The following code clones a “div1” DIV node with a few child nodes and inserts it in “holder” DIV.

<script type="text/javascript">
var clone = function(){
    var newNode = document.getElementById('div1').cloneNode(true);
     document.getElementById('holder').appendChild(newEntry);
}

</script>
<div id="holder">
    <div id="div1">
    <p>
        <label for="testInput">Input:</label>
        <input name="testInput" id="testInput" value="la la la">
    </p>
    <p>
        <input type="button" value="Fire!">
    </p>
    </div>
</div>

<input type="button" value="Clone it!" onclick="clone();">

Note a parameter I pass into cloneNode. If parameter is set to true then an element will be cloned with all the child nodes it has. Otherwise, if parameter is false, only the node itself is duplicated without its children.

The code above works perfectly well except for one thing – cloneNode doesn’t clone event handlers applied to an element. To make your event handlers work you have to redefine them each time for each cloned node. You will also notice that every child of cloned node and the node itself have the same IDs as the original. To make your HTML code valid you should go through all cloned elements and give them unique IDs. This can be done with setAttribute method. For example,

newNode.firstChild.setAttribute('id', 'newId');

Actually IE does clone events that were set like elem.onclick=... or using attachEvent method. But Firefox and Opera don’t.

There are a few well-known bugs with cloned event handlers in IE. To be on the safe side you’d better make sure you remove all handlers off the element or clone elements before applying any handlers to them.

 
11 Comments

Posted by on May 29, 2009 in HTML, JavaScript

 

Tags: ,

Insert Multiple records in one statement

SQL-92 Standard added a new feature – row value constructors. It makes it possible to insert multiple rows at the same time in a single statement. Before SQL Server 2008 we had to either copy/paste a huge number of single INSERT statements or use SELECT/UNION clause in INSERT statement. Now, SQL Server 2008 supports this feature too and provides a new method to insert data to SQL Server tables.

General syntax of row value constructors is the following:

INSERT INTO ''TABLE'' (''column1'', [''column2, ... '']) 
VALUES 
(''value1a'', [''value1b, ...'']), 
(''value2a'', [''value2b, ...'']), 
...

To perform this operation on earlier versions of MS SQL Server that didn’t support row value constructors we used to use SELECT and UNION ALL clause:

INSERT INTO phone_book
SELECT 'John Doe', '555-1212'
UNION ALL
SELECT 'Peter Doe', '555-2323'

This construction still works perfectly well and can make the code much shorter and look much better.

At last have a look at new SQL Server 2008 method of row construction:

INSERT INTO phone_book
VALUES ('John Doe','555-1212'),('Peter Doe','555-2323')

This feature is supported by DB2, SQL Server (since version 10.0), PostgreSQL (since version 8.2), MySQL, and H2.

Isn’t it cool?!

 
Leave a comment

Posted by on May 26, 2009 in SQL

 

Tags: , ,

Del.icio.us API: PHP 5 Class

Today updating my script that posts links to Del.icio.us, I found a light and easy to use PHP5 class.

Have a look at how to use examples on the author’s page – it can help you save time managing your posts!

 
Leave a comment

Posted by on May 24, 2009 in misc, PHP

 

Tags: ,

HTTP post in ASP.NET

Last time I’ve blogged about getting uploaded files in ASP.NET, today’s post is absolutely opposite – sending data to a web page.

Before sending any data to any URI we have to create an instance of WebRequest class.

WebRequest is an abstract class which means that it can handle different protocols (such as HTTP and FTP) and that we actually work with its descendant classes. Instance of what class will be created depends on the URI protocol and also it can be a custom class inherited from WebRequest. In this article I am working with HTTP-specific implementation of WebRequest class.

To create a new HttpWebRequest object I use Create method of WebRequest. In the example below I also prepare data that I want to send and set some properties of WebRequest for correct HTTP post, such as Content-Length and Content-Type.

WebRequest webRequest = WebRequest.Create(URI);

webRequest.Method = "POST";
webRequest.ContentType = "application/x-www-form-urlencoded";

string parameters = "REFERENCE=" + refNum + "&STATUS=" + status;
byte[] bytes = Encoding.UTF8.GetBytes(parameters);

webRequest.ContentLength = bytes.Length;

Now we are ready to send our status update request to the web page that is located at the specified URI. For that we need to create a Stream object and write our data into it.

Stream dataStream = webRequest.GetRequestStream();

dataStream.Write(bytes, 0, bytes.Length);

dataStream.Close();

The request has been sent. If you want to get other server’s reply use the same approach but instead of WebRequest you will need WebResponse object.

Let’s read the response and check if it’s “SUCCESS”:

WebResponse webResponse = webRequest.GetResponse();

dataStream = webResponse.GetResponseStream();

StreamReader reader = new StreamReader(dataStream);
string responseFields = reader.ReadToEnd();

reader.Close();

if (responseFields.ToString() == "SUCCESS") Response.Write("Hurray!");

When you have finished with reading response data, you must close WebResponse object either by calling its Close method or closing the stream. In my example I close both:

dataStream.Close();
webResponse.Close();

As MSDN says, if you do not close the response or the stream, your application can run out of connections to the server and become unable to process additional requests.

 
Leave a comment

Posted by on May 23, 2009 in ASP.NET

 

Tags: , ,

HTTP file upload in ASP.NET

While working on a project that accepts files from another system and stores them locally, I noticed there was not much information on how to do this not using default ASP.NET controls.

Here is a quick summary or quide with a few important tips you may need.

Let’s start from the beginning. To access files uploaded by a client on the server-side, say using PHP, you would use $_FILES collection. In ASP.NET this collection is called HttpFileCollection. Note, the file collection is populated only when the HTTP request Content-Type is “multipart/form-data”. To check Content-Type of the request run the following code:

Response.Write(Request.ContentType); 

//Result:
//multipart/form-data; boundary=---------------------------7d9209171f0356 

Another thing you should remember is maximum file size restrictions. By default it’ set to 4096 KB (4 MB). It depends on the value of the MaxRequestLength configuration setting. If you attempt to upload a file that is longer than this value, the upload fails. To check the default maximum size for the current confuguration try the following:

using System.Web.Configuration;

HttpRuntimeSection configSection = new HttpRuntimeSection();
Response.Write(configSection.MaxRequestLength);

//Result: 4096

Now back to the file upload itself. As I already said HttpFileCollection will provide access to the files uploaded by a client.

HttpFileCollection Files = Request.Files;

In the example above I declared a variable of type HttpFileCollection that “holds” uploaded files.

The great thing about collection data type is that you can access it’s members either by name or by index (the same way as you do for arrays). Let’s take the previous example and get the length of each file in the Files collection:

HttpFileCollection Files = Request.Files;

string[] keys = Files.AllKeys;

for (int i = 0; i<keys.Length; i++) {
    Response.Write("File: " + keys&#91;i&#93; + " with ");
    Response.Write("size of " + Files&#91;i&#93;.ContentLength + "<br />");
}

In last example Files.AllKeys is a string array that contains the keys (names) of all members in the file collection.

Each individial file (member of HttpFileCollection) has HttpPostedFile type which provides properties and methods to get information about a file, to read and save it.

To check the type of the variable or object use GetType method of Type class.

Response.Write(Files[0].GetType()); 

//Result: System.Web.HttpPostedFile 

The example below is the function that checks file size and saves an uploaded file to disk.

Boolean SaveFile(HttpPostedFile fl,string fieldname,string refNum) {
        if ((fl != null) && (fl.ContentLength > 0)) {
            String currentDir = Server.MapPath("Uploaded") + "\\clientDocuments\\";
            int fileLen = fl.ContentLength;
            if (fileLen > 512000) return false;
            byte[] buf = new byte[fileLen];
            fl.InputStream.Read(buf, 0, fileLen);
            string[] spl = fl.FileName.Split('.');
            string shortfname = rnd.Next().ToString() + "." + spl[spl.Length - 1];
            string fname = currentDir + shortfname;
            FileStream fr = new FileStream(fname, FileMode.Create);
            fr.Write(buf, 0, buf.Length);
            fr.Close();
            return true;
        }
        return false;
    }

Hope you find it useful.

 
Leave a comment

Posted by on May 21, 2009 in ASP.NET

 

Tags: , , ,

 
%d bloggers like this: