software development
String.Format is your friend
One of the consultants that works for me was trying to figure out the best way to format strings for writing messages to the event log for a Windows service he’s writing. He was using the horrifying “blah blah blah” +
A quick Google search revealed an excellent String.Format 101 blog post by Kathy Kam. Karl Seguin’s post on the same topic brings performance advantages into the discussion. Another bit of information I didn’t know before reading his post was that the StringBuilder class has an equivalent AppendFormat method.
NDbUnit
I’ve been a big fan of test-driven development (and unit testing) since I first learned about it a few years ago. It wasn’t until this month that I learned about NDbUnit. This little library is a great value-add for unit tests that involve databases. The creation of test data is tedious if done manually (NDbUnit uses XML for data files), but that’s the only real drawback I’ve found so far in my limited experience with it. It plays very nicely with NUnit, MbUnit, and TestDriven.NET. You can get binaries and source code for NDbUnit from Quality Labs. I also put together a (very) small sample project with Visual Studio 2005 that you can try out.
Continuous Integration
The practice is well-defined in a couple of articles on Wikipedia and on Martin Fowler’s website. But as long as I’ve been reading about this best practice, I’ve never seen it implemented at any of my past jobs (or my current one for that matter). Fortunately, one of the consultants I’m currently working with not only has it implemented, but has the necessary software and test projects on a USB key that he carries with him from job-to-job.
Before I demonstrate it to the broader software team as a practice, I’m trying to get it working on my own machine. Because he uses MbUnit instead of NUnit as part of his implementation, it took me a little longer to get the second of his six test projects working. A little googling for Nant and MbUnit yielded an article that listed 5 files to be copied to the bin directory of Nant. Once I did that, the second test project worked fine.
Strangely, I only saw 4 of the 5 files in this list:
- MbUnit.Core.dll
- MbUnit.Framework.dll
- MbUnit.Tasks.dll
- Quickgraph.dll
- QuickGraph.Algorithms.dll
Stop users from double-clicking Submit buttons
I came across this tip via 4GuysFromRolla.com. It’s some JavaScript to disable a form’s Submit button once it’s pressed.
This extended post talks about changing the text value of the Submit button to “Submitted” (or something equivalent) to further communicate that the button has been pressed (and prevent it from being clicked again).
While not a terribly sophisticated tip, it does a great job of preventing certain user errors.
Why Unit Test
I came across a great post on unit testing today that provided not just why to unit test, but what to unit test. Differentiating software into “infrastructure” and “end user application” really highlights what sort of code will benefit the most from the approach. Another really useful bit of this article talks about turning bug reports into unit tests. It’s a very smart idea that I’ll try to use on my own code whenever it’s appropriate.
MyGeneration and Gentle.NET
After last week’s post about the stored procs vs. ad-hoc SQL debate, I decided I’d take a look at MyGeneration and Gentle.NET if I could think of the right project. I decided to start with a simple contact form.
Anytime a form has dropdowns, I try to use database tables to populate them. So I started by copying data for the dropdowns from an existing database to a new one for the project. Once I created a business logic assembly for the new classes to belong to, I fired up MyGeneration and ran the Gentle.NET business entity template. Creating the classes was very easy. the real challenge turned out to be referring to the right Gentle assemblies in my projects. Because I’d included references to Gentle.Common, Gentle.Framework, Gentle.Provider.SQLServer and log4net in the business logic assembly, I thought that was all I needed to do. But the web project wouldn’t compile. In order to get the page working, I had to add Gentle.Common and Gentle.Framework references to web project.
Once I sorted out my reference issues (and added a Gentle.config file), finishing the contact form went very quickly. I developed this bit of code for loading any dropdown list:
private void LoadDropDown(ref DropDownList ddl, IList dropDownItems, string textField, string valueField) { ddl.DataSource = dropDownItems; ddl.DataTextField = textField; ddl.DataValueField = valueField; ddl.DataBind(); }
Here’s how it’s called:
if (!Page.IsPostBack) { this.LoadDropDown(ref ContactTypeList,BLL.ContactType.ListAll(),“Name”,“ContactTypeId”); this.LoadDropDown(ref SubjectList,BLL.InformationType.ListAll(),“Name”,“InformationTypeId”); this.LoadDropDown(ref OrgTypeList,BLL.Audience.ListAll(),“Name”,“AudienceId”); }
Inspired by Ruby on Rails
Instead of vegging out on TV after work today, I decided to veg out on the web. Between reading and IM I managed to kill about 2 1/2 hours before I even noticed. The payoff for this exercise was discovering a little project called the .NET Action Pack. Rob Conery has taken the concepts of Ruby on Rails and reimplemented them using C# and .NET 2.0. The screencast he used to demonstrate the action pack was quite impressive. With a build provider, a configuration file, and a single assembly, you get a whole host of classes that let you query and manipulate a database however you wish that are available at design time. I’m definitely going to try this out at work tomorrow.
Visual Studio 2003 Service Pack 1
Somehow I completely missed this announcement about the Visual Studio 2003 service pack being released. Our group at Lockheed Martin won’t be upgrading to Visual Studio 2005 until 2007 at the earliest, so it looks like I’ll be installing this service pack very soon. Apparently, Microsoft found quite a few bugs that needed fixing.
Stored Procedures vs. Ad-hoc SQL Redux
I’ve written on the never-ending stored procs vs. ad-hoc SQL debate before, but there are quite a few more perspectives on both sides of it than I referred to in my previous post. Here are a few of them:
- Frans Bouma (ad-hoc SQL camp) compiles a summary post with links to various arguments here.
- Jeremy D. Miller (ad-hoc SQL camp) rejects stored procedures because they make test-driven development (TDD) slower. This is an argument I hadn't thought of. The apps I build tend to be database-driven websites. Testing logic that makes database calls at any point does slow things down quite a bit. Miller especially dislikes the idea of putting business logic into a stored procedure (defined as anything other than a CRUD operation).
- Jeff Atwood (ad-hoc SQL camp) argues against stored procedures because he prefers parameterized SQL and a single development environment.
- Microsoft's official guidance is to use stored procedures instead of direct SQL.
- Rob Howard writes in favor of stored procedures. Community Server 2.1 makes significant use of them.
C# versus VB.NET
I decided to post on this topic today because of an article I saw on the printer at work this morning. You can check out the entire article yourself here, but what made me decide to post was the author’s assertion that VB.NET can be “considerably less verbose than C#” because of the “with” keyword. He left out the existence of the “using” keyword in C#. The code he writes as an example could be simplified to the following:
using (TabPage tp = tabControl1.TabPages[0]){ tp.BackColor = Color.Red; tp.BorderStyle = BorderStyle.Fixed3D; tp.ToolTipText = “Click Me!"; tp.Text = “Hello world”; }
In C#, the keyword does double-duty by indicating inheritance from .NET and COM libraries. In VB.NET, another keyword (Imports) is needed for this task.
The author is right about the existence of more automatic formatting and IntelliSense code-completion in VB.NET. However, I consider it more a hindrance than a help when creating properties. In C#, if you want to create a read-only or write-only property, you write the property with just the get block or the set block. In VB.NET, you’re required to provide a ReadOnly or WriteOnly keyword to get the same effect.
The initial reason I decided to learn C# instead of VB.NET is a demo I saw from Don Box at a Guerilla.NET class in 2001. He took a MS Visual C++ sample app and used the .NET Framework to compile it. He didn’t have to change a single line of code to get this to work. He said at the time that this was the only language that trick was going to work for. He turned out to be right.
Early on, another argument in favor of C# was the number of code samples and books. It seemed heavily in favor of C# versus VB.NET, though the gap has certainly narrowed in subsequent years.
A third argument in favor of C# is what language software products are being built in. I heard plenty of rumors in 2001 about Microsoft rewriting some things in C#. But what’s certainly true is that some companies are building products with C#. Writely, a recent acquisition of Google, is written in C#. Community Server, from Telligent, is also written in C#. NUnit, an excellent unit testing tool (ported from JUnit), is also written in C#. NAnt is a C# port of the Ant build tool.
Mine is just one opinion among many as to whether you should use C# or VB.NET. But when there’s a development team involved, the language to be used should be the one the majority of developers are familiar with. That’s why I chose VB.NET when building MethResources.gov even though I personally prefer C#.
Here are some other opinions on the subject: Choosing between Visual Basic .NET and C# (by Ted Pattison) From VB.NET to C# and Back Again (by Darren Neimke and Scott Mitchell)
Open Source on the .NET Platform (part 2)
Back in April, at the end of my first post on the topic of “open source .NET”, I’d written that the next post in the series would be about Community Server. Telligent released version 2.1 of their flagship product just last week.
I first found the product at the end of 2004, when it was still Community Server: Forums. My employer was bidding on a project to provide an online forum to one of our government clients. One option they were considering was to make a copy of a custom online forum they’d already done for another client and modify it to suit the new requirements. This option reminded me of two things I dislike most about custom development:
- "Cut-and-paste inheritance"
- Reinventing the wheel--badly
1. Is open source the best choice for this application? Because of how long online forums have been around, open source is a particularly good choice for this application. I came across a pretty large number of options for online forums when I was searching. That said, a number of them were written in languages like PHP or Perl for UNIX (which helps answer question 2).
2. What platform are your developers most skilled at building for? As a Microsoft shop, trying to deliver a customized solution on a platform the developers weren’t familiar with was far too high a risk. This eliminated a significant number of the applications I’d seen.
3. Is the best open source application on the .NET platform? In 2004, I would have said no. To me it seemed more likely that the best open source forum application would be on UNIX, simply because of longevity. But given what the developers we had were familiar with, and the alternative of cut-and-paste inheritance with a classic ASP solution, Community Server: Forums was the best for our purposes.
4. Is it our goal to re-sell an application we’ve extended? Unlike our experience with IssueTracker, the objective of making money with modified versions of this application was clear from the very beginning.
There are two “barriers to entry” with Community Server that proved significant in our case:
- C#
- Documentation
On the plus side, Community Server is quite well-built. Its naming and architecture are consistent enough that it took me relatively little time to customize a version of it for my most recent project: pushingback.com. The site is customized in a way that would make it quite easy for us to upgrade the site from Community Server 2.0 to 2.1 if requested. If the companies that currently use it are any indication (Microsoft, Dell, MSNBC), it’s one of the bigger (if not the biggest) successes of open source on the .NET platform. In my next post on this subject, I’ll discuss an issue that seems unique to open source on .NET–competing products from Microsoft.
ASP.NET 2.0 Membership
Today I’ve been spending a bit of time fiddling around with Visual Studio 2005, particularly the ASP.NET 2.0 membership functionality. When I visited 4GuysFromRolla.com to see what they had to say about it, I came across 5-part series of articles. The examples are in VB.NET, so I’ve been rewriting them in C# (my preferred .NET language) as I go along. What stood out about their information message example in part 4 of the series was that they added a label to their login page and set the text string based on the error details.
It seemed to me that there should be a property in the Login control that could be set programmatically instead of adding a label that results in two error messages for the user to look at. It didn’t take much digging before I found it. The property: FailureText.
Here’s how my revised code looks:
protected void Login1_LoginError(object sender, EventArgs e){
MembershipUser userInfo = Membership.GetUser(this.Login1.UserName);
if (userInfo == null){
//The user entered an invalid username…
SetLoginFailureText(string.Format(“No account exists with the username ‘{0}’.",this.Login1.UserName));
} else {
if (!userInfo.IsApproved){
SetLoginFailureText(string.Format(“The account with the username ‘{0}’ has not yet been approved by the site’s administrators.”, this.Login1.UserName));
} else {
if (userInfo.IsLockedOut){
SetLoginFailureText(string.Format(“The account with the username ‘{0}’ has been locked out.”, this.Login1.UserName));
}
}
}
}
private void SetLoginFailureText(string failureText){ this.Login1.FailureText = failureText; }
Effective Bug Reporting
This has been a real problem at work lately. I’ve decided to write a document to send to people who report bugs to try and stem the tide of useless “it doesn’t work” reports. I found a nice long piece on effective bug reporting by Simon Tatham here. I’ll probably use it as a reference for further reading because I envisioned something much shorter than seven pages.
Community Server 2.0 Quick Image Buttons
The blog I’m building for a client at work needed an image button to trigger searches instead of the standard link button. After my ill-advised attempts to extend CommunityServer.Controls.IButton, the consultant I’m working with recommended a far simpler solution–changing the ASP.NET LinkButton tag to enclose an HTML image tag with the border attribute set to zero (0).
If you want to use the same technique, start with this sample skin file.
A "Most Viewed Blog Posts" control for Community Server 2.0
The Code Project is one of my favorite sources for finding out how to do things on the .NET platform. Since my blog was down for a bit a couple days ago, I thought I’d put an article there on the latest bit of customization I’ve done to Community Server. If you’re interested in the article, visit this link to read it.
Adding static pages to Community Server 2.0
I was actually searching for information on how to add dynamic pages to a Community Server 2.0 installation when I came across this post. While I don’t need static pages for my current project (yet), this information probably saved me hours of unnecessary work.
Changing File Upload Limits in Community Server 2.0
I wanted to see how much effort it would take to replace this RSS feed with a CS 2.0 blog. It’s currently being generated by an old ASP application that I customized with a colleague of mine. But I kept getting errors when I tried to upload MP3 files above a certain size. A bit of googling revealed this MSDN entry and the attribute “maxRequestLength”.
RSS Publishing
It shouldn’t be a big deal at all with apps like Community Server 2.0 or WordPress available, but budget and/or personnel constraints often conspire against us using either one. So lately, we’ve spent more time (and money, but salaries apparently don’t count) putting together custom applications to generate RSS feeds.
I always check to see if a solution to my problem already exists before building my own, so when it came time to develop the MethResources.gov RSS feed, I simply reused the example from this article by Scott Mitchell. Behind the ONDCP podcast (I did the database work, a colleague did the rest) is a classic ASP application with the most basic admin functionality.
To cut down on this sort of one-off RSS app building, I’ve been hunting around for any bits of code or fully-formed toolkits that could be reused easily. The latest interesting bit of code I came across is the ASP.NET 2.0 RSS Toolkit. It’s from a Microsoft employee, and most comments I’ve read on it have been positive. Of course, when I tried to get the samples to work, I had all kinds of problems. The solution was to create a new website project (with location = “File System”) , browse to the samples directory of the toolkit, and open the existing website. Once I did this, and added RssToolkit.dll to the GAC, all six scenarios worked perfectly. The two examples I tried from Scott Guthrie’s blog entry on the toolkit worked also.
The only things I haven’t found in this toolkit so far are support for enclosures and an easy way to syndicate a database.
ASP.NET Calendar Customization
My latest assignment is to help redesign this website into a true blog for the office of the drug czar. We’re using Community Server 2.0, and one of our requirements is to customize the calendar. Since the CS 2.0 calendar is a wrapper around the stock .NET framework one, I put together a Word document to explain the customization process to the graphic designers who are actually responsible for the look-and-feel of the calendar. My hope is that they’ll understand it well enough to reduce my workload when it comes time to implement this.
The document applies pretty well to calendar customization in general for ASP.NET 1.1 projects.
I created an RTF version and an HTML version of the content as well.
Community Server 2.0 Patching
Telligent sent out an e-mail last Friday afternoon about a critical security patch. These were the patch instructions:
Directions for installing the patch:These are the contents of the readme.txt file:
- Download the .zip file here:
- Community Server 1.1: [communityserver.org/files/fol...](http://communityserver.org/files/folders/archived_cs_releases/entry532297.aspx)
- Community Server 2.0, ASP.NET 1.1: [communityserver.org/files/fol...](http://communityserver.org/files/folders/releases/entry532260.aspx)
- Community Server 2.0, ASP.NET 2.0: [communityserver.org/files/fol...](http://communityserver.org/files/folders/releases/entry532293.aspx)
- Unzip the file(s) and extract them to a location on your computer
- Follow the directions in the readme for installing the patch on your Community Server 2.0 server(s)
Steps for installing the Community Server 2.0 SP1 Patch.I wish the readme file had said exactly where the updated source files go. I don't like the idea of having to hunt around files to replace when the patch has to do with security. So here's what the readme file should include:1. Make a copy of the CommunityServer.Components.dll found in the bin folder of your web site. 2. Replace the existing CommunityServer.Components.dll with the new one you just downloaded and unzipped.
If you have questions or problems, please email support@telligent.com
We have also included the updated source files. If you have modified any of the code in the Community Server Components project you will need to apply these fixes and redeploy your assemblies.
ComponentsHttpModuleCSHttpModule.csTelligent has an announcements blog with a post about this security patch.ComponentsComponentsHtmlScrubber.cs
ComponentsComponentsTransforms.cs