5 Ways HTML5 can Speed Up Your ASP.NET Application

Html5 is often touted as a great solution for delivering multi-platform apps, but the performance boost of using Html5 in existing applications is often overlooked. Here we present 5 ways for you to use Html5 (plus CSS3 of course !) to boost the performance of your ASP.NET and ASP.NBET MVC apps.

  1. Use Html5 Input Types and Form Attributes
    One of the most common tasks in developing a web app is setup the input forms which will normally include client side validation (for example to ensure a valid email was input) , range restrictions (for example a minimum bid amount) and watermarks (ie textboxes with pre-input grayed-out text). This is normally implemented using javascript, ASP.NET simplifies many of these tasks by providing attributes for the ASP.NET TextBox however this is implemented in the final html by auto-generated javascript. This is results in a lot of extra page load and can complicated the debugging.
    Fortunately Html5 includes pre-defined input types such as email which performs many of these functions. For example, a textbox which only accepts an email address and has a placeholder (watermark) of “email address” would be

    <input type="email" placeholder="email address" />

    The are numerous input types included in Html5, a good example of these in operation is at Html5 Forms Demo

  2. Use CSS3 Instead of Images
    Images are often used for styling web elements, such as rounded corners, buttons, gradients, text effects (such as 3D or inset text). CSS3 provides support for all of these out-of-the-box so you page will no longer have to request and load images. With the introduction of IE9, all major browsers now support for these CSS3 properties, although it should be noted that rendering them in mozilla and webkit based browsers (such as Safari and Chrome) requires slightly different CSS code.
    See CSS Performance with Fewer Images for a full listing of all the available CSS3 styles to replace images.

Continues…

ASP.NET ViewState Security

ASP.NET ViewState data is stored in a single Base64-encoded string  such as  this:

id="__VIEWSTATE" value="dDw3NDg2NdTI5MDg7Ozr4="/>

Since this value is not formatted in clear text, developers sometimes assume that their ViewState data is encrypted which is most certainly not the case. This data string can be reverse-engineered this and then viewed. This is an obvious security issue if sensitive data is being stored in ViewState.

To make ViewState secure, there are two choices, hash codes and ViewState encryption.

Use a hash code.

A hash code  is a cryptographically strong checksum. When you use a has code, ASP.NET calculates the checksum based on the current ViewState content data and then adds this to the hidden input field when the page  when is returned to the client.  On the page post back, ASP.NET then recalculates the checksum to  ensures a  match. If a malicious user were to  change the ViewState data, ASP.NET can detect the  the change reject the postback.
Hash codes are enabled by default,  however, sometimes developers elect  to disable hash codes to prevent problems on a web farm when  servers have different keys. Hash codes can be disabled on the page in the .aspx file’s Page directive:

<%@ Page EnableViewStateMac="false" ... %>

To disable hashing site-wide use the  ViewStateMac attribute of the pages  element in  web.config :

<configuration>
<system.web>
<pages enableViewStateMac="false" />
...
</system.web>
</configuration>

For more on hashing, please refer to C# Security – Hashing

Use ViewState Encryption.

Hash codes help to prevent ViewState data from being tampered with but they do not provide much assistance in preventing ViewState data from being read since hash codes can still be converted to clear text. To prevent ViewState being read, use the  ViewState Encryption, which can be turned on at the page level using the ViewStateEncryptionMode property of the Page directive:

<%@Page ViewStateEncryptionMode=”Always” … %>

Or site-wide in the web.config file:

<pages viewStateEncryptionMode=”Always” />

There are three settings for viewStateEncryptionMode:

  1. Always : All ViewState data is encrypted.
  2. Never : No ViewState data is encrypted.
  3. Auto : Data is only encrypted when specifically requested by the ASP.NET control.

The default setting is Auto so no data will be encrypted unless otherwise requested by a control on a page. For a control to request encryption in needs to call the Page.RegisterRequiresViewStateEncryption() method before it is rendered to HTML.

Note that using encryption incurs a performance penalty so it should only be used when necessary.

ASP.NET Control State for Custom Server Controls

