Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

June 2008 - Posts

Code Complete 2

Code Complete 2
Code Complete: A Practical Handbook of Software Construction
Code Complete 2 is very good and must-be book by Steve McConnell for all developers. The book covers many aspcets of coding and gives very good advices about how to organize and write your code, how to comment and document it and how to write code without ruining yourself.

Although I have been in business more than ten years this book was very interesting reading to me. It is easy to read, doesn't make you sleepy and makes you think about your work and coding habbits.

I have tried practices described in this book also in real-world projects and believe me - these practices work very well. I suggest this book to all developers - to beginners, experts and top level professionals.

You can always order your software from company where you see old and heavily used Code Complete on some table.

Editorial review from Amazon

For more than a decade, Steve McConnell, one of the premier authors and voices in the software community, has helped change the way developers write code--and produce better software. Now his classic book, CODE COMPLETE, has been fully updated and revised with best practices in the art and science of constructing software. Whether you're a new developer seeking a sound introduction to the practice of software development or a veteran exploring strategic new approaches to problem solving, you'll find a wealth of practical suggestions and methods for strengthening your skills. Topics include design, applying good techniques to construction, eliminating errors, planning, managing construction activities, and relating personal character to superior software. This new edition features fully updated information on programming techniques, including the emergence of Web-style programming, and integrated coverage of object-oriented design. You'll also find new code examples--both good and bad--in C++, Microsoft(r) Visual Basic(r), C#, and Java, though the focus is squarely on techniques and practices.

Table of contents

Checklists
Reference Tables
Preface
 
Laying the Foundation
1.  Welcome to Software Construction
2.  Metaphors for a Richer Understanding of Programming
3.  Prerequisites to Construction
 
Design
4.  Steps in Building a Routine
5.  Characteristics of High-Quality Routines
6.  Three out of Four Programmers Surveyed Prefer Modules
7.  High-Level Design in Construction
 
Data
8.  Creating Data
9.  The Power of Data Names
10.  General Issues in Using Variables
11.  Fundamental Data Types
12.  Complex Data Types
 
Control
13.  Organizing Straight-Line Code
14.  Using Conditionals
15.  Controlling Loops
16.  Unusual Control Structures
17.  General Control Issues
 
Constant Considerations
18.  Layout and Style
19.  Self-Documenting Code
20.  Programming Tools
21.  How Program Size Affects Construction
22.  Managing Construction
 
Quality Improvement
23.  The Software-Quality Landscape
24.  Reviews
25.  Unit Testing
26.  Debugging
 
Final Steps
27.  System Integration
28.  Code-Tuning Strategies
29.  Code-Tuning Techniques
30.  Software Evolution
 
Software Craftsmanship
31.  Personal Character
32.  Themes in Software Craftsmanship
33.  Where to Go for More Information
Bibliography
Index
Interface for Processes

I had to write one data import/export utility that moved data from one database to another. Once I was finished the first round of coding I found one thing that needed refactoring - the import/export process wasn't generalized. It was part of importer/exporter utility main class (it was console application). After some refactoring I got some common things to use in other tasks like this.

My main idea was to extract interface for processes like this and then define some events. Let's suppose we have process that reads invoices from one database and writes them after some data manipulation to other database. We receive list of invoices and then start processing them.

Process delegates

Every import/export process has start, processing part and finish. Processing part is step that is repeated for every data unit we are processing. All these three may be events that our processing class fires. Let's define some delegates for these events.


delegate void ProcessStartDelegate(int count);
delegate void ProcessStepDelegate<T>(T obj, int index, int count);
delegate void ProcessFinishDelegate();

ProcessStartDelegate is fired when process starts. It is received input data and wants to start processing. Let's say we have invoices as input data. As we have list of invoices we can say how many invoices we have. This is why ProcessStartDelegate has argument calles count.

ProcessStepDelegate is fired for every invoice we have. We want to use these delegates in different import/export processes, so we have to make ProcessStepDelegate generic because this way we can say type of object to it. Index is argument that shows the index of current invoice in input array. count is also there because some processes may change the input collection size during their work.

ProcessFinishDelegate is fired when process finishes. This delegate has no arguments because we already know how much elements we have.

Process interface

Now we have our delegates and we are ready to take the next step. Let's define now interface for import/export processes. We want generic interface so we can use it also with other import/export classes. ProcessStepDelegate was generic and so we have to make our interface generic also. So here is our interface.


interface IProcess<T>
{ 
    event ProcessStartDelegate ProcessStart;
    event ProcessStepDelegate<T> ProcessStep;
    event ProcessFinishDelegate ProcessFinish;
 
    void Process();
}

I added also method Process() this interface because we need something we can call to start the process.

This interface is all we need here.

Example

