ASP.NET 2.0 Compilation In A Nutshell

" It's all about first hit "

ASP.NET 2.0 Compilation is one of the best changes done on v 1.x, but to get the full picture you should understand how compilation was maintained in older versions. In ASP.NET 1.x, if you are working using code behind model, after you compile your site everything is placed in one, or more, assembly, and the ASPX pages stay untouched, until the user requests a page for the first time, that was somehow confusing, what actually happens is that when you compile your application; you only compile the code-behind files, while the ASPX files, are getting compiled upon request, in other words after they are parsed by ASPX parser, the pages are compiled and merged with the code behind file which is already compiled ( MSIL ) and then you get out of this by an assembly, this assembly is compiled using JIT compiler to machine language, and then gets executed emitting the final output ( HTML ) to the user and the compiled page is written or cached to disk for future requests, that is what happens upon the first request, but for all upcoming requests the request goes directly to the previously compiled assembly, and that is a huge deal of time saving, this explains why you were always feeling the first hit to your page is sluggish, but any later requests are very fast!


After you finish developing your application you'll likely need to change your application which in turn implies recompiling your application, so again after users start to hit your application , modified one, for the first time they will suffer poor performance, but developers used to bypass this first hit long response time, by writing a script that hits or requests each and every page in the entire application, so for future requests the application will respond in no time !

The above scenario gave birth to precompilation in ASP.NET 2.0, so here we have 2 kinds of compilation , In-Place Precompilation and Precompilation for Deployment.

ASP.NET 2.0 In-Place Precompilation

Simply, that is a solution for the first hit problem, here you can just make a call for axd file that hits each and every page in your application that will save you the first time request sluggishness, you can do that by calling : http://Server/ApplicationName/Precompile.axd , this if you your using IIS, but if you are using the personal web server you will format it like this : http://Server:PortNumber/ApplicationName/Precompile.axd

Warning

If you try to access the precompile.axd you will get an 404 error, I tried to figure out what's happening and after some search in KBs and forums, I figured out that this feature is not supported anymore!, so the above axd method is just mentioned for keeping record ( I found some posts saying that it's been stopped since Beta 2, and replaced by aspnet_compiler which we'll discuss in the following section).so this feature has been dropped from the early versions.


Note

The old way of compilation that was known as Pre-Runtime compilation is still valid, in which you compile your code-behind files into one assembly or more placed in the bin directory, and the webforms are just compiled upon request, also you should know that the code is getting compiled by JIT from MSIL into Machine code.!

ASP.NET 2.0 In-Place Precompilation Revisited ( aspnet_compiler )

In this section, we're gonna examine using the In-Place Precompilation using the command prompt utility aspnet_compiler, you can browse to this utility from Visual Studio 2005 Command Prompt, and then browse to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50xxx It’s good to see all the arguments the aspnet_compiler is taking, try typing this into the command prompt aspnet_compiler /? You will get a full description d the compiler tool, in the following table I will show you the most important switches for aspnet_compiler

Switch

Description

Notes

-v

This is the virtual path of the web application to be compiled

This should be used with –p switch but –p is optional if not passed the IIS metabase if used to lookup the virtual path location

-p

Physical location of virtual path

Optional

-f

Overwrites previous compilation output

All previous contents are lost

-d

Shows debug information while compiling

-c

For complete recompilation

Helpful with –targetDir

-targetDir

Output location

If not specified output is written to C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files

-keyfile

Path to strong name key file

Strong name key files used to digitally sign your assemblies and to publish to Global Assembly Cache (GAC)

-fixednames

To generate assemblies with the same names in the output directory

Whenever you maintain pre deployment compilation you get assembly files named with a random pattern so in case you update the application you will get ended with a lot of assemblies, so this switch is very important it generates and overwrite existing assemblies.

For the in-place precompilation, you can create a simple web application call it CompilationTest, you can leave it as it is, or write any simple code in Page_Load, then you can enter the following into the command prompt

aspnet_compiler -v /CompilationTest

