Menus

Tuesday, February 19, 2013

Advanced ASPX GridView Pagination and Data Entities

Introduction

Ra-GridView can be seen as an ASP.NET based software system skeleton that uses ASPX GridView control and advanced pagination techniques for displaying the list of data entities loaded from the database, and the ModalPopupExtender control from the ASP.NET AJAX Control Toolkit for creating new entities or for editing entities from the grid. This skeleton can be easily modified and extended into a real software system.
It is also an example of using separated application layers (Data Access Layer and User Interface Layer) for exceptions management and application logging (by using the Windows Event Log).
The provided software code is well commented and cleaned, so there should be no problems in reading and understanding the software. This application skeleton can be easily modified and extended into a real software system by following the steps provided in the section “How to Extend this Application Skeleton”.

Figure 1: Ra-GridView web application

Background

Developing real software systems that are related with management of a large amount of data stored into databases involves finding optimized solutions.
These optimizations become more critical in the case of Web Applications that have their databases stored on the servers and with several users that use Web Browsers to access the data via internet.
In general, from the user interface point of view, in a Web Application, there should be a number of web pages that present data to the user in a list of entities (by using controls like Repeater, DataList, ListView, or GridView) and provide controls for filtering, sorting, searching, and manipulation of the data (Create, Edit, Delete operations). In a real situation, we are talking about a large amount of data, so an optimized pagination becomes critical.
For a beginner who tries to use the ASP.NET GridView control, everything seems to be perfect because the GridView provides pagination and sorting functionalities; but in a conventional way of paging and sorting, we get a complete set of data instead of getting only the portion of data that is required to display on the current/requested page. So, by default, in using the GridView control for manipulating a large amount of data (a few hundreds of rows), the performance is very low, and if the number of rows increases to several hundreds or several thousands, the web page becomes useless.
The conclusion is that in real applications which work with large amounts of data, the implementation of an optimized pagination associated with the ASP.NET GridView controls is a must.

Data Access Layer

The Data Access Layer contains the SQL Stored Procedures, the Data Entities model, and the Data Entities classes generated based on the existing tables and Stored Procedures from the database.
For this example, I used only two tables: Contacts and Groups. The main table is Contacts, and it has a FK (Foreign Key) on ContactID that defines the relationship between these two tables: each Contact belongs to a Group.

Figure 2: Ra-GridView database tables
I focused only in getting the data from the Contact table and its associated Group table, and I defined three Stored Procedures for this.
  • GetContactByID – Get only one record from the Contacts table by its ID.
  • CREATE PROCEDURE [dbo].[GetContactByID]
    @id int
    AS
    BEGIN
        Select * from Contacts where  ID=@id
    END
  • GetAllGroups – Get all records from the Groups table.
  • CREATE PROCEDURE [dbo].[GetAllGroups]
    AS
    BEGIN
        Select * from Groups ORDER BY [Name]
    END
  • GetContactsByFilterPaginated – This is the main SP used to get only one page of records from the Contacts table by using the given filtering, sorting, and paging parameters.
  • As you can see, in the code below, the SP has two pagination parameters that define the current index of the first record from the page and the page size (how many records in the page). It has a sorting parameter that could contain a sorting expression similar to SQL SORT BY. In our example, there is only one filter parameter groupID, but there can be more parameters that define the filter (searching) criteria. The last SP parameter is used to return the total count for all records from the database that match the given filter.
    Note that in my case, to get the data from the Contacts table, I have a filter based on a value from the Groups table, so in the construction of the main Select, I put a JOIN between the two tables and I named the Contacts table as c, and the Groups table as g. These two names (c and g) will also be used in the ASPX and C# code when we define the sorting expressions!
    CREATE PROCEDURE [dbo].[GetContactsByFilterPaginated]
        --- The Pagination params
        @pageIndex int,
        @pageSize int,
        --- The Sorting param
        @sortBy varchar(200),
        --- The Filter params (could be more than one!)
        @groupID int,
        --- The Output param that will store the total count
        @count int OUTPUT
    AS
    BEGIN
        DECLARE @sqlSELECT NVARCHAR(MAX), @sqlFilter NVARCHAR(MAX)
        DECLARE @sqlCount NVARCHAR(MAX), @outputParam NVARCHAR(200)
        ---
        --- Construct the main SELECT and the common SQL Filter
        ---
        SET @sqlSELECT = 'WITH Entries AS ( SELECT ROW_NUMBER() _
            OVER (ORDER BY ' + @sortBy + ') AS RowNumber, c.*, _
            g.Name AS GName FROM Contacts AS c LEFT JOIN Groups +
            AS g ON g.ID = c.GroupID'
        SET @sqlFilter = ' WHERE (c.Deleted is null OR c.Deleted = 0) '
        ---
        --- Build WHERE clause by using the Filter params
        ---
        if(@groupID > 0)
            SET @sqlFilter = @sqlFilter + ' AND c.GroupID = ' + _
            CONVERT(NVARCHAR,@groupID)
        --
        -- Construct SELECT Count
        --
        SET @sqlCount = 'SELECT @totalCount=Count(*) From Contacts c' + @sqlFilter
        SET @outputParam = '@totalCount INT OUTPUT';
        --
        -- Finalize SQLs
        --
        SET @sqlSELECT = @sqlSELECT + @sqlFilter
        SET @sqlSELECT = @sqlSELECT + ' ) SELECT * FROM Entries _
            WHERE RowNumber BETWEEN ' + CONVERT(NVARCHAR,@pageIndex) + _
            ' AND ' + CONVERT(NVARCHAR,@pageIndex) + ' - 1 + ' + _
            CONVERT(NVARCHAR,@pageSize)
        SET @sqlSELECT = @sqlSELECT + '; ' + @sqlCount;
        --
        -- Exec SLQs ==> the total count
        --
        EXECUTE sp_executesql @sqlSELECT, _
            @outputParam, @totalCount = @count OUTPUT;
    END
