Thursday, 17 January 2008
Differences between Server-side and Client-side code?
e.g. In ASP.NET for web controls like asp: button the click event of the button is executed on the server hence the event handler for the same in a part of the code-behind (server-side code). Along the server-side code events one can also attach client side events which are executed in the client�s browser i.e. javascript events.
Object Oriented Programming
Click Here to View Latest ASP.Net Questions
OOP Features
Transactions
Transactions
A transaction is a sequence of operations performed as a single logical unit of work. A logical unit of work must exhibit four properties, called the ACID (Atomicity, Consistency, Isolation, and Durability) properties, to qualify as a transaction:Atomicity
Specifying and Enforcing Transactions
SQL programmers are responsible for starting and ending transactions at points that enforce the logical consistency of the data. The programmer must define the sequence of data modifications that leave the data in a consistent state relative to the organization's business rules. The programmer then includes these modification statements in a single transaction so that Microsoft� SQL Server� can enforce the physical integrity of the transaction.It is the responsibility of an enterprise database system, such as SQL Server, to provide mechanisms ensuring the physical integrity of each transaction. SQL Server provides:
- Locking facilities that preserve transaction isolation.
- Logging facilities that ensure transaction durability. Even if the server hardware, operating system, or SQL Server itself fails, SQL Server uses the transaction logs, upon restart, to automatically roll back any uncompleted transactions to the point of the system failure.
- Transaction management features that enforce transaction atomicity and consistency. After a transaction has started, it must be successfully completed, or SQL Server undoes all of the data modifications made since the transaction started.
Transaction is a procedure the data tranmitted into the database either sucess of failure sate.
It has 2 objectsCOMMIT
ROLLBACK
Strong Naming
Hashes and Signing
To grasp the way that strong names work, you first need to understand a pair of cryptographic concepts: hashing and digital signatures.Hashing is used to create a unique, compact value for a plaintext message. "Message" is a very broad term here; in terms of assemblies, the message is the assembly itself. The message is used as an input to the hash algorithm (in the case of strong naming, the SHA1 algorithm is used). Figure 1 diagrams the process.
<!--[endif]-->Hashing is a one-way street: you can't decrypt the hash value once it has been computed. However, hashing is very useful for comparing values. If two assemblies produce the same hash value, you can assume that the assemblies are the same. Conversely, if hashing an assembly produces a value that doesn't match a previously-calculated hash, you know that something in the assembly has been changed.
Knowing the hash value for an assembly lets you check that no one has tampered with the assembly. But how do you prevent someone from tampering with the hash value? That's where digital signing comes in. While the mathematics of digital signatures are complex, the concept is fairly simple. A digital signature depends on a pair of related numbers, the public key and the private key. When data is encrypted with the public key, it can only be decrypted with the private key (and vice versa), as shown in Figure 2.
<!--[endif]-->Strong Naming for Assembly Identity
The combination of hashing and digital signing allows .NET to protect your assemblies from tampering. Here's how it works. First, a hash value is created from the assembly. Then, the hash value is encrypted with your private key and placed, along with your public key, in the assembly itself. Figure 3 shows this process schematically.
<!--[endif]-->
<!--[endif]-->You can use a strong name to verify that an assembly came from a particular source, and that it wasn't tampered with after it was signed. It's up to you to decide, based on whatever information you choose, whether to trust code from that source.
What's in a (Strong) Name?
In addition to a hash derived from the assembly's contents, the strong name includes three other pieces of information:- The simple text name of the assembly
- The version number of the assembly
- The culture code (if any) of the assembly
Keeping Secrets with Delay Signing
Protecting your private key is obviously very important; if a nefarious person gets your private key, they can produce assemblies that appear to have been signed by you. Because of this, you may wish to keep your private key a closely-guarded secret, known only to a few people in the company. But then, how can you handle assembly signing? It would be tedious if you were the only person who knew the private key, and you had to sign every build of every assembly produced by every developer in your company.Fortunately, .NET provides a way around this problem: delay signing. With delay signing, you can build and test an assembly knowing only the public key. The private key can be applied later if the assembly is actually shipped to customers. Here is a summary of the delay signing process:
- Extract the public key from the public/private key pair. To extract the public key from a file that is storing the public/private key pair, you can use the strong name tool with a slightly different command line:
sn.exe -p MyKeyFile.snk MyPublicKeyFile.snk
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--> - Distribute the file containing only the public key to all of the developers in the company, and store the file containing both keys securely.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--> - Include the public key file in your assembly information file, and specify delay signing:
[assembly: AssemblyDelaySign(true)]
[assembly: AssemblyKeyFile("..\\..\\MyPublicKeyFile.snk")]
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
- Turn off verification for the assembly if you're storing the assembly in the GAC. By default, the GAC verifies the strong name of each assembly. If the assembly is not signed by using the private key, this verification fails. So, for development and testing purposes, you can relax this verification for an assembly by issuing the following command:
sn.exe -Vr MyFile.dll
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--> - At this point, you can use the assembly freely in testing and development.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--> - When you're ready to deploy a delay-signed assembly, you need to sign it with your private key:
sn.exe -R MyFile.dll MyKeyFile.snk
<!--[if !supportLineBreakNewLine]-->
<!--[endif]--> - Finally, you can instruct the GAC to resume verification for an assembly by issuing the following command:
sn.exe -Vu MyFile.dll
Explian Trigger
It supports Multiple after Trigger also. Triggers cannot be created on the temporary tables.
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
MVC (Model View Controller) For ASP.NET
<!--[endif]--><!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
<!--[endif]--><!--[if !supportLineBreakNewLine]-->
<!--[endif]-->
<!--[endif]-->
<!--[endif]-->
<!--[endif]-->Conclusion
Localization and Culture
As the number of Internet users grew worldwide, the need to create software supporting multiple languages was felt intensely because only ten percent of people use English as the primary language. People wanted applications that could communicate with them in their native language. This became simple with the release of the .NET framework.
Locale and .NET culture
Geographically speaking, a locale is a place. In software terms, a �locale� is a collection of information associated with a place. Locale information includes the name and identifier of the spoken language, cultural conventions, etc. A Locale Identifier (LCID) is used to retrieve information about the locale. LCID is a 32-bit unsigned integer value that is divided into four parts. The first two parts identify the language and sub-language (sub-language corresponds to country/region) and the last two parts specify the sorting order for text strings.
The �culture� in .NET refers to the user�s language and region. A culture is identified by language code�region/country code. For example, the French language spoken in
.NET encapsulates the culture related information in the System.Globalization and System.Resources namespaces. The object of the Globalization. CultureInfo class represents a specific culture. Using the methods of this class, we can obtain the information of the culture that is set for the current thread. The following code snippet shows how to set the culture for the current thread and obtain its name, number format and currency format.
foreach(CultureInfo c in CultureInfo.GetCultures(CultureTypes.AllCultures)) { Thread.CurrentThread.CurrentCulture = new CultureInfo(c.Name); Console.WriteLine ( "{0}:{1},Num:{2},Dt:{ 3}, Curr:{ 4} ",c.Name, c.EnglishName, (12345).ToString ("n"), (12345.50).ToString ("c"), (DateTime.Now).ToShortDateString()); } The CultureInfo.GetCultures( ) method returns the list of all the supported cultures. CultureTypes is an enum that contains the types of culture�specific, neutral, all cultures and only those cultures that are installed on the system. To set the culture for a thread, firstly we must obtain the reference to that thread. Here, we have obtained the reference by using the CurrentThread property of the Thread class. The two culture values of an application determine what resources are loaded for an application and how information like currency, numbers and dates are formatted. The resources loaded are determined by the UI culture setting, and the formatting options are determined by the culture setting. The Thread class provides two properties�CurrentCulture and CurrentUICulture�to change the respective culture settings. We have used the CurrentCulture property since we needed to set the culture specific formatting options. The Name and EnglishName are properties of the CultureInfo class that give the culture name and its corresponding Language (Country/Region) combination respectively. Of course, we need to use the Globalization and Threading namespaces to run this code.Let�s now see how to localise resources. We will create a localised WinForm application that allows the user to select a language. On clicking a button another form would get displayed in the selected language. This form would contain a textbox where you can type your name. On clicking a button you would be greeted in the selected language. Our form would look as shown below.
<!--[endif]-->void bdisplay_Click (object sender, System.EventArgs e) { Thread t = Thread.CurrentThread; if(rfre.Checked) t.CurrentUICulture=new CultureInfo("fr-FR"); if(rger.Checked) t.CurrentUICulture=new CultureInfo("de-DE"); if(rita.Checked) t.CurrentUICulture=new CultureInfo("it-IT"); if(reng.Checked) t.CurrentUICulture=new CultureInfo("en-US"); greetform g=new greetform(); g.ShowDialog(); }Collections Class
BitArray
The BitArray class supports a collection of bits which are represented as Booleans. Because it stores bits rather than objects, BitArray has capabilities different from those of the other collections. However it still supports the basic collection underpinning by implementing ICollection and IEnumerable. It also implements ICloneable.
Event-driven programming with WinForm
Event-driven programming with WinForm
Windows applications that we create fall under two major categories�managed and unmanaged. Unmanaged Windows applications can be created using Microsoft Foundation Classes (MFC). Managed applications run under Common Language Runtime (CLR) and are created using .NET Framework Class Library. These applications are called WinForm applications. WinForms (Windows Forms) create graphical user interface (GUI) for Windows applications. A form is a top-level window of an application. It can be a window, a dialog or a multiple document interface (MDI) window.
Creating WinForms has many advantages over creating applications using MFC. In unmanaged Windows-based programs, we need to apply certain styles to the window only when it is created. WinForms eliminate this quirk. If we apply styles that are meant to be applied at creation time, .NET destroys the previous window and creates a new one with new styles.
The .NET Framework Class Library is richer than MFC. Also, the classes remain the same for all the .NET compliant languages. All the classes that are used to create and design a WinForm are encapsulated in System.Windows.Forms namespace. For example, the System.Windows.Forms.Form class is used to create the form, System.Windows.Forms.Button class is used to create a button and so on. To create a GUI, we place components and controls on the form and so, a form acts as a container of components and controls. To create the GUI we drag and drop the controls from Toolbox and change their properties to suit our requirements. When we drag the control on form and change properties, Visual Studio.NET generates suitable code for us. However, only adding controls to create a user interface is not enough. Our application must also respond when the user interacts with the application. A user can interact with the application by moving the mouse, clicking the mouse button, pressing a key, etc. Whenever a user interacts with the GUI, events are generated. Events are notifications sent to the container, which can then respond to it. For example, when we click a button, an event is generated notifying that the user has clicked the button. In response, we can display a message box or do something else. This job is done in methods called �event handlers�. When a particular event is generated, the corresponding event handler gets called to process the event. For calling the event handlers, .NET takes help of events and delegates.
An event in C# is a multicast delegate having a predefined prototype. The prototype is such that every event returns a void and always accepts two parameters. The first parameter is always a reference to an object of System.Object class and the second parameter is always a reference to an object of the System.EventArgs class or a class derived from it. The EventArgs object contains information about the event. The object that raises an event is called an �event raiser� and the object that receives an event is called an �event receiver�. The event raiser class always declares the event and the receiver class must have an event handler to handle that event.
The first parameter collected by the event handler is always a reference to an event raiser object. The addresses of event handlers are stored inside the events (remember that events are actually delegates) and hence they also must have the same signature as the event. This kind of delegate is declared using the keyword event. To understand events, consider the following program.
using System;namespace Sample{ public class mouseeventargs { public int x,y; public mouseeventargs (int x1, int y1) { x = x1; y = y1; } } public delegate void click (object m, mouseeventargs e); public class MyForm { public event click c1; public void mouseclick() { mouseeventargs m = new mouseeventargs (10,20); c1 (this, m); } } class MyForm1:MyForm { public MyForm1() { c1 += new click (button_click); mouseclick(); } public void button_click (object m, mouseeventargs e) { Console.WriteLine (�Mouse Coordinates: � + e.x + � � + e.y) ; Console.WriteLine (�Type is: � + m.GetType().ToString()) ; } static void Main ( string[ ] args ) { MyForm1 f = new MyForm1( ) ; } }} In this program we have declared three classes�mouseeventargs, MyForm and MyForm1 derived from MyForm. The mouseeventargs class corresponds to the EventArgs class. This class contains two int variables x and y and a constructor to initialise them. We have declared a multicast delegate click whose signature is the same as the event handler button_click( ). The MyForm class here is an event raiser class and hence contains an event as a data member called c1 of the type click. It also contains a method called mouseclick( ). In this method we have created an object of the mouseeventargs class. In the statement,
c1 (this, m);
c1 encapsulates the button_click( ) method. this contains the reference of MyForm object (event raiser) and m is a reference of the mouseeventargs object. In the MyForm1 class, we have defined the method button_click( ) (i.e. event handler). When the compiler encounters the statement c1 += new click (button_click), it creates an event object (delegate object) that wraps up button_click( ) method. So whenever the c1 event is raised (or called, as in this program), the method button _click( ) would get executed.
We could call a method even by using a delegate. Then what are events for? Take a look at the following statement.
c1 = new click(button_click);
where, c1 is a delegate reference. This statement has a bug. Here, we are assigning a new delegate object to c1, and so, all the delegates previously added are now lost. Instead of = operator we should have used += operator to add a new delegate object to the delegate list. This would never happen in case of events. This is because we can perform only two operations on events, namely, += and -=. We cannot use = operator with events. As such, events provide a protection layer on delegates. When we use the += and -= operators with delegates, they get converted into a call to Delegate.Combine( ) and Delegate.Remove( ) methods. If we use += and -= operators with events they get converted into a call to add_c1( ) and remove_c1( ) methods. These methods in turn call the Delegate.Combine( ) and Delegate.Remove( ) methods.
WinForms also follow the same mechanism. Only thing is, we don�t need to invoke the event handlers ourselves. They get called automatically when events occur. The compiler adds suitable code such that when an event occurs our event handler would get called. Let us now see what code gets generated when we create a WinForm application and add an event handler.
The minimal code that is required to create a WinForm application is given below:
using System;using System.Windows.Forms;namespace WinFormDemo{ public class Form1 : Form { static void Main () { Application.Run ( new Form1( ) ) ; } }} Here, we have derived a class Form1 from the Form class and passed a reference to its object to the Application.Run( ) method. This method creates the form, displays it on screen and starts a message loop for it. Of course, we don�t need to write this code, Wizard generates it for us. If we add a control to the form, a reference to the class representing the control gets added to the class as a private member. If we add a button the reference to the Button class would get added as shown below.
private System.Windows.Forms.Button button1;
The reference button1 would get initialised in the InitializeComponent( ) method as given below.
this.button1 = new System.Windows.Forms.Button();
On adding a handler for the Click event, the code generated for it looks as given below.
this.button1.Click += new System.EventHandler(this.button1_Click);
The EventHandler is a delegate defined in the System namespace. This statement wraps the EventHandler around the button1_Click( ) method so that when the Click event is fired, button1_Click( ) method would get called. The definition of button1_Click( ) method is shown below.
private void button1_Click (object sender, System.EventArgs e){} The first parameter passed to button1_Click( ) method identifies the object that fired the event (button1 in this case). The second parameter contains additional information about the event.
The objects of every control class fire events. Now you can appreciate how easy it is to handle these events under .NET
Understanding Delegates
Understanding Delegates
A delegate is an important element of C# and is extensively used in every type of .NET application. A delegate is a class whose object (delegate object) can store a set of references to methods. This delegate object is used to invoke the methods. Many developers find delegates complicated. But believe me, it�s a simple concept to understand. In this article we will see how delegates work and in what situations they are used.
Let�s start with a simple program that shows how to declare and use a delegate.
class sample{ delegate void del1(); delegate void del2 (int i); public void fun() { del1 d1 = new del1 (f1); d1(); del2 d2 = new del2 (f2) ; d2 ( 5 ) ; } public void f1() { Console.WriteLine (�Reached in f1�) ; } public void f2 (int i) { Console.WriteLine (�Reached in f2�) ; }} In the sample class we have declared two delegates�del1 and del2. The statement delegate void del1( ) ;
indicates that the delegate del1 is going to encapsulate methods, which takes no parameter and returns void. When this statement is encountered, a class del1 derived from a pre-defined class MultiCastDelegate gets created. Similarly, the statement delegate void del2 ( int i ) ; indicates that the delegate del2 will be used for methods taking one integer and returning a void. This statement would create another class del2 derived from the MultiCastDelegate class. The classes del1 and del2 are called �delegate classes�. To use the delegate class, like any other class, we have to declare its reference. We have declared the reference to delegate class del1 in the fun( ) method through the statement del1 d1 = new del1 ( f1 ) ;
This would create a delegate object d1. To the constructor of the delegate class we have passed the address of the method f1( ). C++ programmers may know that mentioning a method name without parentheses represents its address. The delegate object would now hold an address of the method f1( ). Next, we have called the f1( ) method using the delegate object d1. This is achieved using the statement d1( ) ;
If d1 is an object, how can we use it as if it is a method? Actually, the call d1( ) gets converted into a call to the d1.Invoke( ) method. The Invoke( ) method calls the f1( ) method using its address stored in delegate object. A delegate can contain references to multiple methods. In this case a single call to Invoke( ) calls all the methods.
Similar to d1 we have instantiated another delegate object d2 and stored in it an address of the method f2( ). As the method f2( ) takes an integer as a parameter we pave passed 5 to d2( ). The value 5 would get passed to all the methods whose references are stored in this delegate object. This makes it obvious that the signature of the delegate and that of the methods to be invoked using the delegate must be identical.
If we create an object of sample class and call the fun( ) method both the f1( ) and f2( ) methods would get called through d1 and d2 respectively.
Delegates make possible calling of methods using reference to methods the object oriented way. This avoids using any complex technique like pointers to functions.
Delegates in Inheritance
Suppose there is a base class and a class derived from this class. A method is invoked from a base class method using a delegate. We can initialise this delegate in derived class so that when the method is invoked from the base class it is the derived class�s method that would get called. Here is the program that works similar to this situation.
using System; namespace delegateinherit{ public delegate void del1(); class mybase { public del1 d; public void fun() { d(); } } class der : mybase { public der() { d = new del1 (f1); fun(); d = new del1 (f2); fun(); } public void f1() { Console.WriteLine (�Reached in f1�) ; } public void f2() { Console.WriteLine (�Reached in f2�) ; } } class Class1 { static void Main (string[] args) { der d = new der(); } }} Here, from the fun( ) method of the mybase class we have used the delegate object d to invoke a method. The fun( ) method is called twice from the constructor of the derived class der. Before calling fun( ) method, we have associated the delegate d, first with method f1( ) and then with f2( ). Thus, if we create an object of the der class, first the f1( ) and then f2( ) method get called. We can invoke both the methods in a single call to fun( ) as shown below.
d = new del1 ( f1 ) ;
d += new del1 ( f2 ) ;
fun( ) ;
Where Delegates are useful
In a general WinForm application, a class Form1 gets created, which is derived from the Form class. If we want to handle mouse click messages, we override the OnMouseDown( ) message handler in the Form1 class. When we click the mouse button, control reaches to the OnMouseDown( ) of the derived class i.e Form1 class because of the simple rule of inheritance. But if we click on a push button on the form, the OnMouseDown( ) of the Form1 class does not get called. Because Form1 class is not derived from the class that creates button. In such a situation, delegates prove useful. Calling methods using delegate require only that the signature of methods and that of the delegate should match. It does not require any inheritance chain to call the appropriate method. So, in .NET, all the event handlers are called through delegates, instead of relying on the inheritance chain.
Delegate at work
As said earlier, all the event handlers are called using delegates. We will now see a dummy program to explain how the Paint event handler must be getting called using a delegate.
using System;namespace delegateatwork{ public delegate void PaintHandler(); class Form { public PaintHandler Paint ; public void OnPaint() { Paint(); } } class form1 : Form { public form1() { Paint += new PaintHandler (form1_Paint); OnPaint() ; } public void form1_Paint() { Console.WriteLine (�form1_Paint�); } } class Class1 { static void Main (string[] args) { form1 f = new form1(); } }} We have designed a class Form1 that contains a method called Form1_Paint( ). The Form1 class is derived from the Form class. In the Form class we have declared an object Paint of the delegate class PaintHandler. In