State management is a perennial challenge for any web development framework – once a page is refreshed any data on the page (such as text already entered in textboxes) must be persisted using some method. Traditionally ASP.NET solves this problem using View State which inserts text directly into the html of the page which can then be read by the server when the page is posted to the server. This solution works well in most circumstances but the one major issue is performance – View State adds a large payload to each page request and will slow the ASP.NET site/app down. The issue is especially acute when using ASP.NET AJAX since there are numerous background hits on the server and each of which needs to contain the full View State payload.

Control State is designed to be a much more lightweight store of data than view state . Control State is designed to store   data a control is currently using. Technically, control state works in the same manner as view state—storing serializable data that’s placed in a hidden field when a page is rendered. ASP.NET actually puts   view state and control state data into the same hidden field. The only major difference is that control state is unaffected by the EnableViewState property, therefore even if EnableViewState is set to false, acontrol can still store and retrieve data from  control state.

Since control state cannot be disabled, you will need to  carefully restrict the amount of information stored. Normally, it is limited to something critical such as the current page index or else a data key value. To use control state in  a custom server control, you   begin by overriding the OnInit() method and the calling Page.RegisterRequiresControlState() to notify ASP.NET that the control needs to access control state.

protected override void OnInit(EventArgs e)
{
base.OnInit(e);
Page.RegisterRequiresControlState(this);
}

Unlike view state, control state cannot be accessed  directly through a collection and you must override two methods:  LoadControlState() and SaveControlState(). These methods use a slightly irregular pattern. The overall idea is that you need to take any control state which has been serialized by the base class and then combine that with an object which contains your new serializable object. You can do this using the System.Web.Pair class, as shown below:

string myData;
protected override object SaveControlState()
{
// Get state from the base class.
object baseStateObj = base.SaveControlState();
// Combine  with the state object you wish to store
// and then return the final object.
return new Pair(baseStateObj, myData);
}

This technique will enable you to only store  a single object. For storing several items of information, consider creating a custom class which encapsulates all these details (and ensure it includes the Serializable attribute). An alternative method is to  create a chain of Pair objects:

private string strData;
private int integerData;
protected override object SaveControlState()
{
// Get state from the base class.
object baseStateObj = base.SaveControlState();
// Combine with the state objects you want to store,
// and return the final object.
Pair pairA = new Pair(strData, integerData);
Pair pairB = new Pair(baseStateObj, pairA);
return pairB;
}

Continues…

ASP.NET Hosting Guide

The first choice to consider in selecting an ASP.NET Host is to select between Shared Hosting, VPS Hosting, and Dedicated Server Hosting:

ASP.NET Shared Hosting
(typical price $5 – $25 per month)

In shared hosting the web host allocates a portion of a server to your hosting plan. Typically you are given a fixed amount of disk space and bandwidth but no other resources (such as memory or CPU) are dedicated to your plan. A shared hosting will not allow for any access to the root OS, therefore you will not be able to install programs (such as backup software) on the Windows Server OS that runs the site, nor will you be able to configure IIS to your exact needs (IIS tasks can often be handled by the control panel you will be given but note that some IIS functions such as dynamic compression make not be available on your shared hosting plan).

There should also be at least one SQL Server database included in the package (be sure to check the cost of adding additional SQL Server databases as this cost varies a lot between hosts). Also note the size of the database which should be 100MB for a starter plan. Always check with your host if you will be able to connect to your SQL Server database via SQL Server Management Studio (SSMS) as this is very important in administering the database. Note that when you set up your SQL Server database be sure to set the Recovery Model to Simple and Auto-Shrink to True in the Properties > Options of the database in SQL Server Management Studio. This will dramatically cuts the size of your database.

Shared hosting will normally be administered through a control panel. Plesk is generally considered to be the best of the bunch of control panels although it is often charged at a premium to other control panels. In my experience most control panels will do the job just fine since you will have a limited amount of control that any shared hosting can have over the operation system. Most of the time you will connecting with your host by FTP’ing the files to the server.

Most shared hosts offer unlimited domains to be setup on your plan, although you should check the limit if you plan on running a large number of sites. Note that although the hosts will allow you to register domains with them you should always register the domain with a third party (such as GoDaddy) as it will be much easier to move hosts when the domain is with a separate registrar.

Shared hosting is the most difficult form of hosting to evaluate from just the specs provided by the hosting providers since there are no resources dedicated to your individual plan and you have actually no idea how many sites are stuffed onto the server you share, or the hardware of the server or how the shared SQL Server is configured – in short it is impossible to guess the quality of hosting you are being offered. The only way to evaluate shared hosting is to sign up for a month and check the performance of your ASP.NET web app. The paid version of Pingdom is a good tool for this as it provides a graph of the responsiveness of your app over time, if you dont wish to use the paid version you can enter a URL from your site in the Pingdom load time test (which is free) and then manually compare the response times.

One issue to consider in shared hosting is backups. Since you won’t have access to the OS you won’t be able to install third party backup software. In addition, SSMS may be restricted in making backups since they need to be stored on a physical directory on the server. This is one issue you will need to ask the web host provider about. Ideally you should be able to schedule a regular offsite backup of the site files and database.

ASP.NET VPS Hosting
(typical price $35 – $75 per month)

Virtual Private Server (VPS) hosting is the next step up on the ASP.NET Hosting ladder. Since the introduction of Hyper-V (Microsoft’s virtualization technology for Windows Server) ASP.NET VPS hosting has developed a lot and VPS Hosting is now the main entry point into ASP.NET Hosting. A VPS is essentially a fully isolated instance of a Windows Server operating system with its own dedicated resources which sits alongside other VPSs on the same server. Thus you would be fully isolated from other users on the same server and be able to Remote Desktop into your server and install apps such as backup utilities and setup IIS and SQL Server.

As such a VPS Hosting plan will provide a full compliment of dedicated resources such as disk space, bandwidth, memory and CPU. Note, however, that the CPU allocation for a VPS is not always very clear – many providers simply quote the specs of the actual server CPU (such as 2 Dual Core Xeon processors) without quantifying how much is dedicated to each VPS plan (part of the problem in this is that there is no agreed upon standard quoting a  CPU resource).

In reality the CPU allocation is often of little consequence as most of the performance will come from the hard drive, the memory and the network on which the physical server sits. Since the quality of the network cannot be acertained from the hosting provider’s specs you should look at the memory and hard drive. In general you try get the maximum amount of memory possible, especially if you will be running SQL Server – on my previous host (a dedicated host). It is surprising the amount of memory which can be consumed if it is available.  I previously ran an app on 4GB RAM server of which the system utilized about 3.6 GBs when I moved host I rented a server with 8GB memory and 7.5 GB is currently used by the exact same app with almost all the increase being taken by SQL Server (despite the app using caching where possible). Needless to say the app’s responsiveness increased dramatically.

The disk specs are not always disclosed by the hosting provider, ideally this would be SAS storage although SATA (hopefully 7200 RPM) would also do a good job.

VPS is sometimes termed Virtual Dedicated Hosting (VDS) although normally it is the same principal. Just ensure that all the system resources are dedicated to your ‘VPS’.

ASP.NET Dedicated Server Hosting

A VPS plan will normally be suitable for a small to medium sized enterprise, but if your app(s) have a very high resource utilization you should consider a dedicated server.  For example I run SQL Server Performance.com which serves about 30,000 pages a day as well as DerivativesONE.com which prices complex financial derivatives. Running both of these on a high-spec VPS gave generally poor results in terms of the responsiveness of both sites. A major limiting factor of a VPS is that although the memory is dedicated, the CPU and disk I/O are in reality shared resources with all the other VPS plans across the server farm. In most other respects a dedicated server is very similar to a VPS and should be evaluated in a similar manner.

One issue to be aware of for dedicated hosting is the contract. You should always look carefully at the contract clauses, especially the renewal of the contract – some of the smaller web hosting providers require signed annual contracts which automatically renew without a prior cancellation.

ASP.NET Cloud Hosting

A comprehensive overview of ASP.NET hosting wouldn’t be complete without a mention of cloud hosting. Cloud hosting is the latest buzz in web hosting but unfortunately, in my experience, there is little to recommend it for hosting ASP.NET applications/sites. Most of the major cloud hosting providers such as RackSpace Cloud or Amazon Web Services (AWS) are focused on providing solutions for developers building on the LAMP Stack and so there are major omissions in their cloud offerings, for example neither RackSpace or AWS offer an easy install of SQL Server.
Windows Azure is Microsoft’s Windows cloud hosting offering but it is not fully compatible with existing ASP.NET web apps  and so is more suitable for apps which are built from the ground up to run on Azure.

SQL Server

SQL Server is most expensive part of the Windows  stack which will run your web app, so it deserves careful attention. SQL Server is licensed on a per-processor basis and so when selecting you sever specs always prefer a more powerful Quad-Core to two Dual-Cores since the Quad-Caore will half your SQL Server cost.

Also ensure that if you are using VPS or dedicated servers that the providers offers the SQL Server Web-Edition, several do not publicize this since it will only be about $25 per month as opposed to over $300 for the WorkGroup edition but it in most cases works equally well in a web environment.

If your host charges by size of the database make such it is optimized for size- AutoShrink on, Simple Recovery etc

General Issues across all Hosting Plans

There are a few other factors which are common to any hosting plan which you should consider:

  • .NET Specialization : You should always prefer hosts which focus solely on .NET hosting. Hosts who specialize in ASP.NET will be much better able to support your issues and are usually quicker to upgrade to the latest versions of the .NET platform.
  • Support : Difficult to determine in advance since all hosts claim fantastic performance, but one thing that will always come in useful in  24/7 chat which works great for quickly getting support on small issues such as reboots etc.
  • Test for a month first : Don’t commit for a year before you have tried the host for a month at least. As noted above some of the factors such as the network speed of the hosting provider’s network are not disclosed (or can’t be quantified).
  • IP Addresses : If you are running multiple sites, it is advisable to have each on a separate IP Address, check how many IP’s the plan comes with and the cost of additional IPs.

Anything I missed out? Any experiences to share? Please leave a comment and let us know.

ASP.NET MVC 3 First Look

ASP.NET MVC 3 Preview 1 has just been released and is now available for download here. Microsoft is now using Preview as the name for its early releases which roughly corresponds with the old CTP release type.

The first thing to not is that MVC 3 is backwards compatible with MVC  2, and can be installed side-by-side with MVC 2 – so you can use the current distribution for testing without impacting your current MVC 2 projects.

MVC 3 View Enhancements

MVC 3 introduces two improvements to the MVC view engine:

  • Ability to select the view engine to use. MVC 3 allows you to select from any of your  installed view engines from Visual Studio by selecting Add > View (including the newly introduced ASP.NET “Razor” engine”):
    MVC 3
  • Support for the next ASP.NET “Razor” syntax. The newly previewed Razor syntax is a concise lightweight syntax.

MVC 3 Control Enhancements

  • Global Filters : ASP.NET MVC 3  allows you to specify that a filter which applies globally to all Controllers within an app by adding it to the GlobalFilters collection.  The RegisterGlobalFilters() method is now included in the default Global.asax class template and so provides a convenient place to do this since is will then be called by the Application_Start() method:
    void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
    filters.Add(new HandleLoggingAttribute());
    filters.Add(new HandleErrorAttribute());
    }
    void Application_Start()
    {
    RegisterGlobalFilters (GlobalFilters.Filters);
    }
  • Dynamic ViewModel Property : MVC 3 augments the ViewData API with a new “ViewModel” property on Controller which is of type “dynamic” – and therefore enables you to use the new dynamic language support in C# and VB pass ViewData items using a cleaner syntax than the current dictionary API.
    Public ActionResult Index()
    {
    ViewModel.Message = "Hello World";
    return View();
    }
  • New ActionResult Types : MVC 3 includes three new ActionResult types and helper methods:
    1. HttpNotFoundResult – indicates that a resource which was requested by the current URL was not found. HttpNotFoundResult will return a 404 HTTP status code to the calling client.
    2. PermanentRedirects – The HttpRedirectResult class contains a new Boolean “Permanent” property which is used to indicate that a permanent redirect should be done. Permanent redirects use a HTTP 301 status code.  The Controller class  includes three new methods for performing these permanent redirects: RedirectPermanent()RedirectToRoutePermanent(), andRedirectToActionPermanent(). All  of these methods will return an instance of the HttpRedirectResult object with the Permanent property set to true.
    3. HttpStatusCodeResult – used for setting an explicit response status code and its associated description.

MVC 3 AJAX and JavaScript Enhancements

MVC 3 ships with built-in JSON binding support which enables action methods to receive JSON-encoded data and then model-bind it to action method parameters.
For example a jQuery client-side JavaScript could define a “save” event handler which will be invoked when the save button is clicked on the client. The code in the event handler then constructs a client-side JavaScript “product” object with 3 fields with their values retrieved from HTML input elements. Finally, it uses jQuery’s .ajax() method to POST a JSON based request which contains the product to a /theStore/UpdateProduct URL on the server:

$('#save').click(function () {
var product = {
ProdName: $('#Name').val()
Price: $('#Price').val(),
}

$.ajax({
url: '/theStore/UpdateProduct',
type: "POST";
data: JSON.stringify(widget),
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function () {
$('#message').html('Saved').fadeIn(),
},
error: function () {
$('#message').html('Error').fadeIn(),
}
});
return false;
});

MVC will allow you to implement the /theStore/UpdateProduct URL on the server by using an action method as below. The UpdateProduct() action method will accept a strongly-typed Product object for a parameter. MVC 3 can now automatically bind an incoming JSON post value to the .NET Product type on the server without having to write any custom binding.

[HttpPost]
public ActionResult UpdateProduct(Product product) {
// save logic here
return null
}

MVC 3 Model Validation Enhancements

MVC 3 builds on the MVC 2 model validation improvements by adding   support for several of the new validation features within the System.ComponentModel.DataAnnotations namespace in .NET 4.0:
Continues…

Using Custom Data Types in ASP.NET Profiles

ASP.NET Profile can also accept custom data types and they are relatively easy to implement

The first step is to create a class which wraps the information you require. In the class, you may use public member variables, but the preferred choice is full-fledged property procedures which will allow the  class to support data binding or other complex logic.

For example, the below code shows an  Address class which should be placed in the App_Code directory of the web app:

[Serializable()]
public class Address
{
private string fullName;
public string FullName {...}
private string streetNumber;
public string StreetNumber {...}
private string cityCode;
public string CityCode {...}
private string zip;
public string Zip  {...}
private string stateCode;
public string StateCode {...}
private string countryCode;
public string CountryCode {...}
public Address(string nameCode, string streetCode, string cityCode,
string zip, string stateCode, string countryCode)
{
NameCode = nameCode;
StreetCode = streeCodet;
CityCode = cityCode;
Zip= zip;
StateCode = stateCode;
CountryCode = countrCode;
}
public Address()
{ }
}

Next add a property in the web.config to declare it:

<properties>
<add name="CutomerAddress" type="Address" />
</properties>

Now you can use the Profile in your code.


To assign values to the Profile:

Profile.CutomerAddress.Zip = txtZip.Text;

To access the Profile data:

string zipStr;
zipStr = Profile.CutomerAddress.Zip;

Automatic Saves

The ASP.NET Profiles feature cannot detect changes in complex data types (ie anything other than strings, Boolean values, simple numeric types etc). So the Profile includes complex data types, ASP.NET will save the complete profile info at the end of every request which accesses the Profile. The behavior has an obvious performance cost. Therefore to optimize Profile performance when using  complex types, you can  set the profile property to be read-only (in the event it never changes).

Alternatively, you can disable the autosave behavior by using  the automaticSaveEnabled attribute in the <profile> element and setting this to  false. If you do this you will need to use Profile.Save() to explicitly save changes to the Profile. This approach is normally preferred as the parts of code which modify a Profile are easy to spot and you can easily add  Profile.Save() to the end of the code block:

Profile.CustomerAddress = new Address(txtName1.Text, txtStreet1.Text, txtCity1.Text,

txtZip1.Text, txtState1.Text, txtCountry1.Text);

Profile.Save();

Optimizing ASP.NET Profiles Performance

ASP.NET Profiles were introduced to assist developers in persisting user information. Previous methods of persistence all had limitations in how they stored user data, Session state would only be held in memory and lost once the user’s session ended, a query-string would only be useful for that particular page and had to be recreated on each new page, cookies are only available on a single user machine. Profiles addressed all these difficulties by providing a simple persistent store which plugs into ASP.NET Membership. Profiles are ideal for storing user info such as preferences for a web app, besides being convenient they are very simple to use – just create them in the web.config file and access them anywhere in the application using Profile.ProfileName.

But with the convenience and power of Profiles comes a price – performance. Profiles are stored in a database, and therefore if used without caution can have a major performance cost.

To understand how best to use Profiles, first we will look at how they work under the hood. Profiles plug into the life-cycle of the page at two points:

  • The first time the Profile object is accessed in your code ASP.NET retrieves all the  profile data for the current user from the   database. If   the profile data is used more  than once in the same request ASP.NET reads it only once and then reuses it.
  • If profile data is updated, that update is deferred until the page has finished processing( ie after the PreRender, PreRenderComplete, and Unload events have completed). At that point the profile data  is written   to the database, thus  multiple changes are updated in batch.

Thus, using Profiles can result in an extra two database hits  per  request (if Profile data is read and then updated) or one extra database hit  (for simply reading the Profile data). It should be noted that Profiles do not have a caching mechanism so so every request for Profile data or update of Profile data  requires a database connection.

Thus from a performance viewpoint, Profiles are best when:

  • There are a relatively small number of pages which access the Profile data.
  • Profiles only store small amounts of data (since accessing Profiles always results in the retrieval of all the Profile data for that user it can be quite result in large payloads).

Therefore to optimize performance when using ASP.NET Profiles it is best to combine  

Profiles with other methods of  state management. For example,   a web app could first check if there was a cookie stored on the user’s machine for the user’s date format preference and if not available  this data could be retrieved from the Profile (which would then then add a cookie) this will save a database round trip each time to check the preferences (session state could also be used for this).

Getting Started Using ASP.NET Profiles

ASP.NET Profiles are a very useful tool for  persisting user data. Most other methods of state management do not easily persist the data across user visits, but Profiles plug seamlessly into the ASP.NET Membership database to provide a convenient persistent store.

Defining Profile Properties

The first step to using Profiles is to defining them in the web.config file.  This is done by adding the <profile> section to the web.config file and the adding each property using a  <add> element nested inside the <properties> element:

<configuration>
<system.web>
...
<profile>
<properties>
<add name="Language"/>
<add name="NumberFormat"/>
<add name="JoinedDate"/>
</properties>
</profile>
</system.web>
...
</configuration>

In addition to name the <add> element accepts several attributes which should be used. By default the format of the Profile is set to String but can be set to any datatype, for example the above JoinedDate profile should have a attribute of type added with the associated data type:

<add name="JoinedDate" type="System.DateTime" />

defaultValue is another useful attribute which sets the default of the Profile. For example, this could be used the set the initial language a user’s preferences is set to:

<add name="Language" defaultValue="en" />

There are several additional attributes, namely:

  • serializeAs : The format to use for serializing this Profile (String, CML, Binary, or ProviderSpecific)
  • readOnly : This is a boolean which sets if the Profile can be updated.
  • allowAnonymous : A boolean which sets if the Profile can be used with anonymous profiles.
  • provider : The profile provider that is used to manage this property.

Access Profiles

Profile access is very simple. Just use Profile.ProfileName anywhere in an app to get the profile value for the user. For example:

String langStr = Profile.Language

Update Profiles

Updating ASP.NET  Profiles is also a simple procedure, just assign the value to the Profile and it will be stored:

Profile.Language  = langTxtBox.Text

Note that the Profile will not actually be written to the database (and therefore not stored) until the page life-cycle is complete. Therefore after updating a Profile, avoid accessing it unless the page has finished processing (as only the old value will be stored).

Be aware that Profiles do not come without issues. There is a performance cost to using Profiles inappropriately see ASP.NET Profile Performance for more details.

Run External Applications From ASP.NET

To run an external application from your ASP.NET web application use the System.Diagnostics.Process.Start method for calling the  application.

The first step for  running an external application from an ASP.NET app is to create a ProcessStartInfo object, and then pass  the name of the application to run as well as  command-line parameters it might require. In the sample code below, we use the Java runtime to execute a Java program named ExternalJavaProgram, in this case the name of the application to run is java and the only command-line parameter required is  the name of the Java program - ExternalJavaProgram.

In the page’s code-behind class :

  1. Import the System.Diagnostics namespace.
  2. Create a ProcessStartInfo object and then pass the name of the external app to run as well as all required command-line parameters.
  3. Set the working directory to the external app’s location.
  4. Start the external app process by calling the Start method of the Process class  and pass the ProcessStartInfo object.


Code Example

private void Page_Load(object sender, System.EventArgs e)

  {

  Process proc = null;
  ProcessStartInfo si = null;

  // create a new start info object with the program to execute
 // and the required command line parameters
  si = new ProcessStartInfo("java",  "ExternalJavaProgram");

  // set the working directory to the location of the the legacy program
  si.WorkingDirectory = Server.MapPath(".");

  // start a new process using the start info object
  proc = Process.Start(si);

  // wait for the process to complete before continuing
  proc.WaitForExit( );

  }  // Page_Load

Working with ADO.NET Transactions

A transaction is a group of operations combined into a logical unit of work that is either guaranteed to be executed as a whole or rolled back. Transactions help the database in satisfying all the ACID (Atomic, Consistent, Isolated, and Durable). Transaction processing is an indispensible part of ADO.NET. It guarantees that a block of statements will either be executed in its entirety or rolled back,( i.e., none of the statements will be executed). Transaction processing has improved a lot in ADO.NET 2.0. This article discusses how we can work with transactions in both ADO.NET 1.1 and 2.0.

Implementing Transactions in ADO.NET

Note that in ADO.NET, the transactions are started by calling the BeginTransaction method of the connection class. This method returns an object of type SqlTransaction.
Other ADO.NET connection classes like OleDbConnection, OracleConnection also have similar methods. Once you are done executing the necessary statements within the transaction unit/block, make a call to the Commit method of the given SqlTransaction object, or you can roll back the transaction using the Rollback method, depending on your requirements (if any error occurs when the transaction unit/block was executed).
To work with transactions in ADO.NET, you require an open connection instance and a transaction instance. Then you need to invoke the necessary methods as stated later in this article.  Transactions are supported in ADO.NET by the SqlTransaction class that belongs to the System.Data.SqlClient namespace.

The two main properties of this class are as follows:

  • Connection: This indicates the SqlConnection instance that the transaction instance is associated with
  • IsolationLevel: This specifies the IsolationLevel of the transaction

The following are the methods of this class that are noteworthy:
Commit()   This method is called to commit the transaction
Rollback()  This method can be invoked to roll back a transaction. Note that a transaction can only be rolled back after it has been committed.
Save()       This method creates a save point in the transaction. This save point can be used to rollback a portion of the transaction at a later point in time. The following are the steps to implement transaction processing in ADO.NET.

  • Connect to the database
  • Create a SqlCommand instance with the necessary parameters
  • Open the database connection using the connection instance
  • Call the BeginTransaction method of the Connection object to mark the beginning of the transaction
  • Execute the sql statements using the command instance
  • Call the Commit method of the Transaction object to complete the
    transaction, or the Rollback method to cancel or abort the transaction
  • Close the connection to the database

The following code snippet shows how we can implement transaction processing using ADO.NET in our applications.

string connectionString = ...; //Some connection string
SqlConnection sqlConnection = new SqlConnection(connectionString);
sqlConnection.Open();

SqlTransaction sqlTransaction = sqlConnection.BeginTransaction();

SqlCommand sqlCommand = new SqlCommand();
sqlCommand.Transaction = sqlTransaction;

try
{
sqlCommand.CommandText = "Insert into Employee (EmpCode, EmpName) VALUES (1, 'Joydip')";
sqlCommand.ExecuteNonQuery();
sqlCommand.CommandText = "Insert into Dept (DeptCode, DeptName, EmpCode) VALUES (9, 'Software', 1)";
sqlCommand.ExecuteNonQuery();
sqlTransaction.Commit();
//Usual code
}

catch(Exception e)
{
sqlTransaction.Rollback();
//Usual code
}

finally
{
sqlConnection.Close();
}

The next piece of code illustrates how we can use the “using” statement for the above code. According to MSDN, the “using” statement, “defines a scope, outside of which an object or objects will be disposed.
Continues…