After few seconds you will get the result of your compilation.

The output is written to the Temporary ASP.NET Files special directory, it’s located at the version directory, in this directory you’ll find a folder named with your application name, in this case CompilationTest.

You’ll go through nested folders named using some pattern, and then you will find a DLL assembly starts with App_Web_xxxxxxxx.dll, this is the assembly containing all the code for your application, also you will find an XML based file with .compiled extension if you try to open this file you will get a list meta data for ASPX page and code behind files as well; one file is created for one aspx page, there is one more file called hash.web; I opened this file found this key “cb06f3a30ef12111”, actually I couldn’t figure out the use of this file, but it seems to be for versioning, also sometimes you might get an error saying that another process is holding or locking this file, if you get such an error, try to stop the windows indexing service.

Pre- compilation For Deployment ( aspnet_compiler )

The Pre-Compilation for Deployment, is compiling both the webforms and code behind files, remember the in place precompilation only compiles the code behind files, so this is a great deal of responsiveness, this way you just copy the files and transfer the application directory to your production environment with no pain!

Here also we’ll use aspnet_compiler command prompt tool but this time we shall supply an output directory so the output will be written to the path specified not the Temporary ASP.NET Files.

Try to use the same web application CompilationTest, and add a folder form solution explorer, then add to this folder a webform, and an html file, then go to VS.NET 2005 Command prompt, enter the following :

aspnet_compiler -v /CompilationTest C:\out

The output is written to the destination folder, the output is supposed to be the same as your physical folder, with the same folders tree, also in the bin folder you will find .compiled and .dll files, these assembly files ( .dll ) hold all master pages, all the aspx pages, they’re holding everything in your application, but if you have html or textual files, they are just copied to the output directory, you will find a copy of the html file you have created from solution explorer, the most remarkable thing is that when you open ASPX, ASCX, and ASHX, you will find a single line containing :

“This is a marker file generated by the precompilation tool, and should not be deleted!”.

So these files are simply placeholders, to keep the structure of your web application.

You can xCopy your application to FTP location, also this provides a good deal of protection for your code as you have zero code files, neither .VB nor .CS files included, noting that the APP_CODE directory is getting compiled too.

Warning

If you try to output compilation output to a directory that is under the web application folder you will get the following error “ error ASPRUNTIME: The precompilation target directory C:\Inetpub\wwwroot\CompilationTest\CompilationOutput\) cannot be in the same tree as the source application directory (c:\inetpub\wwwroot\CompilationTest\). Also one thing worth trying, after you run your command and precompile your application for deployment, try to run it again, it will fail because the out directory is not empty, to bypass this supply the “-f” switch, to force overwriting old contents of the destination directory!

Note

There is another important use for the precompilation; in case you have any compilation errors they will be thrown during compilation and the process will halt, to try this, delete the code behind file and try to recompile your application using aspnet_compiler command prompt tool, you will get an error saying the code behind file is missing, this way you will be sure your application is error free.

Labels:

BizTalk 2006 Installation

I have just finished installing BizTalk 2006 on Windows 2003 Enterprise Edition SP1, one of the things that made BizTalk 2004 a real pain was its installation, however installing BizTalk 2006 is a real fun, and it’s straightforward, It’s kind of ( Next, Next, …, Finish ), If you have Internet connection it’s better to let the installation wizard to update all required components through the web, or if you plan to install it to other machine, you can download a cab file and reuse it everywhere else, actually I cannot forget how hard it was to install BizTalk 2004 prerequisites, which made me opt to use VHD image, and I used MS Virtual PC, now it's easy to get it up as the wizard provides a component updater and it's really a one click configuration, how simple !, however to create Groups and get started with BizTalk 2006, if you have SQL Server 2000, you should have SP4 installed to configure BizTalk 2006 from BizTalk Server Configuration.

You can select Basic Configuration and BizTalk Configuration will take after everything, it’s really simple!

You can download SQL Server 2000 Service Pack 4 from here, then you can select the components that most interest you.

After you select Basic Configuration if there is anything incorrect you will get one warning, also to make sure everything is fine, run BizTalk Server 2006 Administration Console; actually it's MMC, from left tree expand BizTalk Server 2006 Administration , then expand BizTalk Group[MachineName:BizTalkMgmtDb], expand Applications node, you will get 2 applications; BizTalk.System, and BizTalk Application 1; this assures that group has been created correctly.

Note: After installing BizTalk 2006 it creates 2 default applications first is BizTalk.System which contains all artifacts required to run built-in applications like Business Activity Services ( BAS ), also it contains some components that are part of BizTalk runtime which is required to each and every BizTalk application, second application is just a default application.

Labels:

ASP.NET 2.0 Cross Page Posting

Introduction [Download Code]

In ASP.NET 1.X the default postback behavior is to postback the page to itself, but sometimes you need to post your page to another page in your application which was difficult in ASP.NET 1.x while it was so easy in ASP 3.0, so this missing feature is back to ASP.NET 2.0.

What The Problelm Is All About

I remember a problem that I have encountered before in ASP.NET 1.1, I was developing a checkout module in which the user is going through multiple pages to place an order, entering credit card, personal, and delivery information; the information was splitted on around 7 pages, and it was kinda wizard ( Thanks to Wizard Control in ASP.NET 2.0 ), so the user could move from one page to the other back and forth, but this information would be kept in one place and I have overriden the page submission through one java script snippet to post back to other page, that was simple, the challenge was how to expose the first page data to the recipient page, this actually could be done by more than one way, one is storing data into a cookie, other to store it into a user session on ther server, or to send them using Query strings parameters ( actually this is not a postback ! ), but by all the means the more pages you get the more complexity you will be in!

Handling Postbacks in ASP.NET 1.X

One of the commonly used properties in ASP.NET 1.X is Page.IsPostBack , it simply determines wheather it's a first request ( get ) , or a postback ( post ) operation, and it was really helpful for performance purposes, especially in cases of heavy data operations, for example if you have data grid that you populate when the page is loading and user selects one row, this selection required doing postback ( Thanks to AJAX ! ), so the page is flickering and also it's reloaded on the server, all the data are actually kept in the ViewState so there is no need to grab data again from database, here the importance of this magical property comes to light!

ASP.NET 2.0 Cross Page Postbacks

ASP.NET 2.0 came to make life of developers easier, and just to solve common problems that developers spend most of their time on, which consequently eating the project time. In ASP.NET 2.0 Cross Page Postbacks is so simple, actually more than simple, in the following lines you'll be shown almost everything you need to know about cross page postbacks in ASP.NET 2.0.

Practical Example

Run your VS.NET 2005, create a new web application, C# and it's preferred to leave defaults, remove the default page, and then add a page call it Personal Details.aspx, design the page as shown in the following picture







Rename the controls to whatever names you like, however you will find them named in a logical pattern, select the Next button, from properties window select property PostBackUrl and set it to LoginDetails.aspx , double click the Finish button to open the event handler method for click event of the button and enter the following code :



protected void btnFinish_Click(object sender, EventArgs e)


{


StringBuilder details = new StringBuilder();


details.Append("First Name : " + txtFirstName.Text + "<br/>");


details.Append("Last Name : " + txtLastName.Text + "<br/>");


details.Append("Address : " + txtAddress.Text + "<br/>" );


details.Append("Date of Birth : " + calDateOfBirth.SelectedDate.ToShortDateString());


lblDetails.Text = details.ToString();



}


As you can see above, this code is nothing new; you postback your page to itself, you read some control values then you concatenate everything then you display it in one lable.

Note : When you open your Login Details.aspx page code behind you will notice that your variables are not written to the code behind class as they were in ASP.NET 1.x, while they are just written while compiling your code, and this is the new Partial Classes approach introduced by ASP.NET 2.0, if you are not familiar with partial classes please refer to my blog post about Partial Classes.

