Friday, May 14, 2010

Patterns & Practices

In last two posts, I have been talking about the layered architecture in ASP.NET applications. If you missed them, you might want to read the first part and the second part, just to get a better insight on the topic I am discussing today.

Dividing an application into multiple layers helps to:
  • Keep different concerns of components separate so that there is clear distinction between different parts e.g. keeping presentation and business logic separate rather than making a mess by mixing them up
  • Easy maintenance of the application
  • Enhanced clarity of the application making it easy to understand
  • Keep individual components cohesive and often efficient
  • Loose coupling between layers
  • Increase reusability, of course
Layered approach towards developing applications is not a new concept. Even with the age-old client-server architecture, we followed the two layer approach. Layered approach is often very synonymously used with tiered approach. Microsoft has a different take on this, and what they say is a layered approach is related to maintaining layers in application during the architecture stage while a tiered implementation is the layered approach of implementing the solution. I agree, but will not be discussing it much. We are talking about architecture here than implementation. But if you are interested, you can read Microsoft’s take on deployment patterns.

In the layered approach, what we have noticed so far is that an application is best divided into the presentation layer, the business logic layer and the data access layer. Each layer can further be divided making it an n-tier application, but mostly the basic architecture revolves around the above mentioned three layers. With large applications, you may also choose to create a separate class library for each of these layers. However, with service oriented architecture, things have changed a bit. The service oriented architecture has become very popular today since for applications that need to interact with external system, services are the best solution. If you are not familiar with service oriented architecture, you can refer this article on Windows Communication Foundation to get an insight. Using services, applications can expose themselves to third party applications or the external world the way they want to. This helps in sharing of data, enabling remote access in secure way and makes the application very extensible.

If services are to be used, additional responsibilities can be added by using an extra layer called “service interface” to the required layers. The architecture will somewhat look like below, but again variations are the way.


The diagram is self-explanatory, and I will keep the detailed discussion on this for later. Today, I only want to bring to your attention that there is no standard way about how to design an application, Depending on the requirement of the application, the development environment, the target environment and many other factors, you have multiple choices with architecture. Different solutions are best solutions for different situations. However, over a period of time as the software industry has evolved, there have been some standard solutions that are known to be best suited for certain scenarios. Such solutions or ideas that have evolved with time and provide you simple solutions to complex situations are known as “design patterns”. Microsoft themselves have a series of articles written on suggested patterns and practices they want to share with us when it comes to developing applications in Microsoft technologies. They focus much on the three tiered approach and service interface if required, something that I have briefly talked about above.

In articles to follow, I will talk about more on this topic, mainly on things like Model-View-Controller architecture that Microsoft is so crazy about. This is not a new concept; in fact if you read Erich Gamma and the team’s book Design Patterns: Elements of Reusable Object-Oriented Software, the first chapter talks about MVC and SmallTalk. But MVC has stood the test of time that made Microsoft go gaga over it today. MVC is based on the Observer Pattern, one of the most popular design patterns, that also forms the base of Java. There are concepts like Page Controller and Broker, and then there are concepts like Service Interface and Service Pattern. I will be adding more discussions on architecture in this blog. Stay around!

Wednesday, May 5, 2010

Introducing Business Objects

This is the second part of discussion on layered architecture in ASP.NET applications. I will extend the same examples, so you should read the first part here, or at least glance through the examples.

Let us extend the data access layer class to include a method to update the database.

ProductDataAccessLayer.cs

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public class ProductDataAccessLayer
{
    string connectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString();

    public DataSet GetProducts()
    {
        SqlConnection conn = new SqlConnection(connectionString);
        DataSet dsProducts = new DataSet();
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT ProductID,ProductName,UnitPrice FROM Products", conn);
        adapter.Fill(dsProducts);
        return dsProducts;
    }

    public int UpdateProduct(int productId, string productName, string quantityPerUnit, double unitPrice, int unitsInStock, int unitsOnOrder, int reorderLevel)
    {
        SqlConnection conn = new SqlConnection(connectionString);
        conn.Open();
        string sql = "UPDATE Products SET ProductName = @productName, QuantityPerUnit = @quantityPerUnit, UnitPrice = @unitPrice, UnitsInStock = @unitsInStock, UnitsOnOrder = @unitsOnOrder, ReorderLevel = @reorderLevel WHERE ProductId = @productId;";
        SqlCommand command = new SqlCommand(sql, conn);
        command.Parameters.AddWithValue("@productName", productName);
        command.Parameters.AddWithValue("@quantityPerUnit", quantityPerUnit);
        command.Parameters.AddWithValue("@unitPrice", unitPrice);
        command.Parameters.AddWithValue("@unitsInStock", unitsInStock);
        command.Parameters.AddWithValue("@unitsOnOrder", unitsOnOrder);
        command.Parameters.AddWithValue("@reorderLevel", reorderLevel);
        command.Parameters.AddWithValue("@productId", productId);
        return command.ExecuteNonQuery();
    }
}
Now in the business logic layer, we will add a wrapper to the update method. You might think that why we do not call the data access layer directly that calling in through the business logic layer. I agree, but when you have to add some business logic to the update method in future, then you will end up messing your code. Little extra effort makes your code more organized and keeps you away from problems in future.

ProductBusinessLogicLayer.cs
using System;
using System.Data;
using System.Data.SqlClient;

public class ProductBusinessLogicLayer
{
    public DataSet GetProducts()
    {
        DataSet dsUpdatedProducts = new DataSet();
        ProductDataAccessLayer productDAL = new ProductDataAccessLayer();
        dsUpdatedProducts = productDAL.GetProducts();
        foreach(DataRow row in dsUpdatedProducts.Tables[0].Rows)
        {
            double unitPrice = Double.Parse(row["UnitPrice"].ToString());
            row["UnitPrice"] = unitPrice + unitPrice * (12.5/100);
        }        return dsUpdatedProducts;
    }

    public int UpdateProduct(int productId, string productName, string quantityPerUnit, double unitPrice, int unitsInStock, int unitsOnOrder, int reorderLevel)
    {
        ProductDataAccessLayer productDAL = new ProductDataAccessLayer();
        return productDAL.UpdateProduct(productId, productName, quantityPerUnit, unitPrice, unitsInStock, unitsOnOrder, reorderLevel);
    }
}
Now, what I have done in the presentation layer is that a few textboxes and an update button is added just above the grid. To make it easy for you, I have assigned some default values to the textboxes as well. When the update button is clicked, the values from all required textboxes is passed to the business logic layer update method and that in turns fires the update method in the data access layer where the actual update takes place.

Products.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        .style1
        {
            width: 125px;
        }
        .style2
        {
            width: 144px;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table>           
 <tr>
  <th>Column</th>
                <th>Value</th>
        </tr>           
 <tr>
                <td>Id</td>
                <td>
                    <asp:TextBox ID="ProductId" runat="server">10</asp:TextBox>
                </td>
        </tr>
        <tr>
                <td>Name</td>
                <td>
                    <asp:TextBox ID="ProductName" runat="server">Ikura</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td>Quantity</td>
                <td>
                    <asp:TextBox ID="QuantityPerUnit" runat="server">12 - 200 ml jars</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td>Unit Price</td>
                <td>
                    <asp:TextBox ID="UnitPrice" runat="server">31.20</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td>Units in stock</td>
                <td>
                    <asp:TextBox ID="UnitsInStock" runat="server">31</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td>Units on order</td>
                <td>
                    <asp:TextBox ID="UnitsOnOrder" runat="server">0</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td>Reorder level</td>
                <td>
                    <asp:TextBox ID="ReorderLevel" runat="server">0</asp:TextBox>
                </td>
        </tr>
 <tr>
                <td></td>
                <td>
                    <asp:Button ID="btnUpdate" runat="server" Text="Update" onclick="btnUpdate_Click" />
                </td>
        </tr>
        </table>
        <asp:GridView ID="GridView1" runat="server"></asp:GridView>
    </div>
    </form>
</body>
</html>
Products.aspx.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Products : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductBusinessLogicLayer productBAL = new ProductBusinessLogicLayer();
        GridView1.DataSource = productBAL.GetProducts();
        GridView1.DataBind();
    }
    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        ProductBusinessLogicLayer productBAL = new ProductBusinessLogicLayer();
        int res = productBAL.UpdateProduct(Int32.Parse(ProductId.Text), ProductName.Text, QuantityPerUnit.Text, Double.Parse(UnitPrice.Text), Int32.Parse(UnitsInStock.Text), Int32.Parse(UnitsOnOrder.Text), Int32.Parse(ReorderLevel.Text));
    }
}
Similarly, we can extend the class to include actions like inserting into or deleting from database.

Seems like we have a perfect architecture in hand, but I feel something is still wrong. You feel the same? Good! Let’s see where the problem is. We have an update method added that updates the fields in the Products table. I have intentionally left many columns of the table and not included them in the example to keep it simple. If the table is really huge with a number of columns, how lengthy our update methods’ parameter list is going to be. Also maintaining the fields by passing them as parameters is a complicated solution. We need a handy solution to maintain these fields.

To find a solution, let us think different. Here, a Product is an entity or say an object for us. All the fields we are talking about are its attributes. What if we create a class called Product that has the fields as its properties! We will be dealing with Product objects instead of a long list of parameters. Sounds better? Lets proceed with creating a Product class.

Product.cs
public class Product
{
    int productId = 0;
    string productName = string.Empty;
    string quantityPerUnit = string.Empty;
    double unitPrice = 0;
    int unitsInStock = 0;
    int unitsOnOrder = 0;
    int reorderLevel = 0;
 
    public int ProductId
    {
        get { return productId; }
        set { productId = value; }
    }
 
    public string ProductName
    {
        get { return productName; }
        set { productName = value; }
    }
 
    public string QuantityPerUnit
    {
        get { return quantityPerUnit; }
        set { quantityPerUnit = value; }
    }
 
    public double UnitPrice
    {
       get { return unitPrice; }
       set { unitPrice = value; }
    }
 
    public int UnitsInStock
    {
       get { return unitsInStock; }
       set { unitsInStock = value; }
    }
 
    public int UnitsOnOrder
    {
       get { return unitsOnOrder; }
       set { unitsOnOrder = value; }
    }
 
    public int ReorderLevel
    {
       get { return reorderLevel; }
       set { reorderLevel = value; }
    }
}
We will change our data access layer so that its update method accepts a Product object than a long list of parameters.

ProductDataAccessLayer.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
public class ProductDataAccessLayer
{
    string connectionString = ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString();
 
 public DataSet GetProducts()
    {
       SqlConnection conn = new SqlConnection(connectionString);
       DataSet dsProducts = new DataSet();
       SqlDataAdapter adapter = new SqlDataAdapter("SELECT ProductID,ProductName,UnitPrice FROM Products", conn);
       adapter.Fill(dsProducts);
       return dsProducts;
   }
 
    public int UpdateProduct(Product product)
    {
       SqlConnection conn = new SqlConnection(connectionString);
       conn.Open();
       string sql = "UPDATE Products SET ProductName = @productName, QuantityPerUnit = @quantityPerUnit, UnitPrice = @unitPrice, UnitsInStock = @unitsInStock, UnitsOnOrder = @unitsOnOrder, ReorderLevel = @reorderLevel WHERE ProductId = @productId;";
       SqlCommand command = new SqlCommand(sql, conn);
       command.Parameters.AddWithValue("@productName", product.ProductName);
       command.Parameters.AddWithValue("@quantityPerUnit", product.QuantityPerUnit);
       command.Parameters.AddWithValue("@unitPrice", product.UnitPrice);
       command.Parameters.AddWithValue("@unitsInStock", product.UnitsInStock);
       command.Parameters.AddWithValue("@unitsOnOrder", product.UnitsOnOrder);
       command.Parameters.AddWithValue("@reorderLevel", product.ReorderLevel);
       command.Parameters.AddWithValue("@productId", product.ProductId);
       return command.ExecuteNonQuery();
    }
}
Update the business logic layer also accordingly.

ProductBusinessLogicLayer.cs
using System;
using System.Data;
using System.Data.SqlClient;
public class ProductBusinessLogicLayer
{
    public DataSet GetProducts()
    {
        DataSet dsUpdatedProducts = new DataSet();
        ProductDataAccessLayer productDAL = new ProductDataAccessLayer();
        dsUpdatedProducts = productDAL.GetProducts();
  
       foreach(DataRow row in dsUpdatedProducts.Tables[0].Rows)
       {
          double unitPrice = Double.Parse(row["UnitPrice"].ToString());
          row["UnitPrice"] = unitPrice + unitPrice * (12.5/100);
       }
  
       return dsUpdatedProducts;
    }
 
    public int UpdateProduct(Product product)
    {
       ProductDataAccessLayer productDAL = new ProductDataAccessLayer();
       return productDAL.UpdateProduct(product);
    }
}
And our presentation layer will be where we will create the Product object from the values filled in the form. While the aspx file remains the same, the code-behind will now be:

Products.aspx.cs
using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class Products : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        ProductBusinessLogicLayer productBAL = new ProductBusinessLogicLayer();
        GridView1.DataSource = productBAL.GetProducts();
        GridView1.DataBind();
    }
 
    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        Product product = new Product();
        product.ProductId = Int32.Parse(ProductId.Text);
        product.ProductName = ProductName.Text;
        product.QuantityPerUnit = QuantityPerUnit.Text;
        product.UnitPrice = Double.Parse(UnitPrice.Text);
        product.UnitsInStock = Int32.Parse(UnitsInStock.Text);
        product.UnitsOnOrder = Int32.Parse(UnitsOnOrder.Text);
        product.ReorderLevel = Int32.Parse(ReorderLevel.Text);
        ProductBusinessLogicLayer productBAL = new ProductBusinessLogicLayer();
        int res = productBAL.UpdateProduct(product);
    }
}
All we did was to add a new Business Object layer (the Product class), and we introduced a better way to deal with the Product as an object. I know you are excited and you are eagerly waiting for me to say that we have just seen 4-tier architecture with Business Objects coming into picture. We will call it Business Object Layer or better, Business Entities Layer.


The sad news is that not everyone agrees that the above follows 4-tier architecture. Often, the Business Entity Layer is considered as a sub layer of the Business Logic Layer, and hence still considered as 3-tier architecture. It won’t be a surprise if you find many applications that implement the Business Object Layer and the Business Logic Layer in the same class, while there are a number of examples where even the Business Logic Layer is spread over multiple layers of its own. Even with Data Access Layer, it is often a preferred choice to create a separate layer of Helper classes. When it comes to designing a solution, there is never a universal thumb rule!

Now that we have a very clear idea about tiered architecture including 4-tier architecture (let’s say), our next discussion will focus on layered architecture in more depth as we look at different ways of designing applications on Microsoft.NET framework.

By the way, the examples I included in this post and the earlier one, and the ones I will include further, are all meant to be simple and hence can be written in better and organized way. I just focused on defining clear layers and explaining the objectives to you. Writing neat code, managing object references and error handling are a few things that are clearly omitted. I leave them to you when you develop the real applications.

Monday, May 3, 2010

Layered architecture for ASP.NET applications

This is the first post in a series of discussion on using layered architecture in ASP.NET applications. I will start with the basics and try to elaborate concepts gradually so as to help developers who have just begun to understand the concept of layers in an application.

For quite a while, a tiered approach towards developing an application has been in the buzz. We hear people talking 2-tier, 3-tier, n-tier applications! What is a “tier” here? It means a layer. When a civil engineer is designing a building, he works on a blueprint of the building. In the blueprint, there is a clearly defined sketch of each part, viz. the base, the pillars, the first floor, the subsequent floors, electrical plans may be!  How the base is to be built and pillars placed so that the floors will be strong is very important consideration. The same applies to developing software applications. We are talking specifically about web applications here to be developed in ASP.NET and we will choose C# as the language for our examples.

A web application should be developed in layers. Each layer should be defined precisely to meet a distinct purpose. The interactions between each layer should be well thought of. In short,
  • Each layer should be designed for a specific purpose and a distinct objective.
  • Each layer should have a unique responsibility and hence not mess up with any other layer’s duties.
  • The interaction between the layers should be well defined. This is very important, failing which layered architecture will not only be an overhead but become clumsy and a havoc to maintain.
2-tier architecture

Consider a very simple ASP.NET application where there are aspx pages directly interacting with the database. For example, the application has an aspx page with a grid whose datasource is set to a dataset and the code for connecting the dataset and populating it is written in the code behind file. The aspx file and its code-behind file contains the content to be displayed on the browser (the web controls), business logic and code for interaction with database.

Here is an example:

Products.aspx
<html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
            <div>
                <asp:GridView ID="GridView1" runat="server">
                </asp:GridView>
            </div>
        </form>
    </body>
</html>
Products.aspx.cs
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
public partial class Products : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ToString());
        DataSet dsProducts = new DataSet();
        SqlDataAdapter adapter = new SqlDataAdapter("SELECT ProductID,ProductName,UnitPrice FROM Products", conn);
        adapter.Fill(dsProducts);
        GridView1.DataSource = dsProducts;
        GridView1.DataBind();
    }
}
To explain the code in short, all we are doing is to execute a SELECT query against Products table in the Northwind database, and then bind a grid to the dataset. The page when loaded will display all products in the grid.

In this architecture, often to make code less cumbersome and keep things short and clean, you may also opt to write stored procedures that performs multiple tasks at the database end. Now, these stored procedures may also very often include some business logic code. For example, you may maintain transactions within a stored procedure and hence end up implementing a part of application’s business logic in the stored procedure or using constraints and triggers in the database. Here what we have is:

  • Application layer – the aspx page and its code- behind forms the application layer that delivers the presentation of data to the user and also contains the business logic.
  • Data access layer – the underlying database acts as the data access layer here. This means the entire database engine, including the database objects (e.g. tables, views) and the manipulating code (e.g. stored procedures).
It means you are using 2-tier architecture. Many of us think that because .aspx files have a separate code behind files, that counts as two different layers and hence ASP.NET applications are by default 3-tiered. Sorry, that’s not the way we can look at it. There is absolutely no difference in writing all the code behind part in the aspx files itself or separating it into a separate code behind file. Code-behind files only provide you a neater way to maintain your code and make sense out of it. Code-behind files do not contribute as a separate layer, unless you want to believe it that way.

3-tier architecture

In the above architecture, we found that although there was an attempt to make a distinction between the two layers, we could often end up having a part of our business logic implemented at the data access layer. To solve this problem, we can introduce a separate layer in between called “Business Logic Layer” where we will implement all business logic of the application and that will interact with the data access layer. This way, the data access layer keeps itself limited to handling database interaction and providing data to or updating data from the business logic layer.

We will see what I mean by a separate business logic layer. But before that, let us restructure the example code of 2-tier architecture from above. What we will do is put the database interaction code into a separate class. This class will be the actual “data access layer” for us and will be mainly and only used for database interaction purpose. The new class will be as:

ProductDataAccessLayer.cs

Our code-behind file will now look like:

Products.aspx.cs

Looks better? Remember, we still have only two layers: the ProductDataAccessLayer is just a cleanly maintained data access layer. The aspx file with its code behind forms the presentation layer.

Now lets say the unit price that is displayed for each product is without the VAT at present. The actual unit price should be inclusive of 12.5% VAT for each item. It would be a bad idea to place the logic into the data access layer since this class is meant to perform actions like select, insert, update and delete etc. And even if we put it there hardcoded, what if the government decides to change VAT to 13% percent tomorrow? What is the best solution then? Remember, we know that touching the data access layer for business logic changes is a bad idea, and we also know that the aspx and code-behind is best for presentation purpose.

Let us add a new layer, the business logic layer. So, here is the example code updated

This is our old data access layer:

ProductDataAccessLayer.cs

I will add a new class "ProductBusinessLogicLayer".

ProductBusinessLogicLayer.cs

And our aspx code behind will change to:

Products.aspx.cs

Notice that the newly introduced class “ProductBusinessLogicLayer” acts as an interface between the presentation and data access layer and has the business logic code for VAT calculation implemented. Any changes in business logic tomorrow will affect only this class. Yu do not have to be concerned about the data layer or the presentation layer while making changes to the business logic.

What we get is a clear separation of business logic and data interaction. Your application just became easily maintainable and extendable!

What we have here is:
  • Application layer – the aspx page and its code- behind forms the application layer that delivers the presentation of data to the user.
  • Business logic layer – the business logic part is moved into an intermediate layer.
  • Data access layer – the data access layer with the underlying database engine forms the data access layer.
So you have 3-tier architecture.

I will talk about implementing 3-tier architecture in detail in the next post, and also look at various methods to implement a 3-tier or n-tier architecture, with examples. Sometime later, we will also talk about the MVC architecture.

Sunday, April 25, 2010

Windows Communication Foundation

If you are familiar with web services, this should be easy. But let us start with the basics.

We know about object oriented programming concept. In object oriented programming concept, we create an instance of a component in form of an object and work with it. As we see, objects are tightly coupled to the component and hence controls the component's lifetime.

In contrary, service oriented applications are loosely coupled. In service oriented architecture, there exists a host (call it a server) that hosts a service and there exist clients to consume the service. The host publishes a contract, which is a template that defines methods and objects that can be called/used by clients. All communications between the host and clients take place in form of messages. SOAP is one of the protocols that defines the format of the message, and it uses XML.

Service oriented architecture is mostly implemented in distributed applications. In .NET, distributed architecture can be implemented using one of the four options: web services, .NET remoting, message queuing or COM+ services. Windows Communication Foundation is a framework that allows you to use all these features at one place and most importantly, it allows you to use these features interchangeably. For example, if you have implemented .NET remoting (that uses TCP as protocol since it is in LAN environment) and want to launch it as a web service (which is accessed using HTTP protocol), all you need to do is just alter the configuration. No rework required. That is why it is often referred to as Unified Programming Model.

When we talk of WCF, we should be familiar with basic terminologies like services, service hosts, communication protocols, messaging, end points etc. I will put a few of them in short here, and leave the rest to you and google.

A host that launches a service exposes one or more endpoints for the service. Think of an endpoint as a hook. To consume a service, a client should have hook to the endpoint of the service and then it can use the service. Similarly, to be able to receive a response from the server, the client should expose an endpoint that the host will hook to. In simple terms, two endpoints always exists when a client and a host are communicating. That makes a service as a collection of endpoints. A client has to connect to the correct endpoint to consume the service it wants to.

HTTP and TCP, as discussed above, are just two examples of communication protocols. And we already know what a contract and a message is. Remember, message is an XML string here. It should have already struck you that the objects and methods are serialized into XML and passed as a message, and de-serialization occurs to get them back in form. Sounds logical?

You will find more terms on WCF and short description here.

This tutorial will tell you how to go about creating a service using WCF. It is very simple to follow. At some points, it is bit confusing since the text formatting is not done properly...but you can easily figure it out.

I will talk about WCF more in posts to come.

Tuesday, April 6, 2010

State management in ASP.NET

A web application runs over HTTP, a stateless communication mode. That means, each request for a page is a new request for the server, no matter if the same page is being requested again. When a page makes a round trip to the server (for example when you fill up a form and submit it), you can naturally expect the data you filled in to be lost when the page loads back...unless you somehow manage to save the data somewhere and fill them back in the controls when the page loads back. This is called "maintaining the state".

