Reading other people’s .NET code

One thing that makes HTML easy to learn is the abundance of examples. You can go to any old website and view the source to see how it’s put together, or look through templates on a site like Open Source Web Design or Open Source Templates. It’s easy find examples of good (and bad) practice.

Scott Hanselman’s article Reading to Be a Better Developer got me wondering why we don’t do this more with .NET code, and the problem for me seems to be finding good code examples. Scott recommends looking at the Coding4Fun Developer Kit, but I wanted something more specific to web development.

So here are a few places I found ASP.NET source code that’s worth studying and learning from.

Microsoft Enterprise Library

A great place to start is the application blocks in Microsoft’s Enterprise Library. These are application service components designed to follow Microsoft best practices and include modules for caching, cryptography, data access, exception handling, logging, policy injection, security and validation.

Website Starter Kits

Another good place to look is the ASP.NET Starter Kit Websites, a collection of working ASP.NET demos that can be examined or built on. They cover DotNetNuke, e-commerce with PayPal, blogging, project time management, media library and plenty more.

Codeplex

Lastly Codeplex, Microsoft’s open source project hosting site. There’s so much goodness here it’s hard know where to start, so try browsing the most popular or active projects to start. Here are the top ten that caught my eye:

  • BlogEngine.NET
    Full featured blog engine targeted at .NET developers. It is light weight and very simple to modify and extend.
  • Umbraco
    Simple, flexible and friendly ASP.NET CMS
  • DinnerNow
    Sample marketplace application designed to demonstrate how you can develop a connected application using IIS7, ASP.NET Ajax Extensions, Linq, WCF, WF, WPF, Powershell, and the .NET Compact Framework.
  • Community Kit for SharePoint
    Set of best practices, templates, Web Parts, tools, and source code for creating a community website based on SharePoint.
  • Facebook Developer Toolkit and Facebook.NET
    .NET wrappers and libraries for the Facebook API.
  • DbEntry.Net
    Lightweight, high performance Object Relational Mapping (ORM) database access compnent for .NET 2.0.
  • PublicDomain
    .NET packages for time zone support, logging, dynamic code evaluation, GAC API, unzipping, RSS, Atom, OPML, screen scraping, and utilities for strings, arrays and cryptography.
  • ASP.NET RSS Toolkit
    Gives ASP.NET applications the ability to consume and publish to RSS feeds.
  • NGenerics
    Class library providing generic data structures and algorithms not implemented in the standard .NET framework
  • Html Agility Pack
    Agile HTML parser that builds a read/write DOM and supports plain XPath or XSLT. The parser is very tolerant with “real world” malformed HTML. The object model is very similar to System.Xml, but for HTML documents.

If you know any other places to find good quality .NET source code then please leave a comment.

Fun Google Searches

It’s amazing how much cool stuff you can do with some of the lesser known Google Search features:

Got any more?

Task List comments in Visual Studio

Here’s a quick Visual Studio tip. You can embed useful notes and reminders in code using Task List comments like this:

// TODO: fix catastrophic memory leak

These notes will automatically appear in the Visual Studio Task List, which you can open with the shortcut Ctrl+W, T or by selecting View – Task List from the main menu bar.

Visual Studio Task List

Visual Studio also supports two other comment tokens, HACK and UNDONE. You can even add your own custom comment tokens in:

Options – Environment – Task List.

If the code and the comments disagree, then both are probably wrong

Let us change our traditional attitude to the construction of programs. Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.
— Donald Knuth

I recently wrote some code commenting guidelines to explain why comments are usually a Good Thing. Some intelligent and good looking people agreed with me, while others insisted sharing incoherent and rambling opinions.

Mads Kristensen rightly pointed out that, “If [comments] are good, then the code is also good”. Some people took this to mean that if a piece of code has good comments, then it’s also guaranteed to be of the very finest quality. There’ll always be exceptions. Code with good comments can easily be mutilated by a placement student or twisted beyond sanity by a crazed Perl developer. But good comments are often correlated with good code when the software is built by a good developer.