Going back to the C# code in the RaGridView solution, there is a “Class Library” project named Ra.GridView.Data. In this project, I added a new entity of type "ADO.NET Data Model", and then I made an association with the database tables and Stored Procedures described above. This Class Library contains all data access code and entity classes. The most important of them are these:
  • RaGridViewEntities – The main data context used to access data by using entity classes. It will also give us access to the static methods associated with the Stored Procedures.
  • Contact – The entity class associated with the Contacts table.
  • Group – The entity class associated with the Group table.

User Interface

The User Interface Layer code is separated from the Data Access Layer, and it contains all the ASP.NET pages and classes organized into a class hierarchy. I also use MasterPage, AJAX, CSS styles, and JavaScript.

Figure 3: Ra-GridView user interface classes

BasePage

It is the base class for all the pages used in the web application, and it provides two properties: DataContext used to access the Data Access Layer, and the abstract property ErrorMessage.
This class is responsible to create and to dispose of the RaGriddViewEntities object used by the DataContext property. This simplifies the work with data entities in the child pages.

BaseEntityPage

It is the base class for all the pages used to create and/or to edit an entity. It overrides the ErrorMessage property to show the error message on the parent page header, and other common members to all children classes could be added here.

BaseListPage

It is the base class for all pages used to display into a list and to manage (search, sort, create, edit, delete) data entities.
The children of this class must be created as pages that use the site master page (SiteMaster). The class has a protected member named _masterPage that provides access to the site master page. It also overrides the ErrorMessage property to show the error message into the master page header, and other common members to all children classes could be added here.

ContactPage

It is the web page used to edit and/or to create a Contact entity into a popup window.
In ContactPage.aspx, there are two buttons: OK and Cancel, and their events are linked (directly and indirectly) with JavaScript actions.
<asp:button id="_saveButton" text="Save" runat="server" width="80px"
    validationgroup="ContactValidationGroup"
    onclick="_saveButton_Click" />
<asp:button id="_cancelButton" runat="server" autopostback="False"
    width="80px" text="Cancel"
    onclientclick='OnCancel();' />
The used JavaScript code from the ASPX file is:
function OnOK() {
    window.parent.document.getElementById('_okPopupButton').click();
}
 
function OnCancel() {
    window.parent.document.getElementById('_cancelPopupButton').click();
}
In the C# code, the event used to save the user input into the database when the user clicks OK directly invokes the OnOk() JavaScript method. In the code example below, you can also see the exceptions management, and the usage of the util class RaGridViewEventLog for logging the possible cached exceptions into the application log.
protected void _saveButton_Click(object sender, EventArgs e)
{
    bool isNewEntity = false;
    Contact contact = CreateOrLoadEntity(this.ContactID);
    //
    if (contact != null)
    {
        try
        {
            //
            // Save the user inputs into the entity.
            //
            contact.FirstName = _firstNameTextBox.Text;
            contact.LastName = _lastNameTextBox.Text;
            //
            string temp = _phoneTextBox.Text.Trim();
            contact.Phone = (temp.Length < 1 ? null : temp);
            //
            temp = _emailTextBox.Text.Trim();
            contact.Email = (temp.Length < 1 ? null : temp);
            //
            temp = _noteTextBox.Text.Trim();
            contact.Note = (temp.Length < 1 ? null : temp);
            //
            int groupID = 0;
            int.TryParse(_groupDropDownList.SelectedItem.Value, out groupID);
            contact.GroupID = groupID;
            //
            // Save the changes into the database.
            //
            if (contact.ID == 0)
            {
                DataContext.Contacts.AddObject(contact);
                isNewEntity = true;
            }
            //
            DataContext.SaveChanges();
        }
        catch (Exception ex)
        {
            RaGridViewEventLog.LogException(ex);
            this.ErrorMessage = 
              "Error in saving the entity into the database!";
        }
    }
    //
    if (isNewEntity)
    {
        //
        // To communicate the ID of the new created contact to the parent,
        // we must cache its value!
        //
        Session["NewContactID"] = contact.ID;
    }
    //
    // Run "OnOk()" script. Note that this will close the popup window
    // by invoking _okPopupButton.click() event on the parent page!
    //
    ClientScript.RegisterStartupScript(this.GetType(), 
                 "contactSave", "OnOK();", true);
}

ContactListPageData

It is the class used to implement optimized pagination and sorting in the ContactListPage page. It provides the following static public members that control the pagination and the way the data is loaded from the database:
  • Page - Used to set the associated page (in our case, ContacListPage).
  • ContactID – If a positive value is set, only one contact will be searched from the database; if a negative value is set, no data will be loaded from the database (empty results); if 0 is set, the filter will be used to search data for the current pagination index.
  • AfterDelete - Notifies that a delete operation took place so the count for all results that match the current searching criteria must be decreased by one.
  • GetCount() – Returns the count for all rows from the database that match the current searching criteria. This method is automatically called from the object data source associated with the ContactListPage GridView object.
  • NewFilter – Notifies that a new filter has been set and/or the user wants to reload the data from the database and repaginate the results. If this flag is not set to true, only the data from the current page is reloaded.
  • GetDataByFilter(int startIndex, intPageSize, string sortBy) - This method is automatically called from the object data source associated with the ContactListPage GridView object. It is the main method used for implementing pagination, and it applies the searching criteria and current filter, then loads from the database only the results for the current page index. Note that for each filter criterion, there exists a public property in the associated page class.
  • ListToDataTable(List<contact>entityList) – A utility method invoked from GetDataByFilter() to convert a list of entities into a DataTable used for the GridView data binding.

ContactListPage

It is the main web page used to show into a list and to manage (search, sort, create, edit, delete) Contact entities. It also uses the GridView control and ContactListPageData to display, paginate, search, and sort the list of Contact objects. It uses the ModalPopupExtender control from the ASP.NET AJAX Toolkit to display ContactPage pages in popup windows for editing or creating Contact entities.

Figure 4: ContactListPage and its ModalPopupExtender in action
Below is the ASPX code used to define the data source used for optimized grid pagination and make the link with the ContactListPageData class and its pagination methods GetDataByFilter() and GetCount().
<asp:objectdatasource id="_gridObjectDataSource" 
    runat="server" enablepaging="true"
    typename="Ra.GridView.Web.Data.ContactListPageData" 
    selectmethod="GetDataByFilter"
    startrowindexparametername="startIndex"
    maximumrowsparametername="pageSize" 
    sortparametername="sortBy"
    selectcountmethod="GetCount"/>
In the GridView control, you have to specify the using of the data source defined above (in the DataSourceID property), the pagination page size (in the PageSize property), and also set the AllowSorting and AllowPaging properties to true, as in the ASPX code below:
<asp:GridView ID="_contactsGridView" runat="server" 
  AutoGenerateColumns="False" DataKeyNames="ID"
  EmptyDataText="There are no data for the current filter!" 
  AllowSorting="True" OnRowCommand="_contactsGridView_RowCommand" 
  ViewStateMode="Enabled" CellPadding="4" GridLines="Both" 
  Width="100%" ForeColor="#333333" 
  AllowPaging="true" PageSize="<%$appSettings:GridPageSize %>"
  PagerSettings-Mode="NumericFirstLast" 
  DataSourceID="_gridObjectDataSource" 
  OnRowDataBound="_contactsGridView_RowDataBound">
To specify the sorting options, in the definition of the grid columns, you have to specify the sort expressions like in the examples below by using the aliases c and g for the table names Contacts and Groups.
<asp:boundfield datafield="Person" headertext="Name" 
                sortexpression="c.FirstName, c.LastName" />
<asp:boundfield datafield="Group" headertext="Group" sortexpression="g.Name" />
<asp:boundfield datafield="Phone" headertext="Phone" sortexpression="c.Phone" />
The ASPX code used for editing a Contact entity by using ModalPopupExtender and IFrame is shown below:
<asp:Button ID="_editPopupButton" runat="server" 
        Text="Edit Contact" Style="display: none" />
<asp:ModalPopupExtender ID="_modalPopupExtender" runat="server"
    BackgroundCssClass="modalPopupBackground"
    TargetControlID="_editPopupButton" 
    PopupControlID="_editWindowDiv"
    OkControlID="_okPopupButton"
    OnOkScript="EditOkScript();" 
    CancelControlID="_cancelPopupButton"
    OnCancelScript="EditCancelScript();"
    BehaviorID="EditModalPopup">
</asp:ModalPopupExtender>
<div class="_popupButtons" style="display: none">
    <input id="_okPopupButton" value="OK" type="button" />
    <input id="_cancelPopupButton" 
            value="Cancel" type="button" />
    <asp:Button ID="_refreshGridPopupButton" runat="server"
        Text="Refresh" ClientIDMode="Static"
        OnClick="_refreshGridPopupButton_Click" />
</div>
<div id="_editWindowDiv" style="display: none;">
    <iframe id="_editIframe" class="contactPageFrame" 
            frameborder="0"> </iframe>
</div>
The JavaScript used for editing a contact entity by using ModalPopupExtender and IFrame:
function ShowEntityEditor(entityID) {
    var frame = $get('_editIframe');
    frame.src = "ContactPage.aspx?ID=" + entityID;
    $find('EditModalPopup').show();
    return false;
}
 
function EditOkScript() {
    var button = $get('_refreshGridPopupButton');
    button.click();
}
 
function EditCancelScript() {
    var frame = $get('_editIframe');
    frame.src = "ContactPage.aspx";
    return false;
}

Before Running This Code

Note that all needed tools for database and source code are given as links in the References section, and they can be downloaded and used (for testing) by you without licensing problems, because they are express versions or open sources.
Before running this code, you should do these steps:
  1. Create a new entry in EventLog by running the CreateEventLogEntry application (from the RaGridView solution).
  2. Create a database named RaGridView in your SQL Server (or SQL Express), then restore the provided database RaGridVew.bak on to it.
  3. Optionally, you can create a login user for this database in your SQL Server (or SQL Express).
  4. Modify the connection string in the Web.config file of the RaGridView web application according to your settings from step 2 and step 3.

How to Extend This Application Skeleton

The provided code could be extended for a real application that works with several entities and associated database tables.
For doing this, I advise you that for each new entity, that has an associated main database table, follow these steps:
  1. In the database, create at least two Stored Procedures similar to GetContactByID and GetContactByFilterPaginated.
  2. In the Ra.GridView.Data project, update the data model with the new Stored Procedures and database tables. Note that entities classes (like Contact and Group) will automatically be generated based on the name of the database tables.
  3. For each new Stored Procedure, add an associated function import into the data model (by using the model browser view of the data model), similar to the image below:

  4. Figure 5: Add a function import for a Stored Procedure
  5. In the web application project, add a new class similar to ContactListPageData into the Data folder, but for your new entity.
  6. In the web application project, add a new item of type “Web Form” that extends BaseEntityPage similar to ContactPage.aspx, but for your new entity.
  7. In the web application project, add a new item of type “Web Form using Master Page” similar to ContactListPage.aspx that extends the class BaseListPage. Then modify the generated ASPX and C# code to include the JavaScript, the using GridView, the ModalPopupExtender, and the associated classes created in steps 4 and 5.
  8. Update the menu items from Site.Master to test your newly created pages.
 

How to write better C#/.NET code

Introduction

Developers always love to fight about coding standards. But it is very vital to follow coding standards to achieve consistency throughout the project or code. All should be of the same mind that conventions are very influential. I will show some good practices that i have learned during my professional years, those are lower level but very important for all levels. 

Quick Test   

Let us demonstrate a FizzBuzz example. The FizzBuzz test is to write a program that goes through the numbers 1 to 100. For every multiple of 3, the program should output "Fizz" and for every multiple of 5 it should output "Buzz". If both above conditions are met it should output "FizzBuzz". If none of the above conditions are met, it should just output the number.
Example 1:
public void Test()
       {
           for (int i = 1; i < 101; i++)
           {
               string Output = "";
               if (i % 3 == 0) { Output = "Fizz"; }
               if (i % 5 == 0) { Output += "Buzz"; }
               if (Output == "") { Output = i.ToString(); }
               Console.WriteLine(Output);
           }
       }
What do you think ? Do we need to make the code better?
Example 2:
public void Check()
       {
           for (int i = 1; i <= 100; i++)
           {
               string output = "";
               if (i % 3 == 0) { output = "Fizz"; }
               if (i % 5 == 0) { output += "Buzz"; }
               if (output == "") { output = i.ToString(); }
               Console.WriteLine(output);
           }
       } 
What do you think now ? Do we need to make the code even better?
Ok, let me help to make it better. Naming thing is one of the hardest job we have as a software developer. Because we spend a lot of time naming things, there are so many things to name properties, methods, classes, files, projects etc. We should spend some energies for naming things because names can be meanings. Adding meaning to code is readability all about.

     public void DoFizzBuzz()
       {
           for (int number = 1; number <= 100; number++)
           {
               var output = GetFizzBuzzOutput(number);
               Console.WriteLine(output);
           }
       }
 
     private static string GetFizzBuzzOutput(int number)
       {
           string output = string.Empty;
           if (number%3 == 0)
           {
               output = "Fizz";
           }
           if (number%5 == 0)
           {
               output += "Buzz";
           }
           if(string.IsNullOrEmpty(output))
           {
               output = number.ToString();
           }
           return output;
       }
What do you think now? Is this better than previous examples ? Is it more readable?

What is better Code?

Write code for People First, Computers Second. Readable code doesn't take any longer to write than confusing code does, at least not in the long run. It’s easier to be sure your code works, if you can easily read what you wrote. That should be a sufficient reason to write readable code. But code is also read during reviews. Code is read when you or someone else fixes an error. Code is read when the code is modified. Code is read when someone tries to use part of your code in a similar project or different project but similar feature or part of a feature. 
“ What if you just writing code for yourself ? Why should you make it readable ? ”
Ok, the major reason behind writing readable is , a week or two from now you’re going to be working on another project. What will happen when any other HUMAN needs to fix an error on that project? I can guarantee you that you will also lost within your own horror code.

From my point of view a better should carried out the following characteristics:
  • Code that is easy to write , modify and extend
  • Code that is clean and talks/convey meaning 
  • Code that has values and cares about quality 

So, write with the human reader in mind while satisfying the needs of the machine to the degree necessary.

How can you improve the Readability? 

First You have to read other peoples code and figure out what is good and what is bad within that code. What makes you easy to understand and what makes you feel more complicated. Then apply those things to your own code. Finally you need sometime, some experience and you need some practice to improve the readability of your code. It is very hard but obvious to implement standards in any software company, through methods like Trainings, Peer Code Reviews, Introducing automated code review tools etc. Most popular tools are as follows:

FxCop is a tool that performs static code analysis of .NET code. It provides hundreds of rules that perform various types of analysis.
StyleCop is an open source project that analyzes C# source code to enforce a set of style and consistency rules. It can be run from inside of Visual Studio or integrated into an MSBuild project. StyleCop has also been integrated into many third-party development tools.
JetBrains ReSharper is a renowned productivity tool that makes Microsoft Visual Studio a much better IDE. Thousands of .NET developers worldwide wonder how they’ve ever lived without ReSharper’s code inspections, automated code refactoring, blazing fast navigation, and coding assistance.

What are Conventions?

According to Wikipedia "Coding conventions are a set of guidelines for a specific programming language that recommend programming style, practices and methods for each aspect of a piece program written in this language. These conventions usually cover file organization, indentation, comments, declarations, statements, white space, naming conventions, programming practices, programming principles, programming rules of thumb, architectural best practices, etc. These are guidelines for software structural quality. Software programmers are highly recommended to follow these guidelines to help improve the readability of their source code and make software maintenance easier. Coding conventions are only applicable to the human maintainers and peer reviewers of a software project. Conventions may be formalized in a documented set of rules that an entire team or company follows, or may be as informal as the habitual coding practices of an individual. Coding conventions are not enforced by compilers. As a result, not following some or all of the rules has no impact on the executable programs created from the source code."
You should be able to tell the difference between a property, local variable, method name, class name etc. because they use different capitalization conventions. These type of conventions has values. You will be able to get lots of guidelines and conventions over internet. So find a convention or build your own and stick with it.
The source of the following (Design Guidelines for Developing Class Libraries) was developed by the Microsoft special interest group. I just made some addons.

Capitalization Conventions 

Below are some examples of our C# coding standards, naming conventions, and best practices. Use these according to your own needs.

Example of some Naming Conventions Guidelines

You will find enough resources over internet. I am just highlighting some of my favorites among them
C# Coding Conventions
C# Coding Guidelines
C# Coding Standards and Best Programming Practices
C# Coding Standards and Naming Conventions

I am providing some basic level examples below but as I already mentioned, find a good convention that fits for you and stick with it.
DO use PascalCasing for class names and method names.
public class Product
{
    public void GetActiveProducts()
    {
      //...
    }
    public void CalculateProductAdditinalCost()
    {
        //...
    }
}
DO use camelCasing for method arguments and local variables.
public class ProductCategory
{
  public void Save(ProductCategory productCategory)
   {
       // ...
   }
}  
DO NOT use Abbreviations
// Correct
ProductCategory productCategory;
 
// Avoid
ProductCategory prodCat;
DO NOT use Underscores in identifiers
// Correct
ProductCategory productCategory;
 
// Avoid
ProductCategory product_Category; 
DO prefix interfaces with the letter I.
public interface IAddress
{
 
}
DO declare all member variables at the top of a class, with static variables at the very top.
public class Product
{
    public static string BrandName;
 
    public string Name{get; set;}
    public DateTime DateAvailable {get; set;}
 
    public Product()
    {
        // ...
    }
}
DO use singular names for enums. Exception: bit field enums.
public enum Direction
{
    North,
    East,
    South,
    West
}
DO NOT suffix enum names with Enum
//Avoid
public enum DirectionEnum
{
    North,
    East,
    South,
    West
} 

Why we need Conventions?

Programmers on large projects sometimes go overboard with conventions. They establish so many standards and guidelines that remembering them becomes a full-time job. The computer doesn’t care whether your code is readable. It’s better at reading binary machine instructions than it is at reading high-level-language statements.
Conventions offer several specific benefits. They let you take more for granted. By making one global decision rather than many local ones, you can concentrate on the more important characteristics of the code.
  • They help you transfer knowledge across projects
  • They help you learn code more quickly on a new project.
  • They emphasize relationships among related items.
You should write readable code because it helps other people to read your code. Naming thing is one of the hardest job we have as a software developer. Because we spend a lot of time naming things, there are so many things to name properties, methods, classes, files, projects etc. We should spend some energies for naming things because names can be meanings. Adding meaning to code is readability all about.So it will help you better sleep at night.
 

Top Rules Developer Should Follow

Try to Avoid Comments

This is topic create some interesting conversations among all level of developers. But I almost never write comments on individual method or short class. Most comments i have ever seen is trying to describe the purpose/intentions. But comments are meaningless and C# compilers ignores comments. They have no impact what the code really does. They don't influence the generated code at all. Most of comments are meaningless noise. Let us check the comments below:

//ensure that we are not exporting
 //deleted products
  if(product.IsDeleted && !product.IsExported )
    {
       ExportProducts = false;
    }
If we name the method like CancelExportForDeletedProducts() instead of comments what will happen? So, method names are more affective than comments. Methods execute and they are real. But comment is good for some cases like, when visual studio will take comments for creating an API documentation and those comments are different, you can use "///" for those comments so that other developers can get intelligence of your API or Library. 
I am NOT telling you that avoid comment is a must for all the times. According to Kent's oral tradition point goes more to large-scale comments about how the whole thing works, not to individual method comments. If comment is trying to describe the purpose/intentions then it is wrong. If you look at thickly commented code, you will notice that most of those comments are there because the code is bad. Please read the following books for further detail:
  • "Professional Refactoring in C# & ASP.NET" by Danijel Arsenovski 
  • "Refactoring: Improving the Design of Existing Code" by Martin Fowler, Kent Beck, John Brant, William Opdyke, don Roberts

Avoid Unnecessary Regions in Class

Regions are a feature of VS that allow you to surround blocks of code. It could be a single or multiple methods. The region exists because it is easier to navigate around the large file. The regions are used to hide ugly code or class that have exploded in size . If a class does too many things it also violates the Single Responsibility Principle. So next time whenever you will think for adding a new region to your file take step back and ask that is it possible to separate your region into a separate class.

Keep Method Short

The more lines of code in a method the harder it is to understand. Everyone recommends 20-25 lines of code is ok. But some geeks prefer 1-10 lines for safety, this their personal preference. There is no hard and fast rule. Extract Method is one of the most common refactoring. If you consider a method that is too long or needs a comment to understand its purpose. You can apply Extract Method there with little effort. People always keep asking on the length for a method. But length is not the issue. When you are dealing with complex methods, keeping track of all local variables can be complicated and time-consuming. Where extracting a method can be a real time-saver. You can use the Visual Studio extract method which will track which variables are passed to a new method, which are returned by the method’s return value as output parameters.
Using ReSharper
Using Microsoft Visual Studio
 
For more detail on each step, please navigate the msdn link.
According to Refactoring: Improving the Design of Existing Code by Martin Fowler, Kent Beck (Contributor), John Brant (Contributor), William Opdyke, don Roberts 
"Extract Method is one of the most common refactoring I do. I look at a method that is too long or
look at code that needs a comment to understand its purpose. I then turn that fragment of code
into its own method.
I prefer short, well-named methods for several reasons. First, it increases the chances that other
methods can use a method when the method is finely grained. Second, it allows the higher-level
methods to read more like a series of comments. Overriding also is easier when the methods are
finely grained.
It does take a little getting used to if you are used to seeing larger methods. And small methods
really work only when you have good names, so you need to pay attention to naming. People
sometimes ask me what length I look for in a method. To me length is not the issue. The key is
the semantic distance between the method name and the method body. If extracting improves
clarity, do it, even if the name is longer than the code you have extracted
"

Avoid Too Many Parameters  

Declare a class instead of too many parameters. Creating a class that puts all these parameters together. This is generally a better design and valuable abstraction.
//avoid
public void Checkout(string shippingName, string shippingCity, 
 string shippingSate, string shippingZip, string billingName, 
string billingCity, string billingSate, string billingZip)
       {
 
       }  
//DO
public void Checkout(ShippingAddress shippingAddress,

BillingAddress billingAddress)
        {
 
        } 
We should introduce class instead of all parameters.

Avoid Complex Expressions

if(product.Price>500 && !product.IsDeleted && !product.IsFeatured &&

 product.IsExported)
          {
             // do something
          } 
Complex expression have some meaning behind them it is just hidden by those multiple expressions. We can Encapsulated the complex expression into that object by using a property. That code will be easier to read. 

Consider Warnings as Errors


If you notice the code you will find a variable that was declared but never used. Normally if we build the project we will get a warning and we can run our project without any error. But we should remove warning as much as possible. So setup your build to treat warning as Errors like the following steps:





Avoid Multiple Exit Points

This rule is very easy to follow. Developer should try to maintain single exit point and entry point.
 //avoid
         if(product.Price>15)
           {
               return false;
           }
           else if(product.IsDeleted)
           {
               return false;
           }
           else if(!product.IsFeatured)
           {
               return false;
           }
           else if()
           {
               //.....
           }
           return true;
 //DO
       var isValid = true;
           if(product.Price>15)
           {
               isValid= false;
           }
           else if(product.IsDeleted)
           {
               isValid= false;
           }
           else if(!product.IsFeatured)
           {
               isValid= false;
           }
           return isValid; 
You can imagine 4 exit points scattered around 20- 30 lines of code.That makes you more harder to understand and see what is happening inside the method and what will execute and when will execute.
I got too many responses, some agreeing but mostly disagreeing that it was a good  "standard" to enforce. To find out the potentiality I did some unit testing and found that for complex method that have multiple exit points usually have a set of tests for each of those paths. Once work is done, get the heck out of there isn't always possible because sometime you need to clean up your resources as well.
if( BADFunction() == true)
 {
    // expression
    if( anotherFunction() == true )
    {
     // expression
     return true;
    }
    else
    {
         //error
    }
 }
 else
 {
    //error
 }
 return false;
  if( !GoodFunction())
 {
    // error.
    return false
 } 
     // expression
 if( !GoodFunction2())
 {
    //error.
    return false;
 }
 // more expression
 return true; 
Please read Controlling Loops chapter from the book "Code Complete" by Steve McConnell for further detail clarification on Multiple Exit Points.

Assertion    

An assertion is code that’s used during development—usually a routine or macro—that allows to check itself as it runs.True means everything is operating as expected. False means it has detected an unexpected error in the code.An assertion usually takes two arguments: a Boolean expression that describes the assumption that’s supposed to be true and a message to display if it isn’t.
Assertions are especially useful in large, complicated and in high reliability system.
Example: If a system assumes that there will be maximum 100,000 user records, the system might contain an assertion that the number of records is less than or equal to 100,000. So assertion will be silent within that range. If it encounters more than that records,it will loudly “assert” that there is an error in the program.

Checking Loop Endpoints 

A single loop usually has three cases of interest: the first case, an arbitrarily selected middle case, and the last case.If you have any special cases that are different from the first or last case, check those too. If the loop contains complex computations, get out your calculator and manually check the calculations.

Sunday, February 3, 2013

Bind Dropdownlist from Database - ASP.NET

Before implement this example first design one table UserInformation in your database as shown below
Column Name
Data Type
Allow Nulls
UserId
Int (set Identity=true)
No
UserName
varchar(50)
Yes
Location
Varchar(50)
Yes
Once table designed in database write the following code in your aspx page
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>how to show data in dropdownlist from database in asp.net</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<b>Selected UserName:</b>
<asp:DropDownList ID="ddlCountry" runat="server" />
</div>
</form>
</body>
</html>
Now add the following namespaces in code behind

C# Code
using System;
using System.Data;
using System.Data.SqlClient;
using System.Web.UI.WebControls;
After add namespaces write the following code in code behind
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindContrydropdown();
}
}
/// <summary>
/// Bind COuntrydropdown
/// </summary>
protected void BindContrydropdown()
{
//conenction path for database
using (SqlConnection con = new SqlConnection("Data Source=SureshDasari;Integrated Security=true;Initial Catalog=MySampleDB"))
{
con.Open();
SqlCommand cmd = new SqlCommand("Select UserId,UserName FROM UserInformation", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
ddlCountry.DataSource = ds;
ddlCountry.DataTextField = "UserName";
ddlCountry.DataValueField = "UserId";
ddlCountry.DataBind();
ddlCountry.Items.Insert(0, new ListItem("--Select--", "0"));
con.Close();
}
}
VB.NET Code
Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.UI.WebControls
Partial Class VBSample
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
BindContrydropdown()
End If
End Sub
''' <summary>
''' Bind COuntrydropdown
''' </summary>
Protected Sub BindContrydropdown()
'conenction path for database
Using con As New SqlConnection("Data Source=SureshDasari;Integrated Security=true;Initial Catalog=MySampleDB")
con.Open()
Dim cmd As New SqlCommand("Select UserId,UserName FROM UserInformation", con)
Dim da As New SqlDataAdapter(cmd)
Dim ds As New DataSet()
da.Fill(ds)
ddlCountry.DataSource = ds
ddlCountry.DataTextField = "UserName"
ddlCountry.DataValueField = "UserId"
ddlCountry.DataBind()
ddlCountry.Items.Insert(0, New ListItem("--Select--", "0"))
con.Close()
End Using
End Sub
End Class
Demo