In traditional environments like classic ASP, it was a painful responsibility of the developer to maintain state using Request collection. ASP.NET realized the pain and has come up with multiple ways to maintain state for an ASP.NET page.

State management can be done either client side or server side. In this article and the following ones, we will look at possible state management techniques and also talk about when best to use what.

In case of ASP.NET, the features available for preserving data across page or application are as follows:
  • View state
  • Control state
  • Hidden fields
  • Cookies
  • Query strings
  • Session state
  • Application state
  • Profile properties
  • Database
We will also evaluate each of these features in terms of implementation overhead, resource requirements, client side support (for client side methods), performance and security.


Managing state client side

Client side state management mostly involves storing state either in the page's HTML, the client browser's session or some physical location on the client machine.


View state

View state is the default mechanism provided by ASP.NET to maintain the value of controls in a page across a round trip i.e. postback. When a page is being rendered on the server, the values in all controls that have view state enabled (by default all controls have view state enabled) are serialized into XML and then encoded using base64 encoding. This value is then stored in a hidden field named "__VIEWSTATE". You can view this field using the "view source" option in the browser. A typical example would be:

<input type="hidden" name="__VIEWSTATE" value="dDwtNTI0ODU5MDE1Ozs+ZBCF2ryjMpeVgUrY2eTj79HNl4Q=" />

So, view state is typically an encoded string containing IDs and values of controls in a page so that when the page is posted back, the server automatically puts the values back into the controls before sending the page back to client (rather than developers required to do it themselves in traditional environment).

Besides storing control's values, the view state collection (which is nothing but a dictionary object) can be used to store other values as well, as shown below:

ViewState("MyPostBackCount") = 2;

A view state can store data of multiple data types, viz. strings, integers, boolean values, arrays, array lists and hash tables.

However, in case of large amount of data being loaded in controls e.g. in case of grids, view state can result into a huge string and can have negative impact on performance by slowing down page load on the browser. Huge view state also means huge amount of data flowing between the client and the server. ASP.NET provides an option to disable view state at the page level and also at control level. When it is a choice between comfort and performance, disabling view state can be an option; however the developer will then have to implement an alternative for maintaining the state. Also, in case of data bound grids, disabling view state can create problems in default paging and sorting behaviour.

Implementation - View state is maintained by default and hence needs no specific programming to be done.
Resource requirements - Since the view state is maintained in a hidden field, it does not consume server resources. There is an overhead involved in encryption and decryption but it is so insignificant that you don't need to bother about it.
Client side support - Hidden fields are allowed by most browsers and do not need specific permission from users. However, for devices that have constraints loading huge data (e.g. mobile devices) or if there are firewall restrictions on the limit of data allowed in hidden fields, large amount of data in view state can create problems.
Performance - As discussed, large amount of view state data can be a serious bottleneck. If view state can result into performance issues, it is wise to disable view state and implement an alternative.
Security - View state is an encrypted string. It provided optimum security, but still there is a risk of view state data being tampered because it is after all hidden in the form itself and can be viewed on browser end.


Control state

Like view state, control state is also an encrypted string generated at server and stored in a hidden field to persist data across postbacks. But control state only contains critical data about controls for the controls to function properly and unlike view state, control state cannot be disabled. If you were wondering, how could controls function properly if view state was disabled...control state is your answer, but this is very simply put. The truth gets worse if we dive deep...glad, we won't ;-).

Controls state is a separate object than view state and is initialized by the PageStatePersister class while view state is an instance of the StateBag class.

Implementation - Control state is custom state persistence mechanism and hence requires some programming to be done. We will look at control state with example in a later article.
Resource requirements - Like view state, the control state is also maintained in a hidden field and does not consume server resources.
Client side support - It's just a hidden field!
Performance - Unlike view state, data in custom state never gets large enough to pose a worry.
Security - No worries...custom state is an encrypted string and it does not store user provided data.


Hidden fields

A hidden field is a control that renders a hidden input control that can store some value and can be used for persisting data across postback. Unlike view state and control state that is handled by ASP.NET, hidden strings are to be added by the developer wherever required. Hidden fields are visible on client and not encrypted either. Hence they should never be used for storing sensitive data.

An .aspx page can contain,

<asp:HiddenField ID="MyPostBackCount" runat="server" />

and this can be accessed in codebehind as:

HiddenField1.Value = "2";

Implementation - Hidden fields are easy to implement as shown in example above.
Resource requirements - The hidden field control generates an equivalent input control that is hidden and not displayed on browser. No server resource required.
Client side support - This is also just a hidden field!
Performance - Issues related to amount of data stored in the hidden field can pose similar problems as with the view state. Hidden fields are never advised for large amount of data.
Security - As mentioned, hidden fields are visible on client using the "view source" option in browser and the stored values are not encrypted either. They can be easily tampered with and are strictly not suggested for storing sensitive data.


Cookies

Cookies are well known in state management world. They are small bunch of data stored on client side either in browser memory or text files. Cookies are not ASP.NET specific but since they are also state management measures, let us evaluate cookies as an option. Cookies can be temporary or permanent (persistent). Also, cookies can have multiple values in a single cookie. We will discuss cookies in a separate discussion.

In ASP.NET, cookies are accessed through the Response object.

Response.Cookies["UserName"].Value = "guest";
Response.Cookies["UserName"].Expires = DateTime.Now.AddDays(1);

Implementation - Cookies are simple collections and easy to use with less programming required.
Resource requirements - Cookies are client side storage option, hence they either consume space in the client browser's memory or physical disk. They do not pose any demand on server resources.
Client side support - Cookies can be disabled by client and hence has restricted applicability. Also, cookies have limited allowed size on client, often up to 4 KB.
Performance - Cookies have size limits and hence do not contribute to performance bottlenecks
Security - Cookies can be easily tampered with and is a known threat area. It is strongly advised to use encryption and decryption with cookies and not to store sensitive data either.


Query strings

Query string is another option and a traditional one for persisting data. It is data appended to an URL in a pre-defined form that can be read as parameters. ASP.NET exposes the parameter collection through Request object.

Implementation - Query strings are well known and simple to implement.
Resource requirements - Since parameters are appended to URL, it has nothing to do with serer or client resources. However, the larger the data, the more the packets transferred.
Client side support - Query strings are well supported but fall within the size limit of about 2083 characters for URLs.
Performance - Query strings do not contribute to performance bottlenecks for obvious reasons.
Security - Query strings are the easiest to play around with and tamper. It is visible with the URL and should only be used for limited non-sensitive data.


Maintaining state server side

Maintaining state server side often means storing data in server memory or some data store.


Session state

Session state is a server side data storage mechanism that stores data in key-value pair format in server memory and is maintained by server. This state is maintained as long as the browser session is active, i.e. data persists in memory across multiple page requests as long as the session is active. Each user connected to the server has its own session id and its own session state. Session state should be used only for data that need to persist across multiple page requests or throughout the session.

Session["UserName"] = "guest";

Implementation - Session state is easy to use as shown in example above.
Resource requirements - Session state resides in memory on server. If large amount of data or objects are stored in session state, it will end up consuming a lot of memory on server and badly degrade server performance.
Performance - Large amount of data in server state can be a performance issue since the server will have to resort to virtual memory paging in absence of the memory consumed by server state.
Security - Session state is maintained in memory on server. Security is not an issue.


Application state

Application state is a global storage mechanism that stores data in key-value pair format and is maintained by server, like session state. However, this state is maintained at application level, i.e. data persists across multiple page requests and even multiple sessions. It should be obvious that application state is a very precious store and has the longest life span among the methods we know. Use it wisely!

Application["ClickCounter"] = clickCounter + 1;

Implementation - Application state is easy to use as shown in example above.
Resource requirements - Like session state, application state consumes server memory. Worse, it persists across multiple sessions as well. If large amount of data is stored in application state, it will end up consuming a lot of memory on server and hence degrade server performance.
Performance - Large amount of data in application state can choke up server memory and degrade server performance.
Security - Application state is maintained in memory on server. Security is not an issue.


Profile properties

Profile properties use external storage medium (data store) to persist data rather than in memory. This feature uses ASP.NET profile to maintain user specific data that requires to be stored and used across multiple sessions of an individual user. We will talk about profile properties in a separate article in detail.

Implementation - Profile properties are easy to use, given that the developer can configure the profile provider.
Resource requirements - Since data is stored in data store rather than memory, it does not consume any resource in server memory at least. And since the storage is done in an external medium, there is no limit on data storage.
Performance - Since data is stored in data store than memory, storage and retrieval of data is relatively slower than other server side methods. But this should not be a concern.
Security - Well, it is not as secure as other server side methods, but it does not pose huge threat either.


Database

Often, database is also used along with cookies or session states to store data in order to persist it. In simple terms, if you think that you need to store some data in your database related to user's authentication or preferences or whatever, you can store it in database as well.

Implementation - Maintaining state in database is as simple as performing normal database operations. Of course, it is not automatic and requires programming.
Resource requirements - Database gives you an unlimited storage and there is no server memory in concern here.
Performance - Obvious as it is, database operations would consume some time and hence this method is not as quick as the rest. I would say, performance here is specific to implementation.
Security - Security relies on what measures are taken to secure database. Adequate authentication and authorization can introduce required security factor.


We are now familiar with the possible methods of maintaining state in ASP.NET. In the next article, we will talk about which method is best in what circumstances.

Monday, April 5, 2010

ASP.NET Page Life Cycle

By understanding the details of how an ASP.NET page runs on the server before the rendered HTML is sent to the browser, one can realize how many significant stages a page goes through and how much control it releases to the developer. While the page runs through its life cycle, while the methods of the page’s base class can be overridden, a number of events are also raised that can be handled and exploited.

I wanted to write in detail about the life cycle, but time constraints...you know. But, everything about the life cycle can be found here, put in simple terms and details.

Recently a diagram was also added in this article, that makes it really clear. Here is a direct link to the image if needed. This sketch seems to be influenced by a diagram by some "Andrianarivony Leon" that has been on the web for a while. But the diagram in the link above is a better version, I wont post the original here. Have a look...the diagram is a must have for a .NET developer for his/her dashboard.

Update on June 12, 2010:
I found a video on the ASP.NET site that might be helpful to understand the life cycle. You can access the video here.

Sunday, September 6, 2009

Good programming practices

While conventions and standards introduce uniformity to code and make it easily understandable, developers are strictly advised to follow some good coding practices listed over a period of time. If you browse the Internet, you will find a vast number of resources available on good programming practices. Some of them have stood with time and are always relevant, some are not really significant and some do not go along with our conventions. However, there are a few points that are relevant to our organization and to the general C# developers; and applicable to the code we write regularly.

Today, we will have a look at such “good programming practices”:

Variables
  • Declare one variable per line. Do not list multiple variables in the same line although they are the same type. By declaring one variable per line, you can easily add comment for each variable, which you should (must for member variables).
  • Declare and initialize variables in the same order they are used. This applies to both member and local variables.
  • Always initialize variables, if possible at the point of declaration. There should a valid reason if a variable is not initialized.
  • Declare and initialize variables close to where they are used. This is very important because only by identifying their scope of usage, one can decide which variables should stay local and which variables are required as member variables. The idea is to declare and use variables as locally as possible. By declaring variable close to their usage, however, does not mean that variables should be declared anywhere. In methods, the variable declarations should be on the top.
  • Do not make member variables public or protected. Keep them private and expose them through public/protected properties.
  • In a method, use “this.” for member variables. This way, member variables can be easily distinguished from local ones.

Constants
  • Constants should be used instead of hardcoded numbers in code. Declare and initialize constants at the top and use them throughout the code.
  • Remember, the rule for variables about one declaration per line applies to constants as well.