How about this one, “code should be written in a way that doesn’t require commenting”. Close, but wrong. Code should be written is such a way that it doesn’t require commenting to explain how it works. My original article wasn’t about refactoring, but if you have a block of code with a comment then sometimes it makes sense to extract it into its own method. If it still isn’t clear then try renaming the method. If you think you need a comment to note assumptions then state them explicitly by introducing an assertion. If there’s still any uncertainty then use comments. Explain obscure optimizations or special algorithms. Explain why you’re code does what it does.

Posted in .net. 3 Comments »

Convert table to CSV string in SQL Server

There doesn’t seem to be a native function in SQL Server to collapse a table of row values into a comma-separated string, for example:

Animal
Llama
Manatee
Pygmy Marmoset
Okapi

Result CSV: “Llama, Manatee, Pygmy Marmoset, Okapi”

In mySQL there’s a built-in aggregate function called group_concat, but no equivalent in SQL Server unless you build your own .NET function, like in this TechNet article Invoking CLR User-Defined Aggregate Functions. That’s quite a chunk of coding and is restricted to SQL Server 2005 or later, so here’s a handy SQL snippet that does a similar job without the fuss.

select Name from Animal

declare @csv varchar(max)
select @csv = coalesce(@csv + ‘, ‘, ”) + Name from Animal
select @csv

If you use the code regularly then consider creating a scalar user-defined function (UDF) that returns the CSV string as varchar.

Recruiting VB.NET developers

Why is it almost impossible to recruit good VB.NET developers? Here’s my theory.

Many who call themselves VB.NET developers often fall into the niche of someone with lots of VB6 experience who has dabbled a bit with .NET. As a result, their VB.NET code looks just like VB6, with all its inherent problems, which is perfectly allowable through VB.NET legacy features. These compatibility components are great for migrating old VB6 code to .NET, but lazy ex-VB6 developers abuse them into new code because it’s easier than learning the correct .NET equivalents. For example, they use modules instead of classes, On Error Goto instead of structured error handling, and legacy functions such as IsNumeric or LTrim.

What you need is a .NET developer, someone who understands .NET regardless of language. Unfortunately, many of these people label themselves C# developers because of the (somewhat unfair) stigma of VB not being a ‘real’ programming language, and because C# developers are generally paid more.  So, if you want good VB.NET developers, hire C# developers, or better yet a language agnostic .NET developer.

Even if a C# developer has never laid eyes on VB code, nearly all differences are syntactic and can be picked up in a few days.  The real expertise in .NET is an understanding of the framework, object-oriented design, and good general development practices.

Related links:

Posted in .net. 1 Comment »

Exam 70-547 – MCPD – Web Developer

Last year I took the exams for MCTS: .NET 2.0 Web Apps.  It was a good way to pick up all the new .NET 2.0 stuff, so now I’m going to have a go at the next certification MCPD: Web Developer.  I need to pass one more exam to upgrade MCTS certification to MCPD:

Exam 70-547 - PRO: Designing and Developing Web-Based Applications by Using the Microsoft .NET Framework

Here are some study resources I found, they might be useful to anyone else studying for the same exam.  Leave a comment if you’re also studying for MCPD, or know any other good study links.

General Info

Books

Practice exams

Unhygienic .NET code

I’m currently rewriting an ASP.NET page that’s part of a large and very busy website.  The code is so bad it’s difficult to imagine how it ever worked in the first place, let alone serviced hundreds of thousands of hits every day.  I’m refactoring it to run within a new architecture that has proper boundaires between presentation, business and data layers.  It’s a close call whether or not to completely rewrite the page from scratch, but there’s too much danger of missing some crucial functionality.

Here are a few points I’ve picked out that would’ve made the original code less disgusting.

  1. Don’t build your entire page’s logic into a single Page_OnLoad event handler.  This routine should only contain calls to other functions that need to be executed when a page loads.
  2. Comment your code, even if you just add markers to roughly indicate what each group of statements is doing.  It’s painstaking to trawl though thousands of lines of uncommented code trying to work out what each bit does.
  3. Modularise your code.  Split each separate unit of work into its own function or subroutine.  Pass data to these routines in parameters rather than sharing data in global or other broad-scope variables.  Make your routines loosely-coupled and highly-cohesive.
  4. If you use a data layer, as you should be, don’t pass an open SqlDataReader (or any DbDataReader) to your presentation layer, the .aspx code-behind.  Your data access should be abstracted from the presentation and business layers, so they aren’t tied to a particular implementation.  I like to use business entity objects and generic collections, but you can also use strongly-typed datasets or XML.  The pros and cons are outlined in this MS Patterns & Practices guide, Designing Data Tier Components and Passing Data Through Tiers.
  5. Don’t use Hungarian notation, where the variable name indicates the data type, such as intRowCount instead of just rowCount.  This was useful for weakly-typed languages that use variant data types, but is useless and messy in .NET’s strongly-typed languages.  If you try to do something not supported by a particular data type then it won’t compile.  You can find out a variable’s type by hovering the mouse over it in Visual Studio.
  6. Don’t declare all your variables at the top of a function, especially when your function is several thousand lines.  It’s not 1980 and this isn’t C.  Keep your variables’ scope as small as possible, and declare them near where they’re used.
  7. Don’t open multiple database connections on the same page an leave them open until the very end.  You shouldn’t be opening any connections anyway, this should happen in the data layer, but if you must then at least only open them where they’re needed and close them as soon as you’re finished.  There’s a large overhead involved in keep database connections open, so this mistake can seriously damage your application’s performance.
  8. Don’t wrap all your code in a massive try block with an empty catch that swallows up any exceptions that might be thrown, just because you can’t be bothered to do any error handling. Exceptions should either be handled or propagated up the call stack until they are.

Remember, the next person who has to maintain or extend your application might be you.  Or even worse, me.

Posted in .net. 2 Comments »

.NET Coding Guidelines – SQL Injection

In the first of my guidelines for deadbeat developers, I asked why you’re too lazy to comment your code. This time, I’d like to investigate why you build software that’s catastrophically insecure.

Part 2 – Protect against SQL injection in .NET

This code will look familiar because it’s the sort of sloppy mistake you make all the time.

string productId = Request.QueryString["ProductId"];
string sql = "delete Products where Id=" + productId;
SqlCommand cmd = new SqlCommand(sql);
cmd.ExecuteNonQuery();

Your feeble imagination doesn’t stretch far enough to consider what happens when a mischievous user sets productId to, say, “1 OR 1=1″. You merrily build the query, complete with unverified user input, and execute it against the database.

delete Products where Id=1 OR 1=1

Oh dear, where did all your products go?

A vigilant SQL Server DBA can thwart your stupidity at the database by restricting your access. By assigning your login to the db_denydatareader and db_denydatawriter roles, you can thankfully be prevented from running any SELECT, DELETE, INSERT or UPDATE queries whatsoever.

SQL Server roles

Since you can’t be trusted, the DBA should give you permissions to execute only the stored-procedures and UDFs you need. This is the principle of least privilege.

Grant SQL exec permission

Parameterised stored-procedures are usually safe from SQL injection because they validate the type and size of the inputs. These inputs are evaluated as values only, and not executed as part of the SQL statement. But there is one exception. When you build SQL dynamically inside the stored-procedure.

sp_executesql ’select * from Products where Id in ‘ + @List

This line is from a real stored-procedure I saw last week, @List is a varchar parameter containing something like “(1,2,3)”. And, of course, the values for @List came from unverified user input. If you absolutely have to use dynamic SQL then at least clean the inputs and remove or escape anything that could be potentially dangerous.

Read more about SQL injection: