This Was Probably Sheer Luck ...

by Randall 7/31/2008 1:11:00 PM

I just spent part of two days battling an exception while waiting on a response from a web service. 

    ---> System.Net.WebException: The server committed a protocol violation. Section=ResponseStatusLine at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest     request)

   at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)

   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) 

I found all sorts of suggestions to fix the issue.  Most of them involved adding the following information to your web.config:

    <system.net>
        <settings>
            <httpWebRequest useUnsafeHeaderParsing="true" />
        </settings>
    </system.net> 

No luck.

I even found a post that suggested you override the WebRequest method within your proxy class (seems like a bad idea because if you ever regenerate your proxy class ... well, you know what'll happen to your "fix").

protected override WebRequest GetWebRequest(Uri uri)
{
     HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);

     request.ProtocolVersion = HttpVersion.Version10;

     return request;
} 

Anyway, after neither of those solutions had worked, my Google resources were running low.  I kept noticing that all of the posts mentioned .Net 1.1 ...

So I changed the webservice to use 2.0 (this is a COTS product and installs to 1.1 by default) and voila.  No more nasty gram.

Perhaps this will help someone.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Fixes

String.Format Shortcut

by Randall 6/24/2008 5:19:00 PM

Well, I feel like I have totally missed the boat on something.

I love using string.Format() in order to construct messages and other things that need to be written to the console, etc.  For example:

    string msg = string.Format("I can't believe it's {0} already!", DateTime.Now.Date.ToShortDateString());
  Console.WriteLine(msg);

Anyway.  I just learned that the line above can be written as:

    Console.WriteLine("I can't believe it's {0} already!", DateTime.Now.Date.ToShortDateString());

Seems as if the compiler can determine that you're formatting a string and will infer the string.Format() function.

Too bad it can't infer the following:

    string msg = "I can't believe it's {0} already!", DateTime.Now.Date.ToShortDateString();

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Getting Started With TestDriven.Net PlugIn & Unit Testing With NUnit Tutorial

by Randall 6/18/2008 10:42:00 AM

(You can download a Word version of this tutorial here.) 

In case you've been using NUnit (or some other testing framework) and NCover as stand-alone applications, you need to check out a plug-in for Visual Studio 2005/2008 called TestDriven.Net.

For those of you who have yet to even get started with Unit Testing - let's take a small project, create some unit tests, and show how this plug-in (along with NUnit and NCover) can increase the quality of your code.

*Disclaimer*  This demo will not implement the TDD methodology.  There is another school of thought that says you write a test before writing any code.  However, the purpose of this entry is to show you how easy it is to get started with unit testing.  How you choose to apply it to your projects will, of course, be left to you.  Furthermore, in-line SQL is used in this demo for purposes of simplicity and the connection string is embedded in the code.  Of course you'd ALWAYS want to put the connection string in your App.config or Web.config.  You know that.

Source code for the example project is located here (without the unit tests if you'd like to complete them youself) and the fully completed source code is available here.  The script for generating the single table is here - you'll simply need to create a database called 'DogsDB' and update your connection string.  I've marked the location of the connection string with a 'TODO' comment.  You can find that by looking in Visual Studio's Task List (hit CTL+T).

Dogs Application

So we have this little application that will allow us to manage all of the dogs in a kennel (or whatever).  We have all of our code in-place that will perform the normal CRUD operations and provide functionality to the UI.  How do we know that it will work?  I suppose before I stated doing unit testing I would simply have hooked in whatever user controls I needed and ran the application.  For really simple projects (such as this one) yes, that can work.  However, when you begin working on large-scale applications and creating very large APIs that will break other applications when they fail - unit testing will save your a$$.

At this point we'll be working with the unfinished sample.

If you haven't downloaded NUnit yet, you'll need to do that before going to the next step.  You can download it here

Let's add a new project to our solution - a class library - and call it 'UnitTestingDemo.UnitTests'.  This will be the container for all of our unit tests. 

 At this point, we'll need to add a reference to the NUnit framework.  So go ahead and add the reference - you'll find the asembly under the .Net tab of the 'Add Reference' dialog. 

Now we want to start writing tests for our business layer.  You could write tests that touched your DAL directly, but theoretically your BLL should expose all of your DAL.  However, if there are private methods within your DAL, you'll need to write tests to address those issues.  For this example, we'll just be testing the public layer which is in the BLL.

Let's go ahead and stub out our tests based on what's in the BLL.

In the project we just created, rename Class1.cs to DogLayerTests.cs and add a using statement for NUnit.Framework.  Your class should now look like this ... 

We want to base all of our tests on what's in our BLL.  One of the easiest ways to do this is to simply copy & paste our BLL methods into our test class. 

  1. remove all of the code from within each method
  2. rename each method to reflect that it's a test (add '_Test' to the end of each method's name)
  3. change every return type to void
  4. remove all parameters from each method's signature

When you're done, DogLayerTests should look like this ...

 

In order for NUnit to know that you want this class and its methods to constitute a suite of tests, you must 'decorate' the class and its methods with a couple of attributes.  At the class level, NUnit expects the [TestFixture] decorator and the [Test] decorator at the method level.  Go ahead and add those now.  Your code should now look like this ...

(If you don't see [Test] and [TestFixture] in IntelliSense, you either forgot to add the assembly reference to NUnit.Framework or you forgot to add the using for the namespace.) 

  Since we're starting with an empty database, the first thing we probably want to test is the ability to save a dog to the database.  Since NUnit will run your tests in alphabetical order, you can simply rename your methods numerically to fix that issue.  However, I think by definition each unit test should be able to run without any dependencies on other tests.  But if the database is empty, and you can't guarantee there will be any data to load, I'm not sure what else we can do.

I want to conduct my tests in the following order: Save, Get, Get All, Delete.  I'll letter my tests accordingly using A, B, C, & D as prefixes on the method names. 

Let's go ahead and write the test code for A_Dog_Save_Test.  We'll need to add two project references, one for the BLL and another for the Data Objects.  Do this and add your using statements for both namespaces. Because we're using the Color object in the System.Drawing namespace, you'll also need to add a reference to System.Drawing in your UnitTests project.  Go ahead and do that now also.

Once we start coding our test for the Save functionality, we can see that within that test, we'd like to have a way to verifiy that the object was saved.  Yes, the method itself will return a bool value, but we still want to know.  Based on that observation, we'll make the newly-created Dog a private member within the class so that other methods can perform tests based on it.

    [TestFixture]
    public class DogLayerTests
    {

        private DogLayer _dogLayer = new DogLayer();
        private Dog _dog = null;

        [Test]
        public void A_Dog_Save_Test()
        {

            this._dog = new Dog();
            this._dog.Id = System.Guid.NewGuid();
            this._dog.Name = "Fido";
            this._dog.Breed = "Mutt";
            this._dog.HairColor = System.Drawing.Color.Brown;
            this._dog.Age = 7;

            Assert.That(this._dogLayer.Dog_Save(this._dog) == true);

        }

    ...

    } 

We want all of the other tests to fail since they don't contain any code.  In order to make that work, insert the following into each of the remaining test methods.

Assert.That(true == false);

This will force the rest of our tests to fail; this is desirable. 

Now we'd like to run our test in order to determine if everything is working.  Since you have NUnit now, you can run your tests.  However, this article is about working with the TestDriven.Net plug-in, so you'll need to download that now.  You can download it here.  (Don't forget to save your solution and exit Visual Studio prior to running the installer.)  Once you have completed the installation, re-open the solution and continue.

Right-click on your test class and select 'Run Tests'. (We'll explore some of the other menu items later.)

 Your test will fail (there's an error that we'll flush out next). 

Debugging Using the Test Driven .Net Plug-In

Since our test failed and we have a bug, we want to be able to step through our test just like we'd normally step through using the debugger.  In order to do this, place a breakpoint at the test's call to the Save method.  Right-click on the test project again, but this time select 'Test With --> Debugger'.  You can now step into your code - eventually you'll find that we're missing a closing paren in our SQL insert statement.

Change

sb.AppendLine(string.Format("'{0}',", value.HairColor));

to

sb.AppendLine(string.Format("'{0}')", value.HairColor)); 


Re-run your tests.  The Save test will now pass and you'll see this in the Output window ... 

Congratulations.  You have just written your first unit test.

For the sake of brevity (too late, I know) here's the code for the rest of the test methods:

(Note that I have added more code in the first test to create multiple dogs which will be loaded by the Dogs_Get() test)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using NUnit.Framework;

using UnitTestingDemo.DataObjects;
using UnitTestingDemo.BLL;

namespace UnitTestingDemo.UnitTests
{

    [TestFixture]
    public class DogLayerTests
    {

        private DogLayer _dogLayer = new DogLayer();
        private Dog _dog = null;

        [Test]
        public void A_Dog_Save_Test()
        {

            this._dog = new Dog();
            this._dog.Id = System.Guid.NewGuid();
            this._dog.Name = "Fido";
            this._dog.Breed = "Mutt";
            this._dog.HairColor = System.Drawing.Color.Brown;
            this._dog.Age = 7;

            Assert.That(this._dogLayer.Dog_Save(this._dog) == true);

            // create 5 dogs and save them all
            for (int i = 0; i < 5; i++)
            {
                Dog tempDog = new Dog();
                tempDog.Id = System.Guid.NewGuid();
                tempDog.Name = string.Format("Name{0}", i.ToString());
                tempDog.Breed = string.Format("Breed{0}", i.ToString());
                tempDog.HairColor = System.Drawing.Color.Brown;
                tempDog.Age = i;

                Assert.That(this._dogLayer.Dog_Save(tempDog) == true);

            }

        }

        [Test]
        public void B_Dog_Get_Test()
        {

            Assert.That(this._dog != null);

            // attempt to retrieve the dog to ensure that it was saved ...
            Dog tempDog = this._dogLayer.Dog_Get(this._dog.Id);

            Assert.That(tempDog != null);

            // check as many properties as you'd like
            Assert.That(this._dog.Name == tempDog.Name);
            Assert.That(this._dog.Breed == tempDog.Breed);

        }

        [Test]
        public void C_Dogs_Get_Test()
        {
            List<Dog> dogs = this._dogLayer.Dogs_Get();
            Assert.That(dogs != null);
            Assert.That(dogs.Count > 0);
        }

        [Test]
        public void D_Dog_Delete_Test()
        {
            // get all of the dogs in the database
            List<Dog> dogs = this._dogLayer.Dogs_Get();
            Assert.That(dogs != null);
            Assert.That(dogs.Count > 0);

            // delete all of them
            foreach (Dog dog in dogs)
            {
                // delete the dog
                Assert.That(this._dogLayer.Dog_Delete(dog.Id) == true);

                // attempt to load the dog - it should fail (return null)
                Assert.That(this._dogLayer.Dog_Get(dog.Id) == null);
            }

        }

    }

}

Run your tests again.  Oh no.  Another bug (actually two within the same method).  This time I'll leave it up to you to decipher - but it's in the DAL. ;) (*Hint* Make sure your reader has rows before attempting to read from it and ensure that method will always return a value.)

Now that all of our tests have passed with flying colors, we're good to go, right?  Well yes and no.  Yes all of our tests passed, but how much of our code did we test?  Are we testing everything that will get called during its use?  This brings us to the next part.

Verifying Test Coverage With NCover

NCover is a code-coverage tool that is available as a stand-alone product but which is also packaged with the Test Driven .Net plug-in you downloaded earlier.  What exactly is code-coverage you ask?  Well, it's just a way of showing you whether or not your lines of code were actually used based on the tests you have written.  NCover will show you line-by-line what code was 'touched' and even provide a percentage of the lines of code within a method that were used by your test.  Determining the 'correct' percentage of appropriate code coverage is an entirely difference discussion on its own, but I attempt to get 100% coverage within my business and data access layers.  Some things, such as your data objects, might not get 100% coverage.  What is and isn't a good level of coverage will be left for you to research and determine.

Let's get started.

Since all of our tests passed, let's determine how good of a job we did in contructing our test classes (based on code coverage).  Right-click on your test project and select 'Test With --> Coverage'.  

NUnit will run the tests, then NCover will launch and show you the results. 

Looks pretty good, right?  I mean we have 100% in our business layer.  Remember though that this BLL isn't really doing anything in this application - it's really acting as a pass-through to our DAL.  Speaking of - we only have 29% coverage there.  Let's take a look and see what the problem is.

Looks like our BaseDal is skewing our results.  If you're like I am, you have a generic SQL base DAL from which all of your other object-specific DALs inherit.  This class should have been tested within some other solution (as a matter of fact, it was).  Since we've already unit tested that class in another test suite, we'll focus our efforts on obtaining 100% coverage within our DogDal.

Looks like everything is at 100% except for the Dog_Save method.  Let's take a look and see what the issue is ... 

Well, look at that.  We never attempted to update a previously-existing dog.  How do we know?  The red lines of code were never touched.  If you think back to our tests, we only saved new dogs - we never updated any of them.

While we thought we were ok because all of our tests passed, it's clearly evident now that we didn't do the best job we could when writing our tests.  This is why these tools are invaluable - because we all make mistakes.  True, our update method probably works - but you need to adopt the attitude of 'I want to KNOW that it works'.  Never assume anything, as you know. 

Let's go back and fix our tests.  In the first test where we were saving new dogs, let's add a few more lines of code that will update each of the dogs we just created and saved.  Your test method A_Dog_Save_Test should now look like this ...

        [Test]
        public void A_Dog_Save_Test()
        {

            this._dog = new Dog();
            this._dog.Id = System.Guid.NewGuid();
            this._dog.Name = "Fido";
            this._dog.Breed = "Mutt";
            this._dog.HairColor = System.Drawing.Color.Brown;
            this._dog.Age = 7;

            Assert.That(this._dogLayer.Dog_Save(this._dog) == true);

            // create 5 dogs and save them all
            List<Dog> dogs = new List<Dog>();
            for (int i = 0; i < 5; i++)
            {
                Dog tempDog = new Dog();
                tempDog.Id = System.Guid.NewGuid();
                tempDog.Name = string.Format("Name{0}", i.ToString());
                tempDog.Breed = string.Format("Breed{0}", i.ToString());
                tempDog.HairColor = System.Drawing.Color.Brown;
                tempDog.Age = i;

                Assert.That(this._dogLayer.Dog_Save(tempDog) == true);

                dogs.Add(tempDog);

            }

            // update all 5 of the newly-created dogs
            foreach (Dog dog in dogs)
            {
                dog.Name = string.Format("{0}_Updated", dog.Name);
                // save the dog - this will be an update now
                Assert.That(this._dogLayer.Dog_Save(dog) == true);
            }

        }

Re-run all of your tests using NCover as we just did.  They should all pass and NCover will show you the new results.  Drill down into the DogDal and look at the code coverage percentage ... 

Congratulations.  You now have 100% code coverage within your DogDal.  This is what we wanted.

Wrap-Up

While writing your unit tests, running them, fixing them, analyzing your code coverage, and adjusting your tests all takes time - the benefit in the long run will blow your mind.  As the weeks progress and you become more removed from the code you just wrote, having a series of tests to run will provide some much-needed peace of mind.  Developing software is tough enough without worrying about breaking code that you have previously written.

With that being said, I challenge you on your next project (or even your existing project(s) to implement unit testing.  It will change the way you develop software.  Frankly I don't know how I called myself a 'professional' developer before I began doing this.


kick it on DotNetKicks.com

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , ,

Tips for Writing Tutorials

by Randall 6/5/2008 12:38:00 PM

I'm finally digging into Windows Workflow Foundation so I decided to try some tutorials. (Yes, I am fully aware that it's been out there for over a year and a half now.)

I know that CodeProject has a good reputation and occassionally I have found good resources there.  However, for the most part, the tutorials that are placed there are utter garbage.  Instead of hurrying to get something out there so you can say you've been 'published', take some time and follow these suggestions. 

  • DO use correct grammar and spelling.  If you are not a native English speaker, then find someone who is to proof your submittal.
  • DON'T tell the reader to 'copy & paste' your code.  Do explain to them WHY you are doing it.
  • DO be sure and point out any references that you're using so the reader can be sure to use the proper 'Includes {namespace]}'.  The reader is trying to learn something; you're trying to help them - so help them.
I'm certainly not an expert on tutorial writing - just a consumer of them.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Oracle Sucks

by Randall 6/4/2008 3:42:00 PM

Yes, this is going to be a rant.

Today I attempted to deploy a Windows service to a server.  It failed.  When I started thinking about it, I realized that my service was trying to connect to an Oracle datasource.

Guess what?  Client connectivity components weren't installed.  For those of you who are unfamiliar with Oracle, here's the crux: In order to get your code working with Oracle (even when your connection string is correct), you must do the following:

  • Install Oracle (xx)  Client on the system
  • Configure your TNSNAMES.ORA
  • Create a System DSN for the database

Voila!  That's it!  Presto!

Now compare that to SQL Server.

  • Include a connection string in your App.config

Notice a difference here?

I used to think that Microsoft had the worst organized site of all the major companies, but they have been outdone by Oracle.  Go ahead.  Take a look around Oracle's website and try to find the Oracle10g Client download.  I dare you.  Tell me how long it takes. 

In case you need it for some reason, you can find it here.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

New Blog Platform

by Randall 6/3/2008 6:20:00 PM

I recently migrated away from GoDaddy and began hosting my own blog.  I've chosen BlogEngine.NET as my new platform.  So far, so good.

And yes, this is actually running on a machine in my house. Cool

Currently rated 3.0 by 1 people

  • Currently 3/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Arrival at TechEd 2007

by Randall 6/3/2007 9:06:00 PM

Well, Alan, Geff, and I arrived in Orlando about 8:15 this morning.  We went to check in for TechEd and were provided with a whole load of goodies...

  • A very nice laptop backpack
  • Microsoft Business Intelligence Resource Kit
  • Intel Enterprise Resource Kit for Microsoft Solutions
  • Windows Server 2008 (Longhorn) 32-bit Beta 3 Kit
  • Windows Mobile 6.0 Developer Resource Kit
  • Windows Server 2008 (Longhorn) Beta 3 Resources
  • Microsoft Forefront
  • Microsoft System Center
  • Visual Studio Industry Partner Program Partner Resource CD
  • Microsoft Security Assessment Tool
  • Office 2007 Sharepoint Server 2007 Technical Resource DVD
  • Windows Server Virtualization Resource DVD

Here are some pics from the trip...

Geff catching some zzzs on the plane ...

Alan's big goofy grin ...

Alan and Geff inside the Orlando airport - the place was a monster!

One of the MANY signs within the airport welcoming TechEd 2007 guests ...

The view from Geff's balcony ...

 

TechEd doesn't actually start until tomorrow.  Keep checking - should be lots of good stuff coming for WF and WCF.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

Abstracting Your Dalc

by Randall 3/23/2007 3:24:00 PM
For quite some time now I've been using a Base DALC from which all of my object-specific dalcs inherit.  I found it tedious to code the same old ADO.Net commands for every CRUD operation I need to implement.

For example, when I want to load a list of foo objects, in my foo dalc I simply do something like this:

...

    public FooList FooList_Get(Guid id) {
    
        SortedList paramList = new SortedList();
        paramList.Add("uiFooListId", uiFooListId);
    
        SqlDataReader drdDb = base.GetDataReader("some stored proc name", SortedList);
    
        //enumerate your reader
    
        //close it
    
    }
    
...

My base dalc call methods looks like this:

    /// <summary>
    /// Executes a stored and returns the results as a SqlDataReader.
    /// Paramlist is the parameters in form of (key=paramName;value=paramValue).
    /// <summary>
    /// <param name="storedProcName"></param>
    /// <param name="paramList"></param>
    /// <returns></returns>
    /// <remarks>Notice that a sorted list is used instead of an actual parameter collection.
    /// This is done in case the database provider ever changes, you won't break any inherited classes.
    /// </remarks>
    public SqlDataReader OpenDataReader(string storedProcName, SortedList paramList)
    {
    
        SqlConnection cnnSql = null;
        SqlCommand cmdSql = null;
        SqlDataReader drdSql = null;
        IDictionaryEnumerator enmParam = null;
    
        try
        {
    
            //set-up the connection object
            cnnSql = new SqlConnection(this.ConnectionString);
    
            //set-up the command object
            cmdSql = new SqlCommand();
            cmdSql.CommandText = storedProcName;
            cmdSql.Connection = cnnSql;
            cmdSql.CommandTimeout = 3000;
            cmdSql.CommandType = CommandType.StoredProcedure;
    
            //add the parameters
            enmParam = paramList.GetEnumerator();
            while (enmParam.MoveNext())
            {
                cmdSql.Parameters.Add(new SqlParameter((string)enmParam.Key, enmParam.Value));
            }
    
            //open the connection
            cnnSql.Open();
    
            //get the reader
            drdSql = cmdSql.ExecuteReader(CommandBehavior.CloseConnection);
    
            return drdSql;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    
    }


Can you see the benefits of doing this?  I initially did it because, well, I'm lazy and I don't like repeating the same code everywhere.  However, while reviewing someone's code yesterday, another reason appeared for encapsulating your ADO.Net commands.

I recently inherited an application from a developer who left our company.  I needed to track some logic within the code - specifically the order in which stored procedures were called within the application.  I had to search through the dalc and place a debug statement within each call.  Had the dalc operations been encapsulated into a base class, I would have had to place debug statements in only one location - yup, you guessed it, the base dalc.

So, it turns out that being lazy can also be a good practice.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Determine the Number of Lines Within a StringBuilder

by Randall 3/21/2007 1:52:00 AM
Today I was faced with the need to determine the number of lines within a StringBuilder instance.  If I had needed the length of the string contained within the StringBuilder, that would have been a trivial task.

After perusing MSDN, I was unable to find a property or method of the StringBuilder class that provided the needed behaviour.  You would think that this would be accessible via something like StringBuilder.Lines.Count, but no luck.

So, I figured out a hack of sorts.  If you first create a text box control (within code), you can determine the line count from the control.

...

private int GetLineCount(StringBuilder sb)
{

    TextBox ctl = new TextBox();
    ctl.Text = sb.ToString();

    int lineCount = 0;

    foreach (String s in ctl.Lines)
    {
       lineCount++;
    }

    return lineCount;

}

...

Voila! The number of lines within a StringBuilder.  If anyone happens to know the 'correct' way of doing this from within the framework, please let me know.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: ,

First Entry

by Randall 3/20/2007 2:28:00 AM
So today I enter the world of blogging.  'Why?' you may ask.

Let me answer that.   As a developer (a lazy one at that), quite often I am faced with problems that someone else has already encountered, solved, and graciously posted the solution so that others can be saved the same time-sink.

That's why.

I'm now in my 7th year of development and it's time that I begin returning to the developer community at least a small percentage of what I've taken.

I hope that you'll find something here that will help you in your quest to become a lazy codeslinger yourself.

By the way, when I say 'lazy', I don't literally mean lazy.  I mean lazy in the sense that I prefer to work smarter, not harder.  So, within my blog you'll find information about useful timesavers like Reflection and Code Generators.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Powered by BlogEngine.NET 1.3.1.0
Theme by Mads Kristensen

About the author

Name of author Randall Sexton
Currently a .Net developer for Bechtel Corporation in Oak Ridge, TN.

E-mail me Send mail

Calendar

<<  October 2008  >>
MoTuWeThFrSaSu
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

View posts in large calendar

Recent comments

Don't show

Authors

Categories


Logo Credit

My logo was taken from CodingHorror.
Jeff Atwood © Copyright 2007

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008

Sign in