Session variables
  • Use session (or even application) variables sparingly. Session variables should be used only when some data has to be stored throughout the session of the user. Never use them for temporary storage purposes.
  • Do not store large objects in session variables. 
  • Do not use session variables throughout the code. Use session variables only within the classes and expose methods to access the value stored in the session variables.

Control flow (branches and loops)
  • All flow control primitives (if, else, while, do, for, switch) should be followed by a block (a pair of curly braces) even if it is empty. Remember to put a curly brace on a new line always.
  • All switch statements should have a default label as the last case label. 
  • Convert strings to lowercase or uppercase before comparing. It is important to bring string on both sides of a condition to one case before performing comparisons.
  • Do not make explicit comparisons to boolean values: true or false. 
  • Use ternary operator for simple if-else statements. 
  • Use String.Empty instead of “” while checking if a string is empty.
  • Do not compare floating points using == or != operators. 
  • Use StringBuilder class instead of String when you have to manipulate string objects in a loop.
  • When casting types, always check if there is a possibility of loss of precision.

Methods
  • Name a method so that it tells what it does. It saves you from writing lot of comments. For example, instead of naming a method that saves a phone number as SaveData (string phoneNumber), use SavePhoneNumber (string phoneNumber).
  • Do not create two methods with names that differ only by case (although their purpose or scope is different). This applies to all objects including namespaces, classed, variables etc.
  • A method should not have only one return statement. Avoid multiple or conditional return statements.
  • Never return null for an empty collection.
  • All variants of an overloaded method should be used for the same purpose and have the same behavior.

Events and delegates
  • Always raise events through a protected virtual method.
  • Always use the sender/arguments signature for event handlers.
  • Do not programmatically call an event handler. Instead, code the action in a separate method and call the method.

Some general tips
  • Avoid fully qualified type names. Use the using statement instead.
  • Do not hardcode strings. Use resource files.
  • Always use external style sheet to control the look and feel of the pages (even for images).
  • Keep name of querystring arguments short (2-3 characters). For e.g., use “fn=test.txt&v=1.1” instead of “filename=test.txt&fileversion=1.1”.
  • If you have opened database connections, sockets, file stream etc, always close them in the finally block.
  • Always set a reference field to null after usage to tell the Garbage Collector that the object is no longer needed. 
  • Avoid implementing a destructor. If a destructor is needed, also use GC.SupressFinalize.

Code structure: Size and layout

How many times have you come across a source file that is so huge in length that to trace a part of code in it can get you sick, not only because there is too much of code to dig into but also because the scroller is too small to grab? ;-)

It is important to know when it is enough!

  • If a method exceeds beyond 30-40 lines, you should consider splitting into further segments. Rarely business logic has to be written above 40 lines without an option to divide it into segments. As long as dividing the code into methods makes sense, it does not matter. Compartmentalized code only makes it readable and easier to understand.
  • Watch the number of arguments that a methods has. If the list of arguments exceeds 5-6, think again. May be, you can use a structure as class for it. You don’t want to have a terrible argument list as the COM methods in Office Automation, do you?
  • 300-400 lines of code in a file already make the file huge. If a source file exceeds this limit, you must be missing something. Check if a new class can be introduced or your code is not optimized enough.

Layout of code

Just like a blueprint for a building or an editor’s draft of a book, the code layout is very important. When you are using Word or any similar editor, have you not noticed how many option are available to format the text (with options for headings, subheadings, emphasis and much more; we call them markup)? What is the advantage of a good layout or formatting of code? You make the code readable and help others to easily maintain it when needed.

How easy it is to understand a statement like this:

querystring="name="+userName+"&userid="+userID+"&email="+email;

For developers who are familiar with Visual Basic (that uses & operator to concatenate) and C# (that uses + operator to concatenate), this statement must hold you for a while before you figure out which operator is used to concatenate the string.

Now what about this:

querystring = "name=" + userName + "&userid=" + userID + "&email=" + email;

It is the same statement, but the concatenation operator (+ in this case) is so distinct compared to earlier example.

Let us talk about the standards for code layout:

  • Always indent code. Use tabs to indent code, not spaces.
    There is enough argument on the web on whether to use spaces or tabs to indent. Using tabs can be troublesome if different developers use different length of spacing for tabs, while using spaces has always been a tedious job. However, when all developers are using the same editor (everyone in our organization uses Visual Studio 2005 or 2008 for development in C# with default setting of tab at 4 characters), using tabs is the best way to indent.

  • Never leave more than one blank line between statements.
    Blank lines should be used to separate units as methods, and also separate different segments of code for clarity. However, it is never necessary to use more than one blank line anywhere in code. Avoid using more than one blank line, but do not forget to use blank lines completely. You must use a single blank line always to separate methods and logical segments of code.

  • Know when to use spaces and when not.
    • Always use a space between an operator and an operand. However, in case of unary, increment or decrement operator, do not use a space between the operator and the operand.
    • For flow control primitives (if, else, while, do, for, switch), always put a space between the keyword and the starting bracket. But do not use a space between bracket and text inside a bracket.
    • Always follow a comma or a semicolon with a space.
    • Do not use a space between the methods name and bracket in method while defining or calling a method.
    • Do not use a space within square brackets for subscripts.

 Bad:
if (x==y)
for(i=0;i<10;i++)
BuildSampleString ( myChar, 0, 1 );
x = dataArray[ index ];
Good:
if (x == y)
for (i = 0; i < 10; i++)
BuildSampleString(myChar, 0, 1);
x = dataArray[index];

  • Always put curly braces on a separate line.
    For example:

    class MyClass {
       …
    }

    or

    if (x == y) {
       …
    }

    should be written as:

    class MyClass
    {
       …
    }

    and

    if (x == y)
    {
       …
    }

It takes time for developers to get into this habit if they already are not following this. But with IDEs like Visual Studio helping developers with auto indentation and spacing, it is not very difficult for developers now. So, no excuses! ;-)

Code structure

The standardization of the structure of code is important to allow developers locate objects quickly, trace bugs more effectively and not the least, make the code readable and explanatory. Let us talk about the structure of code today.

I checked multiple sources from Microsoft and also scanned through the code gallery at MSDN to study how people organized their code. I did not find uniformity of order in MSDN samples and other code from the very developers from Microsoft. Some code in gallery even declare member variables at the end of the class while some code use underscore for member variables, which we have strictly avoided. At some point, I thought, we have no rigid reference to stick to, but we will create our standards as close as possible. In fact, I had already speculated that as long as the order of code was followed throughout the application, it hardly mattered which order was put into practice. But I was curiously looking for a scientific order that had explanation. For example, to have events and public methods above private methods makes sense because it helps quicker maintenance, most of the times. There is no scientific backup to support this, but if you work on maintenance of a source for a while, you should feel the same.

First and foremost, "one file, one class" policy is a must. There should not be more than one class in one file. Multiple classes not only tend to make the file size big but also complicate tracing and maintenance. Hence, there should always be one class in a file and the file name according to the class. It is suggested than even if there are objects like enumerators of a namespace level scope, use a separate class for them.

In a source file (C#), the following order should be followed for its contents:

// Copyright information
// File details
// Change log (version history)

Using statements (imports) 

Namespace
{
     Class
     {
          #region Enumerators (of class level scope) 

          #region Static Methods 

          #region Constants 

          #region Member Variables 

          #region Properties 

          #region Constructors and Destructors 

          #region Events 

          #region Public Methods 

          #region Protected Methods 

          #region Private Methods
     }
}

Whenever there is question about ordering based on access specifiers, the ordering should always be done in order of: public, protected and private. Hence, if required to classify events based on access specifiers, public events should come first followed by protected and then private ones.

I am already drowsing now, its past midnight. I will limit today’s discussion on code structure to the order of code. Tomorrow, we will discuss sizing code and more. Goodnight!

Coding convention – Database and files

In the last blog, we stopped at the naming convention for C# code. However, it is not only C# source that forms an application. We need to standardize naming convention for database objects, files and folders etc. We will focus on them in this blog.

Naming convention for database

The table below is a chart with the standards to be followed for database objects. As in the previous blog for source code, we have three columns here. The first column has the database unit, the second has the details about which case to be used (and special conditions, if any) and last column has an example to illustrate.

Object
      Convention
Database
  • Use Pascal case
  • No abbreviation
  • Format:
    {CompanyName}[_Scope][_Project]

    Example(s):
    MyCompany_Application_Main
Table
  • Use Pascal case
  • Use plural name (for junction tables, concatenate name in one to many relationship order)
  • No abbreviation or underscore
  • No prefix or suffix (avoid Hungarian notation)

    Example(s):
    Users
    UserRoles

Column
  • Use Pascal case
  • No abbreviation or underscore
  • Primary key field should be named as singular form of table name + "ID" (e.g. UserID for table Users)
  • Boolean fields should have prefix as "Is", "Has" etc
  • DateTime fields should have "Date" or "Time" or both as suffix

    Example(s):
    UserID
    FirstName
    IsActive
    JoiningDate

Index
  • Use Pascal case
  • Format:
    {TableName}_{ColumnName}_{U/N}{C/N}
    (U/N for unique or not and C/N for clustered or not)
  • No prefix or suffix (avoid Hungarian notation)

    Example(s):
    TaskDetails_IsCurrent_NN

Constraint
  • Use Pascal case
  • Format:
    {Type}{TableName}_{ColumnName}
    (Type: Pk for Primary key, Fk for Foreign key, Ck for Check and Un for Unique)

    Example(s):
    PkUsers_UserId

View
  • Use Camel case
  • No abbreviation or underscore
  • Prefix "vw"

    Example(s):
    vwUserRoles

Stored Procedure
  • Use Camel case
  • No abbreviation or underscore
  • Prefix "sp"

    Example(s):
    spDeactivateOldEmployees

Trigger
  • Use Pascal  case
  • Format:
    {TableName}[_Description]_{Type}
    (Type: U for Update, D for Delete and I for Insert)

    Example(s):
    Users_U
    Salary_CalculateTotal_U

Variable
  • Use Pascal case
  • No abbreviation or underscore
  • For boolean type, use prefix as "Is", "Has" etc.

    Example(s):
    @MaximumAge


Let us look at naming files and folders now.

Naming convention for files and folders

Files and folders should be named uniformly throughout the application. This is very important because name can identify the type, purpose, scope and validity of a file in an application. The table below presents the standards.

Type
      Convention
Folder
  • Use Pascal case
  • No abbreviation (except for system standards)
  • Use underscore sparingly (avoid as much as possible)
  • No prefix or suffix (avoid Hungarian notation)

    Example(s):
    Content
    App_Code

Code (Source) File
  • Use Pascal case
  • Use the same name as the main class
  • No abbreviation or underscore
  • No prefix or suffix (avoid Hungarian notation)

    Example(s):
    Users.aspx.cs
    CalculateInvoice.cs

Backup File
  • Format:
    {Date}_{Initials}_{FileName}
    (Date in format yyyyMMdd and Initials of the file creator)

    Example(s):
    20090905_NY_CalculateInvoice.cs

Log File
  • Format:
    {Date[Time]}{Description}.log.{Extension}
    (Date[Time] can be in format: yyyy[MM[dd[HH[mm[ss]]]]])

    Example(s):
    200905MonthlyImport.log.xls
    20090905142530System.log.txt

DLL Assembly
  • Use Pascal case
  • Use the same name as the containing namespace

    Example(s):
    SecurityTools.dll


We will also discuss naming convention for style tags and classes soon. However, a quick mention about HTML code is relevant here. In HTML, use XML standards to ensure compatibility with newer versions of HTML and XHTML. Primarily, use Pascal case for all elements and Camel case for their attributes, unless required otherwise by the environment.