Let's see now simple example about how to use IProcess interface. As I said before we suppose we have class for invoices. We call this class Invoice.


public class InvoiceImporter : IProcess<Invoice>
{
    public event ProcessStartDelegate ProcessStart;
    public event ProcessStepDelegate<Invoice> ProcessStep;
    public event ProcessFinishDelegate ProcessFinish;
 
    public InvoiceImporter() { }
 
    public void Process()
    {
 
        List<Invoice> invoices = LoadInvoices();
 
        if (this.ProcessStart != null)
            this.ProcessStart(invoices.Count);
 
        int i = 0;
 
        foreach(Invoice invoice in invoices)
        {
            if (this.ProcessStep != null)
                this.ProcessStep(invoice, ++i, invoices.Count);
 
            ProcessInvoice(invoice);
        }
 
        if (this.ProcessFinish != null)
            this.ProcessFinish();
    }
 
    private List<Invoice> LoadInvoices()
    {
        List<Invoice> invoices = new List<Invoice>();
 
        // Fill list here
 
        return invoices;
    }
 
    private void ProcessInvoice(Invoice invoice)
    { 
        // Do some processing here    
    }
}

This is simple skeleton of invoice importer. I follows completely IProcess interface. You can use this interface for different kinds of import/export classes to make sure they all follow the same pattern.

Don't Make Me Think

Don't Make Me ThinkDon't Make Me Think by Steve Krug is the definitive guide to user friendly web pages. This book doesn't tell you about how to make HTML pages or how to design them. This book tells you what to keep in mind when dealing with web pages and how to make your web pages user friendly.

The book is pretty good reading when having a longer flight by example. It has not very much pages and it is easy to read. Many things you can find in this book are very elementar when thinking about them. But we often forget those little and important things that make or sites easy and fun to use.

Don't Make Me Think is not only for web professionals. It is very good reading also for managers and specially for people from companies who want to create or update their web sites. This book is very good investment because after reading this book you think about web pages differently than before.

Posted: Jun 15 2008, 12:32 AM by DigiMortal | with 2 comment(s) |
Filed under:
GridView and Invalid CurrentPageIndex Value Exception - .Net 3.5 Version

In my previous GridView entry titled as GridView and Invalid CurrentPageIndex Value Exception I made an example about how to corrigate paged GridView page index before grid is bound to data. Let's to id now .Net Framework 3.5 way.


public static class GridViewExtensions
{ 
    public static void CorrigatePageIndex(this GridView gdv, Int32 rowCount)
    {
        Int32 newIndex = gdv.PageIndex;
        if(gdv.PageSize> 0) 
            if((Int32)Math.Ceiling((decimal)rowCount / gdv.PageSize) < newIndex)
                newIndex = (Int32)Math.Ceiling((decimal)rowCount / gdv.PageSize); 
        if(newIndex <0) 
            newIndex = 0;
        gdv.PageIndex = newIndex;
    }
}

Now we can corrigate page index usng the following code.


protected void Page_Load(object sender, EventArgs e)
{
    if (this.IsPostBack)
        return;
    DataTable dt = GetRows();
    gdvList.PageIndex = 15;
    gdvList.DataSource = dt;
    gdvList.CorrectCurrentPage(dt.Rows.Count);
    gdvList.DataBind();
}

Posted: Jun 12 2008, 09:12 AM by DigiMortal | with no comments
Filed under: ,
Basic ASP.NET SEO

SEO is popular topic nowadays and as ASP.NET is growing its popularity also as platform for public systems. Therefore SEO is going to be more important topic also for ASP.NET developers. The world of SEO is always in rapid change - can you imagine that last year Google published 450 updates to it's search engine algorithms? Although the field is changing fast there are some key points that has been fundamental and unchanged this far. Let's see what is the minimum you should do and how you can make your sites more SEO friendly on ASP.NET.

At first I will give you some first ideas what you can do to make your site better. And after this list (that hopefully makes you think) I will tell you one little point - what SEO is all about.

NB! This blog entry describes only the technical side of SEO you may want to consider when building your public sites. There are many other topics how your site gets more visible and how you can make more traffic. But I will leave these topics for some of the next blog entries.

1. Page titles

One of the most important things are page titles (between <title></title> tags). When somebody is searching something then these titles are shown as links in search results. One of the common mistakes is using same title for all pages. Imagine how worthless are the following search results for user.

TheVeryBigCorporation
Some fragments from page that may not be useful for user.

TheVeryBigCorporation
Some other fragments from page as description.

TheVeryBigCorporation
Almost no content, let's show what we have. Date Modified 01/19/2008 Titles by Marc and Lewis Custom services.

TheVeryBigCorporation
Some fragments from page that may not be useful for user.

TheVeryBigCorporation
Some fragments from page that may not be useful for user.

When using page titles carefully you give searchers a reason to visit your site - if your site offers something they are looking for. They can easily see from results if this page may offer something they are interested in.

Adding title to your pages is not something complex. If you built CMS then you have titles anyway inserted for each page. If you built product catalog then use product names as page titles. If you think further you discover that you have more data already there in your databases you can use in page titles.

2. Use meaningful URLs

"Nice" URLs is the other important point. Instead of using long URLs that contain many query parameters, you should use URLs that are formatted as URLs of static pages. Some experts say that it is enough, I don't agree - it is not enough. Look at the following two URLs.

somesite.com/index.php?op=content&act=view&id=100.html

somesite.com/content/view/100.html

First one looks like some alian language. The other one is better at one point - it is shown correctly by almost every mail client in this world (except the buggy ones of course). But for visitor this URL doesn't have any value. Visitor may get some idea that he or she is looking at content and then there is hundred. What is this hundred stand for? Dunno.

Now let's go one step further and let's use meaningful URLs instead of nice ones. Meaningful URL is nice URL that has some meaning for visitor. I mean if I give you meaningful URL you can figure out what you may find on page behind this URL. Here is the meaningful version of previous URL.

somesite.com/printers/laserjet-1200.html

Now you have URL that tells you what you can find when you follow it. In this case it hopefully opens the page that introduces HP LaserJet 1200.

You can use components like UrlRewritingNet.UrlRewrite for nice URLs. Also be noticed that IIS7 has URL mapping support that provides you with mod_rewrite-like features (mod_rewrite is very popular Apache HTTP Server module).

3. Tell about the structure of your content

Every page has some structure. Title, maybe teaser, paragraphs, headings and so on. Maybe some citations and quotes and why not some important points you want to emphasize. Most of robots are not very strong on analyzing CSS. To make your page semantically correct follow these steps.

  1. Use headings to divide longer stories to parts that make sense to readers. You can use <h1>...<h5> tags by example. These tags are made for this.
  2. If you need to emphasize some sentence of your text, put it between <strong>, <em> or <u> tags.
  3. Use <cite> for citations, <quote> for quotes and so on. Let robots know what parts your pages contains. 

This way you also make your pages easier to read to your visitors. I am sure they are happy if you provide correctly structured content that is easy to read.

You can make your users life easy - use WYSIWYG editors like FCKEditor, so your users can create structured content by theirselves. FCK has also support for ASP.NET and offers ASP.NET control you can use on your pages for free. Integrating these editors to your site is nothing complex.

5. Test your site on extreme conditions

What happens when your site is slow and requests often timeout? Well, some of these requests are made by robots and if they continuously cannot connect your site they will dsrop it form their indeces. Make sure your site responds acceptably fast to requests also under heavy load.

As a visitors we don't like slow sites. We want pages to open fast and when page is opening every second is like decade for us.

You can use tools to make automatic stress tests to your site. Just record your paths, configure flood and run the tests. When you use performance counters you may find out almost all weak parts of your site before it goes to production.

6. Test your AJAX site in terms of SEO

When using AJAX in your site then you are usually in hard trouble - search engine spiders will see only few parts your site because they doesn't run JavaScript. Yes, they can analyze it but they doesn't run it. So, most content of AJAX intensive sites is invisible for robots and it will never get indexed.

To make your AJAX site search engine friendly try to avoid initial content loading over JavaScript. At least for these parts of your page that you want to be indexed. Also you have to make it easy to robots to navigate through your site.

If you want to see how robots will see your AJAX site then use a simple trick. Turn off JavaScript support from your browser and try to visit your AJAX site. Now you will see what really gets indexed when robots are indexing your site.

The End - The Point

The fundamental point of SEO is not technically optimize your sites for robots and indexing algorithms. Search engines are developed differently - they try to find more and more accurately how well page fits for humans needs.

Each of previous six point - if you noticed - mentions visitors and how things are getting better for them. Exactly - better to visitors, not robots.

If you develop your pages with visitors in mind then you are best SEO expert ever seen!

Posted: Jun 10 2008, 02:41 PM by DigiMortal | with 13 comment(s) |
Filed under: ,
GridView and Invalid CurrentPageIndex Value Exception

There are many developers who have faced the page index problems using GridView. Specially, if GridView supports deleting. Also one may face page index going out of range when there are multiple users managing same data. Here is my little advice about how to avoid page index problems when using GridView.

How to produce "Invalid PageIndex value" exception

Let's produce this exception intentionally. We have to bind GridView to some data source and enable paging. Before we bind GridView to data we have to set current page index. If we have 10 pages of data then let's say that current page index is 15.


protected void Page_Load(object sender, EventArgs e)
{
    if(this.IsPostBack) 
        return;

    gdvList.PageIndex = 15;
    gdvList.DataSource = GetRows();
    gdvList.DataBind();
}


As a result we will get the following error.

Invalid PageIndex value.

Now, let's see what we can do to avoid this error.

Corrigating page index

If there is custom control class that extends GridView it is more convenient to add the following code to this class so this feature is available in all GridViews used in project. If there is no custom class then we have to write some additional code before binding GridView to data.

To corrigate the page index our method has to know to things:

  1. count of elements in data source,
  2. GridView object that has index we want to corrigate.

This method can be added to some utility class in project.


public static void CorrectCurrentPage(Int32 count, GridView gdv)
{   
    Int32 newIndex = gdv.PageIndex;

    if(gdv.PageSize> 0)
        if((Int32)Math.Ceiling(count / gdv.PageSize) <newIndex)
            newIndex = (Int32)Math.Ceiling(count / gdv.PageSize);
    if(newIndex <0)
        newIndex = 0;
    gdv.PageIndex = newIndex;
}


This method is pretty universal and if it is needed it is not hard to rewrite it for DataGrid by example. Now, why we give elements count to this method but not the object with data? The reason is simple - we don't want to know what is the data source of GridView. Is it somethings based on IEnumerable interface or is it DataTable or is it something else. All we need to know is elements count so we don't have to handle different data sources in this method.

Let's extend the first code example with one line and let's see what happens.


protected void Page_Load(object sender, EventArgs e)
{
    if(this.IsPostBack) 
        return;
    DataTable dt = GetRows();
    gdvList.PageIndex = 15;
    gdvList.DataSource = dt;
    CorrectCurrentPage(dt.Rows.Count, gdvList);
    gdvList.DataBind();
}

Now, if current page index is bigger than pages count in GridView then we have last page in GridView as current page. If current page has too low value then we have 0 as current page index. This way you can be sure that there is no problems related to running out of page indexes.

C# and Partial Classes

.Net 2.0 provided us with new feature called partial classes. Using partial classes we can use multiple files to keep the code of same class. Yes - we can put some methods to one file and the others to another file. Although partial classes may be extremely useful they can be also used to ruin system's technical design if developers don't know what happens behind the compiler.

Visual Studio uses partial classes to keep Windows and Web forms automatically generated code separately of user written code behind the forms.

Let's see one very simple partial class that has two methods. The parts of this class can be also defined in same file if needed.


public partial class PartialClass
{
    public void MethodA()
    {
        Console.WriteLine("I am A!");
    }
}

public partial class PartialClass
{
    public void MethodB()
    {
        Console.WriteLine("I am B!");
    }
}


If we try to call methods of this class we can see something like this on screen.

Methods of partial class

As we can see, IntelliSense doesn't say a thing about separation of these methods. You can see hint of extension methods if you check out one of my previuos entries Extension methods - how they look like after compiling.

Let's compile this code now and let's see what has compiler done. Here is the class shown in Reflector.

partial-class-reflector

As we can see there is no separation of methods after compiling - all parts are compiled together and we can see it as one class. No separation anymore!

This is also prove to multi-tier arcitecture example I gave in entry titled as Behind the Compiler.

Building Object Applications That Work

Building Object Applications That Work
Building Object Applications That Work
Building Object Applications That Work by Scott Ambler is great book for every developer who is working with object-oriented systems. This book is recommended reading also for system architects, designers and managers to get better understanding of object-oriented world.

The author of this book, Scott W. Ambler, is specialist of object-oriented techniques. He has long and rich experience working with object-oriented systems. The book covers many important topics like terms and language of object-oriented world, design, measuring, user interfaces, persistence and databases and testing.

For me this book was very good overview of field and I found out many things I was not considered before. Also I got some very good ideas, so I suggest this book to every developer who wants to get better understanding of object-oriented conception.
 

Working Effectively with Legacy Code

Working Effectively with Legacy Code
Working Effectively with Legacy Code (Robert C. Martin Series)
This is the first entry of my books sections in this blog. The first book I want to introduce is Working Effectively with Legacy Code by Michael Feathers. This book is extremely useful when there is need to fix systems with legacy code base. Okay, for me there are two types of legacy code: a) legacy code that is possible to improve b) CTRL-A and Delete. This book covers only first type of legacy code.

The book introduces different problem related to legacy code base and offers methods how to make legace code readable, usable and testable. This book is recommended reading for everybody who must mess with legacy code because it is always better to develop on code that is as safe as currently possible.

Working Effectively with Legacy Code may save you not only hours of time but event days or weeks or why not - months. I suggest this book highly also to developers who want to learn how to write systems that live longer than usual mess seen in our everydays life.

More Posts