Tuesday, 6 December 2011

SQL Server DO's and DON'Ts



So, you are now the leader of a SQL Server based project and this is your first one, perhaps migrating from Access. Or maybe you have performance problems with your SQL Server and don't know what to do next. Or maybe you simply want to know of some design guidelines for solutions using SQL Server and designingDatabase Access Layers (DAL): this article is for you.
Even if you are not using SQL Server, most of these design guidelines apply to other DBMS, too: Sybase is a very similar environment for the programmer, and Oracle designs may benefit from this too. I won't show here how to use specific T-SQL tricks, nor won't give you miracle solutions for your SQL Server problem. This is by no means a complete, closed issue. What I intend to do is give you some advices for a sound design, with lessons learned through the last years of my life, seeing the same design errors being done again and again.

DO know your tools.

Please, don't underestimate this tip. This is the best of all of those you'll see in this article. You'd be surprised of how many SQL Server programmers don't even know all T-SQL commands and all of those effective tools SQLServer has.
"What? I need to spend a month learning all those SQL commands I'll never use???" you might say. No, you don't need to. But spend a weekend at MSDN and browse through all T-SQL commands: the mission here is to learn a lot of what can and what can't be done. And, in the future, when designing a query, you'll remember "Hey, there's this command that does exactly what I need", and then you'll refer again to MSDN to see its exact syntax.
In this article I'll assume that you already know the T-SQL syntax or can find about it on MSDN.

DON'T use cursors

Let me say it again: DON'T use cursors. They should be your preferred way of killing the performance of an entire system. Most beginners use cursors and don't realize the performance hit they have. They use memory; they lock tables in weird ways, and they are slow. Worst of all, they defeat most of the performance optimization your DBA can do. Did you know that every FETCH being executed has about the same performance of executing a SELECT? This means that if your cursor has 10,000 records, it will execute about 10,000 SELECTs! If you can do this in a couple of SELECTUPDATE or DELETE, it will be much faster.
Beginner SQL programmers find in cursors a comfortable and familiar way of coding. Well, unfortunately this lead to bad performance. The whole purpose of SQL is specifying what you want, not how it should be done.
I've once rewritten a cursor-based stored procedure and substituted some code for a pair of traditional SQLqueries. The table had only 100,000 records and the stored procedure used to take 40 minutes to process. You should see the face of the poor programmer when the new stored procedure took 10 seconds to run!
Sometimes it's even faster to create a small application that gets all the data, proccess it and update theserver. T-SQL was not done with loop performance in mind.
If you are reading this article, I need to mention: there is no good use for cursors; I have never seen cursors being well used, except for DBA work. And good DBAs, most of the time, know what they are doing. But, if you are reading this, you are not a DBA, right?

DO normalize your tables

There are two common excuses for not normalizing databases: performance and pure laziness. You'll pay for the second one sooner or later; and, about performance, don't optimize what's not slow. Often I see programmers de-normalizing databases because "this will be slow". And, more frequent than the inverse, the resulting design is slower. DBMSs were designed to be used with normalized databases, so design with normalization in mind.

DON'T SELECT *

This is hard to get used, I know. And I confess: often I use it; but try to specify only the columns you'll need. This will:
  1. Reduce memory consumption and network bandwidth
  2. Ease security design
  3. Gives the query optimizer a chance to read all the needed columns from the indexes

DO know how your data will be/is being acessed

A robust index design is one of the good things you can do for your database. And doing this is almost an art form. Everytime you add an index to a table, things get faster on SELECT, but INSERT and DELETE will be much slower. There's a lot of work in building and mantaining indexes. If you add several indexes to a table to speed your SELECT, you'll soon notice locks being held for a long time while updating indexes. So, the question is: what is being done with this table? Reading or Updating data? This question is tricky, specially with theDELETE and UPDATE, because they often involve a SELECT for the WHERE part and after this they update the table.

DON'T create an index on the "Sex" column

This is useless. First, let's understand how indexes speed up table access. You can see indexes as a way of quickly partitioning a table based on a criteria. If you create an index with a column like "Sex", you'll have only two partitions: Male and Female. What optimization will you have on a table with 1,000,000 rows? Remember, mantaining an index is slow. Always design your indexes with the most sparse columns first and the least sparse columns last, e.g, Name + Province + Sex.

DO use transactions

Specially on long-running queries. This will save you when things get wrong. Working with data for some time you'll soon discover some unexpected situation which will make your stored procured crash.

DO beware of deadlocks

Always access your tables on the same order. When working with stored procedures and transactions, you may find this soon. If you lock the table A then table B, always lock them in this very same order in all stored procedures. If you, by accident, lock the table B and then table A in another procedure some day you'll have a deadlock. Deadlocks can be tricky to find if the lock sequence is not carefully designed.

DON'T open large recordsets

A common request on programming forums is: "How can I quickly fill this combo with 100,00 items?". Well, this is an error. You can't and you shouldn't. First, your user will hate browsing through 100,000 records to find the right one. A better UI is needed here, because you should ideally show no more that 100 or 200 records to your users.

DON'T use server side cursors

Unless you know what your are doing. Client side cursors often (not always) put less overhead on the network and on the server, and reduce locking time.

DO use parametrized queries

Sometimes I see in programming forums, questions like: "My queries are failing with some chars, e.g. quotes. How can I avoid it?". And a common answer is: "Replace it by double quotes". Wrong. This is only a workaround and will still fail with other chars, and will introduce serious security bugs. Besides this, it will trash the SQL Servercaching system, which will cache several similar queries, instead of caching only one. Learn how to use parameterized queries (in ADO, through the use of the Command Object, or in ADO.NET the SqlCommand) and never have these problems again.

DO always test with large databases

It's a common pattern programmers developing with a small test database, and the end user using largedatabases. This is an error: disk is cheap, and performance problems will only be noticed when it's too late.

DON'T import bulk data with INSERT

Unless strictly necessary. Use DTS or the BCP utility and you'll have both a flexible and fast solution.

DO beware of timeouts

When querying a database, the default timeout is often low, like 15 seconds or 30 seconds. Remember that report queries may run longer than this, specially when your database grows.

DON'T ignore simultaneous editing

Sometimes two users will edit the same record at the same time. When writing, the last writer wins and some of the updates will be lost. It's easy to detect this situation: create a timestamp column and check it before you write. If possible, merge changes. If there is a conflict, prompt the user for some action.

DON'T do SELECT max(ID) from Master when inserting in a Detail table.

This is another common mistake, and will fail when two users are inserting data at the same time. Use one ofSCOPE_IDENTITYIDENT_CURRENT, and @@IDENTITY. Avoid @@IDENTITY if possible because it can introduce some nasty bugs with triggers.

DO Avoid NULLable columns

When possible. They consume an extra byte on each NULLable column in each row and have more overhead associated when querying data. The DAL will be harder to code, too, because everytime you access this column you'll need to check
I'm not saying that NULLs are the evil incarnation, like some people say. I believe they can have good uses and simplify coding when "missing data" is part of your business rules. But sometimes NULLable columns are used in situations like this:
CustomerName1
CustomerAddress1
CustomerEmail1
CustomerName2
CustomerAddress2
CustomerEmail3
CustomerName1
CustomerAddress2
CustomerEmail3
This is horrible. Please, don't do this, normalize your table. It will be more flexible and faster, and will reduce the NULLable columns.

DON'T use the TEXT datatype

Unless you are using it for really large data. The TEXT datatype is not flexible to query, is slow and wastes a lot of space if used incorrectly. Sometimes a VARCHAR will handle your data better.

DON'T use temporary tables

Unless strictly necessary. Often a subquery can substitute a temporary table. They induce overhead and will give you a big headache when programming under COM+ because it uses a database connection pool and temporary tables will last forever. In SQL Server 2000, there are alternatives like the TABLE data type which can provide in-memory solutions for small tables inside stored procedures too.

DO learn how to read a query execution plan

The SQL Server query analyzer is your friend, and you'll learn a lot of how it works and how the query and index design can affect performance through it.

DO use referential integrity

This can be a great time saver. Define all your keys, unique constraints and foreign keys. Every validation you create on the server will save you time in the future.

Selecting Rows Randomly from a Large Table


If you use Microsoft SQL Server 2000, you likely have run into the following problem: You want to select a random sampling of rows from a large table with lots of rows, but you are unsure of how to do so. Having a random sampling of rows can be useful when you want to make a smaller version of the table or if you want to troubleshoot a problem by seeing what kinds of rows are in the table.
To get a random sampling, you might be tempted to select the top n rows from the table. However, this sample is not random, and the first n rows are not necessarily representative of the whole table. Other solutions exist that involve adding columns to the tables; however, adding columns is not always possible or practical.
The standard way to grab random rows from a small table is to use a query such as the following:
  SELECT TOP 10 PERCENT *
  FROM Table1
  ORDER BY NEWID()

The key here is the NEWID function, which generates a globally unique identifier (GUID) in memory for each row. By definition, the GUID is unique and fairly random; so, when you sort by that GUID with theORDER BY clause, you get a random ordering of the rows in the table. Taking the top 10 percent (or whatever percentage you want) will give you a random sampling of the rows in the table.
Often, when questions about how to select random rows are asked in discussion groups, the NEWIDquery is proposed; it is simple and works very well for small tables. However, the NEWID query has a big drawback when you use it for large tables. The ORDER BY clause causes all of the rows in the table to be copied into the tempdb database, where they are sorted. This causes two problems:
  1. The sorting operation usually has a high cost associated with it. Sorting can use a lot of disk I/O and can run for a long time.
  2. In the worst-case scenario, tempdb can run out of space. In the best-case scenario, tempdb can take up a large amount of disk space that never will be reclaimed without a manual shrink command.

Monday, 5 December 2011

how to create sql server database table from c# code


Creating a database table.
private void CreateTableBtn_Click(object sender, System.EventArgs e)
{
// Open the connectionif( conn.State == ConnectionState.Open)
conn.Close();
ConnectionString ="Integrated Security=SSPI;" +
"Initial Catalog=mydb;" +
"Data Source=localhost;";
conn.ConnectionString = ConnectionString;
conn.Open();
sql = "CREATE TABLE myTable"+
"(myId INTEGER CONSTRAINT PKeyMyId PRIMARY KEY,"+
"myName CHAR(50), myAddress CHAR(255), myBalance FLOAT)" ;
cmd = new SqlCommand(sql, conn);
try{
cmd.ExecuteNonQuery();
// Adding records the tablesql = "INSERT INTO myTable(myId, myName, myAddress, myBalance) "+
"VALUES (1001, 'Puneet Nehra', 'A 449 Sect 19, DELHI', 23.98 ) " ;
cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
sql = "INSERT INTO myTable(myId, myName, myAddress, myBalance) "+
"VALUES (1002, 'Anoop Singh', 'Lodi Road, DELHI', 353.64) " ;
cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
sql = "INSERT INTO myTable(myId, myName, myAddress, myBalance) "+
"VALUES (1003, 'Rakesh M', 'Nag Chowk, Jabalpur M.P.', 43.43) " ;
cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
sql = "INSERT INTO myTable(myId, myName, myAddress, myBalance) "+
"VALUES (1004, 'Madan Kesh', '4th Street, Lane 3, DELHI', 23.00) " ;
cmd = new SqlCommand(sql, conn);
cmd.ExecuteNonQuery();
}
catch(SqlException ae)
{
MessageBox.Show(ae.Message.ToString());
}
}
As you can see from Listing 5, I also add data to the table using INSERT INTO SQL statement.
The CREATE PROCEDURE statement creates a stored procedure as you can see in Listing 10-18, I create a stored procedure myPoc which returs data result of SELECT myName and myAddress column.
Listing 5. Creating a stored procedure programmatically. 
Private void CreateSPBtn_Click(object sender, System.EventArgs e)
{
sql = "CREATE PROCEDURE myProc AS"+
" SELECT myName, myAddress FROM myTable GO";
ExecuteSQLStmt(sql);
}
Now I show you how to create views programmatically using CREATE VIEW SQL statement. As you can see from Listing 6, I create a view myView which is result of myName column rows from myTable.
Listing 6. Creating a view using CREATE VIEW
private void CreateViewBtn_Click(object sender, System.EventArgs e)
{
sql = "CREATE VIEW myView AS SELECT myName FROM myTable";
ExecuteSQLStmt(sql);
}
The ALTER TABLE is a useful SQL statement if you need to change your database schema programmatically. The ALTER TABLE statement can be used to add and remove new columns to a table, changing column properties, data types and constraints. The Listing 7 show that I change the database schema of myTable by first change column data type range from 50 to 100 characters and by adding a new column newCol of TIMESTAMP type.  
Listing 7. Using ALTER TABLE to change a database schema programmatically. 
Private void AlterTableBtn_Click(object sender, System.EventArgs e)
{
sql = "ALTER TABLE MyTable ALTER COLUMN"+
"myName CHAR(100) NOT NULL";
ExecuteSQLStmt(sql);
}

The new table schema looks like Table 2. 
Table 2. MyTable after ALTER TABLE
Column NameType               Size                         Property
myId                    integer4Primary Key
myNamechar 50Allow Null
myAddresschar255Allow Null
myBalance float8Allow Null
newColtimestamp 8Allow Null
You can also create other database object such as index, rule, and users. The code listed in Listing 8 creates one rule and index on myTable.
Note: Create Index can only create an index if you don't have an index on a table. Otherwise you will get an error message. 
Listing 8. Creating rules and indexes using SQL statement.

private void CreateOthersBtn_Click(object sender, System.EventArgs e)
{
sql = "CREATE UNIQUE CLUSTERED INDEX "+
"myIdx ON myTable(myName)";
ExecuteSQLStmt(sql);
sql = "CREATE RULE myRule "+
"AS @myBalance >= 32 AND @myBalance < 60";
ExecuteSQLStmt(sql);
}
The DROP TABLE command can be used to delete a table and its data permanently. The code listed in Listing 9 deletes myTable. 
Listing 9. Deleting table using DROP TABLE.
Private void DropTableBtn_Click(object sender, System.EventArgs e)
{
string sql = "DROP TABLE MyTable ";
ExecuteSQLStmt(sql);
}
Now next step is to view data from the table, view and stored procedure. The ViewDataBtn_Click method listed in Listing 10 shows the entire data from the table. The ViewSPBtn_Click and ViewViewBtn_Click methods view stored procedure and view data we have created earlier. As you can see using views and stored procedures work same as you use a SQL Statement. We have discussed working with Views and stored procedures in the beginning of this chapter. As you can see from Listing 10, 11, and 12, I view data from stored procedure and view.  
Listing 10. Viewing data from a database table.  
private void ViewDataBtn_Click(object sender, System.EventArgs e)
{
/// Open the connectionif( conn.State == ConnectionState.Open)
conn.Close();
ConnectionString ="Integrated Security=SSPI;" +
"Initial Catalog=mydb;" +
"Data Source=localhost;";
conn.ConnectionString = ConnectionString;
conn.Open(); 
// Create a data adapterSqlDataAdapter da = new SqlDataAdapter
("SELECT * FROM myTable", conn); 
// Create DataSet, fill it and view in data gridDataSet ds = new DataSet("myTable");
da.Fill(ds, "myTable");
dataGrid1.DataSource = ds.Tables["myTable"].DefaultView;
}
Listing 11.Using a stored procedure to view data from a table.  
private void ViewSPBtn_Click(object sender, System.EventArgs e)
/// Open the connectionif( conn.State == ConnectionState.Open)
conn.Close();
ConnectionString ="Integrated Security=SSPI;" +
"Initial Catalog=mydb;" +"Data Source=localhost;";
conn.ConnectionString = ConnectionString;
conn.Open(); 
// Create a data adapterSqlDataAdapter da = new SqlDataAdapter("myProc", conn); // Create DataSet, fill it and view in data gridDataSet ds = new DataSet("SP");
da.Fill(ds, "SP");
dataGrid1.DataSource = ds.DefaultViewManager;
}
Listing 12.Using a view to view data from a table.  
private void ViewViewBtn_Click(object sender, System.EventArgs e)
/// Open the connectionif( conn.State == ConnectionState.Open)
conn.Close();
ConnectionString ="Integrated Security=SSPI;" +
"Initial Catalog=mydb;" +
"Data Source=localhost;";
conn.ConnectionString = ConnectionString;
conn.Open(); 
// Create a data adapterSqlDataAdapter da = new SqlDataAdapter
("SELECT * FROM myView", conn); 
// Create DataSet, fill it and view in data gridDataSet ds = new DataSet();
da.Fill(ds);
dataGrid1.DataSource = ds.DefaultViewManager;
}
Finally, I create AppExit method which releases the connection and reader objects and I call them from the Dispose method as you can see in Listing 13. 
Listing 13. AppExit method 
protected override void Dispose( bool disposing )
{
AppExit();
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
// Called when you are done with the applicaton// Or from Close buttonprivate void AppExit()
{
if (reader != null)
reader.Close();
if (conn.State == ConnectionState.Open)
conn.Close();
}

How to make web page to be printer friendly


As you can see, window.print() method will print everything in your page, including navigation or Print button. Because of that, possible solution is to have two versions of page, one for displaying on screen and second version for printing. Version for printing will not contain buttons or navigation, but only the report formated for printing. In this case, your print button will have HTML code like this:
<input type="button" value="Print" onclick="window.open('YourPrintPage.aspx')" />
Print button on first page only opens a new window and navigate to print version of the page. At the end of YourPrintPage.aspx, you can add javascript code for printing, like this:
<script language="javascript">
window.print();
</script>
This javascript will execute when page loads and you don't need any button on your printing version.
It is not just about hiding navigations, buttons and other unwanted elements. You need to use different metric units. For screen version it is best to use pixels to define size of fonts, tables, images etc., as you probably already do. But, for print version use points instead of pixels. For example:
body {
   font12pt;
}

Avoid "printer friendly" version of the same content

It is unnecessary to make another page just for printing. Instead of two versions of the same content, it is often better to solve print format problems with css styles and have only one page for both printing and showing on screen. Take a look at bellow html code snippet, you can place it inside page's <head> tag:
<LINK rel="stylesheet" href="style-for-screen.css" type="text/css" media="screen">
<LINK rel="stylesheet" href="style-for-print.css" type="text/css" media="print">
As you can see, there is media attribute inside the LINK tag. Web browser will use style-for-screen.css to show page on screen or style-for-print.css when print the page. Now you can simply hide elements like navigation, buttons etc. For example, let say your navigation menu is inside <div> tag with id = "navigation". To hide it, inside style-for-print.css file code should be:
#navigation { display none }
Or, if you don't want to have two css files, you can do it all in one file, with code like this:
@media print
{
    /*****   Styles for print   ******/
      h1h2h3 {color:black;}
      #navigation {display:none}
}

@media screen {
      /*****   Styles for screen  ******/
}

Friday, 2 December 2011

Differences between ASP.NET and ASP


Dear friends here is a list of differences of the ASP.NET technology and the classic ASP technology.Hope it is informative. Please send your feedback or/and add if you have additional information.

Introduction

These are the list of differences which I came across while working on ASPand ASP.NET projects.

Background


I have seen many articles on Internet where in I came across the differences of ASP.NET and ASP. These articles are jumbled across the websites. I have compiled all those and published this article to give better understanding on the differences of both.

Description


Process Isolation
ASP is run under the inetinfo.exe(IIS) process space and hence susceptible to application crashes as a result the IIS needs to be stopped or restarted. ASP is related to the process isolation setting in IIS.
But, ASP.Net
The ASP.NET worker process is a distinct worker process, aspnet_wp.exe, separate from inetinfo.exe ( IIS process), and the process model in ASP.NET is unrelated to process isolation settings in IIS.
Note :- IIS is still the entry point to a ASP.NET application

Non-MS Platform Support

Classical ASP had no mechanism of running itself on non- Microsoft technology platforms like the 'The Apache Web Server'

But, ASP.NET
ASP.NET could be run on non-Microsoft Platforms also. Cassini is a sample Web server produced by Microsoft which, among other projects, has been used to host ASP.NET with Apache.

Multi Language Support in WebPage


In ASP only two languages were available for scripting VBScript and Jscript/Javascript.
But in ASP.NET
We are no longer constrained to the two scripting languages available in traditional ASP: Any fully compliant .NET language can now be used with ASP.NET, including C# and VB.NET.

Note :- (C# and VB.Net are both server Side languages.)

Interpretation Vs Compilation

In ASPASP engine executes server-side code, which is always through an interpreter (JScript or VBScript). When a traditional ASP page is requested, the text of that page is parsed linearly. All content that is not server-side script is rendered as is back to the response. All server-side script in the page is first run through the appropriate interpreter (JScript or VBScript), the output of which is then rendered back to the response. This architecture affects the efficiency of page rendering in several ways. First, interpreting the server-side script on the fly.As a side effect, one common optimization for ASP applications is to 
move a lot of server-side script into precompiled COM components to improve response times. A second efficiency concern is that intermingling server-side evaluation blocks with static HTML is less efficient than evaluating a single server-side script block, because the interpreter has to be invoked over and over again. Thus, to improve efficiency of rendering, many ASP developers resort to large blocks of server-side script, replacing static HTML elements with Response.Write() invocations instead. Finally, this ASP model actually allows different blocks of script within a page to be written in different script languages. While this may be appealing in some ways, it also degrades performance by requiring that a particular page load both scripting engines to 
process a request, which takes more time and memory than using just one language.
But in ASP.NET,
In contrast, ASP.NET pages are always compiled into .NET classes housed within assemblies. This class includes all of the server-side code and the static HTML, so once a page is accessed for the first time (or any page within a particular directory is accessed), subsequent rendering of that page is serviced by executing compiled code. This eliminates all the inefficiencies of the scripting model of traditional ASP. There is no longer any performance difference between compiled components and server-side code embedded within a page they are now both compiled components. There is also no performance difference between interspersing server-side code blocks among static HTML elements, and writing large blocks of server-side code and using
Response.Write() for static HTML content. Also, because the .aspx file is parsed into a single code file and compiled, it is not possible to use multiple server-side languages within a single .aspx file.
Debugging benefits
In classic ASP it was very difficult for us to debug the application. ASP developers had time to debug application due to limited support due to the interpreted model.
But in ASP.NET In addition to improved performance over the interpreted model, pages that are compiled into classes can be debugged using the same debugging tools available to desktop applications or component developers. Errors with pages are generated as compiler errors, and there is a good chance that most errors will be found at compilation time instead of runtime, because VB.NET and C# are both strongly typed languages. Plus, all the tools available to the .NET developer are applicable to the .aspx developer.

Server-Side code placement Web Page 
class=docText>Especially if you are using ASP pages it is possible to include executable code outside the scope of a function within a script block marked as runat=server, and , it is possible to define a function within a pair of server-side script tags.
But in ASP.NET,
In ASP.NET it is no longer possible to include executable code outside the scope of a function within a script block marked as runat=server, and conversely, it is no longer possible to define a function within a pair of server-side script tags.

    Note also that the generated class definition provides a default constructor for you, and if you try to define your own default constructor within your page, it will cause a compiler error. This can be somewhat frustrating if you are trying to properly initialize elements of your class (such as filling up our array of values or subscribing to events).
    Fortunately, an alternative technique gives you more complete control over the class definition while separating the layout from the page logic. This technique is called code-behind.
Deployment Strategies
In traditional ASP applications, components used by pages and deployed in this fashion were notoriously difficult to update or replace. Whenever the application was up and running, it held a reference to the component file so to replace that file, you had to shut down IIS (temporarily taking your Web server offline), replace the file, and restart IIS.
But in ASP.NET,
The goals of ASP.NET was to eliminate the need to stop the running Web application whenever components of that application need to be updated or replaced that is, updating an application should be as simple as using xcopy to replace the components on the Web server with the new updated versions. To achieve this xcopy deployment capability, the designers of ASP.NET had to ensure two things: first, that the running application not hold a reference to the component file and second, that whenever the component file was replaced with a new version, that new version was picked up with any subsequent requests made to the application. Both of these goals are achieved by using the shadow copy mechanism provided by the Common Language Runtime (CLR).
Shadow copying of assemblies is something you can configure when you create a new application domain in .NET. The AppDomainSetup class (used to initialize an AppDomain) exposes a Boolean property called ShadowCopyFiles and a string property called CachePath, and the AppDomain class exposes a method called SetShadowCopyPath() to enable shadow copying for a particular application domain. The Boolean property turns the mechanism on for a particular application domain, the CachePath specifies the base directory where the shadowed copies should be placed, and the SetShadowCopyPath() method specifies which directories should have shadow copying enabled.
ASP.NET creates a distinct application domain for each application it hosts in its worker process and for each application domain, it enables shadow copying of all assemblies referenced in the /bin directory. Instead of loading assemblies directly from the /bin directory, the assembly loader physically copies the referenced assembly to a separate directory (also indicated in the configuration settings for that application domain) and loads it from there. This mechanism also keeps track of where the assembly came from, so if a new version of that assembly is ever placed in the original /bin directory, it will be recopied into the Noteshadow" directory and newly referenced from there.
In addition to shadow copying of assemblies, ASP.NET needs the ability to create and load assemblies on the fly. The first time an .aspx page is referenced, as we have seen, it is compiled into an assembly and loaded byASP.NET. What we haven't seen is where those assemblies are located once they are compiled. Application domains also support the concept of a "dynamic directory" specified through the DynamicBase property of the AppDomainSetup class, which is a directory designed for dynamically generated assemblies that can then be referenced by the assembly loader. ASP.NET sets the dynamic directory of each application it houses to a subdirectory under the system Temporary ASP.NET Files directory with the name of the virtual directory of that application.
One consequence of both dynamic assembly generation and shadow copying is that many assemblies are copied during the lifetime of an ASP.NET application. The assemblies that are no longer being referenced should be cleaned up so that disk space usage doesn't become a limiting factor in application growth. In ASP.NET shadow copied assemblies are removed as soon as possible after a new version of that assembly is copied, and dynamically generated assemblies that are no longer used are cleaned up the next time the ASP.NET worker process is bounced and the particular application associated with the dynamic assemblies is run again. In general, this means that you shouldn't have to worry about unused assemblies generated by ASP.NET wasting space on your machine for very long.
New Page Directives
In ASP you must place all directives on the first line of a page within the same delimiting block. For example:
<%LANGUAGE="VBSCRIPT" CODEPAGE="932"%>

But in ASP.NET, you are now required to place the Language directive with a Page directive, as follows:
<%@Page Language="VB" CodePage="932"%> <%@QutputCache Duration="60" VaryByParam="none" %>

You can have as many lines of directives as you need. Directives may be located anywhere in your .apsx file but standard practice is to place them at the beginning of the file. Several new directives have been added inASP.NET. I encourage you to look these up in the ASP.NET documentation to see how they may benefit your application.

Threading Issues
The threading model of COM object created using VB within a web-based application is STA. ASP worker thread resides in its own STA and hence the compatability is fine in this case with a little performance hit.
But in ASP.NET,
The ASP.NET threading model is the Multiple Threaded Apartment (MTA). What this means is that components that you are using that were created for the Single Threaded Apartment (STA) will no longer perform or function reliably without taking some extra precautions in ASP.NET. This includes, but is not limited to, all COM components that have been created using Visual Basic 6.0 and earlier versions. You will be glad to hear that you can still use these STA components without having to change any code. What you need to do is include the compatibility attribute aspcompat=true in a <%@Page> tag on the ASP.NET page. For example, <%@Pageaspcompat=true Language=VB%>. Using this attribute will force your page to execute in STA mode, thus ensuring your component will continue to function correctly. If you attempt to use an STA component without specifying this tag, the run time will throw an exception. Setting this attribute to true will also allow your page to call COM+ 1.0 components that require access to the unmanaged ASP built-in objects. These are accessible via the ObjectContext object. If you set this tag to true, your performance will degrade slightly. I suggest doing this only if you absolutely need to.

Validation & Browser scripting capabilities
  • ASP has no inbuilt facility for Validation of controls.i.e, checking whether a textbox is left blank or not or a combo is selected or not or if a phone number does not fit a particular pattern for a area and many such examples.
  • The user had to write the client side Javascript code for all these kind of validations.
  • Client and server side validation both were the headache of the of the developer.
  • Javascript code to fit a particular Browser was also the developer's burden. He had to write specific code so that it could fit a set of browsers. It took lot of the developers time.
But in ASP.NET,
In built validation controls are provided which are as easy to implement and the developer has to worry the least.
The features provided by ASP.NET validation controls is :- 
  • Browser Independent coding :- Developer does not have to worry about the browser how the controls would render to.
  • Client-Side or Server-Side :- The Validation Controls manage the code checking if the client side code is disabled the validation is done on the server side.

Rich Validation set :- There are 6 types of validation which cater to the needs of the validation requirements:
  • RequiredFieldValidation Control - Requires that the control not be left blank.
  • CompareValidator Control - Used to compare Data in Two Controls
  • RangeValidator Control - Used to check for Range validation.(also supports various data Type - Date , string etc..)
  • RegularExpressionValidator Control - Used to check the complicated patterns in the user input.
  • CustomValidator Control- The final control we have included in ASP.NET is one that adds great flexibility to our validation abilities. We have a custom validator where we get to write out own functions and pass the control value to this function.
This control also provides Client side and server side validation of which the Server side validation could be a different function altogether.
    • Validation Summary - The validation summary control will collect all the error messages of all the non-valid controls and put them in a tidy list. The list can be either shown on the web page (as shown in the example above) or with a popup box

    Conclusion

    This article targets to the developers who have directly started working on ASP.Net and also for the web developers who have migrated from ASP to ASP.Net. This article is at the draft level and might need additions which I intend to do.I welcome suggestion or criticism!! I would request to add as much feedback to this article post as possible. I would keep this post updated. 
    Contact Us:

    Email:

    Vinodkumar434@gmail.com,
    vinodtechnosoft@gmail.com

    Skype Name:

    vinodtechnosoft