Setting the PostBackUrl property doesn't imply you cannot add code for Click event handler, however still you can code to this button click event handler, after this code gets executed the page posts back to the second page, for demonstration purposes we've added the following code to event handler of the Next button, please double click the button and enter the following :




protected void btnSubmit_Click(object sender, EventArgs e)


{


Response.Write("<center><h2>Please Be Patient, You'll be Directed to Next Page Shortly !</h2></center>");


}


Now, we're done with the first page and it's the time to manage the recipient page, to process incoming post back data from the sender page, actually there is a new property of the Page Class called PreviousPage , and this property gets a reference to the page that gave control to the current page ( as described by MSDN ), and you can get access to all the members of a standard Page class, however we cannot write for example PreviousPage.txtFirstName.Text, this is basically because the controls are declared as Protected, so you've got 2 ways to do it, first is to use the mostly common used method FindControl , passing the control id and casting to the proper control data type, and second is to expose the controls that you need to use in second page as public properties, we'll introduce the second approach is it's more organized and object oriented, however the first one also works and it's a single line to be written.

Note : for the first approach you will need to write a line of code like this one,

TextBox postedFirstName = (TextBox)PreviousPage.FindControl("txtFirstName");


Then, you can use postedFirstName as a clone of the original txtFirstName at the first sender page.For the second approach we'll need to expose the controls as public read-only properties from the sender page, this one example for first name textbox :

public TextBox postedFirstName

{
get

{

return txtFirstName;

}

}


You should do the same for all other controls you want to expose to your recipient page, however you will find the complete code in the downloadable sample attaching this article.

Now, go to the LoginDetails.aspx or the recipient page, and enter the following :



protected void Page_Load(object sender, EventArgs e)


{


lblDetails.Text = "First Name Entered in First Page is " + PreviousPage.postedFirstName.Text;


}




Try compiling your page; you will get a compile error described as : 'System.Web.UI.Page' does not contain a definition for 'postedFirstName', and this definately makes sense, as you're still in design time so how could the compiler know that postedFirstName is a member of the PerviousPage, so we have to supply something more to let the compiler aware of the PreviousPage data type, consequently you will be able to use the pretty bless of Intellisense.

Go the Source view of LoginDetails.aspx and add the following directive just after the main Page directive

<%@ PreviousPageType VirtualPath="~/Personal Details.aspx" %>



This will tell the compiler and VS.NET Intellisense about your PreviousPageType, try compiling now the LoginDetails.aspx you will get no errors.

Note : Sometimes you use one page for more than one purpose, so in the above example LoginDetails page could be used as a standalone page away from the posting page, and at other times it could receive postback data from the first page, so you should distinguish between these 2 modes, to better handle events and postback data, you can edit the page load event handler in LoginDetails.aspx to be like this :



protected void Page_Load(object sender, EventArgs e)


{


if (Page.IsCrossPagePostBack)


{


lblDetails.Text = "First Name Entered in First Page is " + PreviousPage.postedFirstName.Text + "<br/>";


lblDetails.Text += "Last Name Entered in First Page is " + PreviousPage.postedLastName.Text + "<br/>";


lblDetails.Text += "Address Entered in First Page is " + PreviousPage.postedAddress.Text + "<br/>";


lblDetails.Text += "DOB Entered in First Page is " + PreviousPage.postedDateOfBirth.SelectedDate.ToShortDateString();


}


}



Now, you will only manage postback data if and only if the page is involved in a cross postback.

Warning : for some unknown reason you will always find the property Page.IsCrossPagePostBack false, I searched for the reason but I couldn't figure out why, also I found so many people wondering about this, unfortunatel I couldn't find and answer for this, it seems to be useless property, however you can work around this by reconstructing the condition to be like this :


if (Page.IsCrossPagePostBackPreviousPage != null)


As PreviousPage is not null in case of cross postback.

Conclusion

ASP.NET 2.0 Cross Posting is a great addition to ASP.NET 2.0, but the IsCrossPagePostBack property is somehow non-functional, while the PreviousPage property is always populated.

Labels: