Archive

Archive for June, 2008

Setting Conditional Breakpoints in VS2008

June 17, 2008 Comments off

I subscribe to Sara Ford’s excellent Blog Visual Studio 2008 Tip of the Day.  I have to admit though, that I rarely use the tips.  They tend to be a little too deep in the mud for my tastes, although I will forever be grateful for her showing us how to change colors for things like Matching Braces.

Today, however, she has a great tip that you should probably read: how to set conditional breakpoints.

Categories: Visual Studio

First Foray into Unit Testing with Visual Studio 2008

June 12, 2008 12 comments

I’ve read about Unit Testing and Test Driven Development (TDD) but have never attempted to use it or even really understand it. I recently became intrigued by it watching Rob Conery’s excellent video series. Today I began putting the final touches on the Authorize.Net code I am going to release, so I thought this would be a good opportunity to try some testing.

I have never done any Unit Testing, and even though I wasn’t sure where to start, I figured it out pretty quickly. First things first, I added a Test Project to my solution. This created all the necessary framework code as one might expect. I deleted the default TestMethod and began adding TestMethods of my own, intuitively marked with the [TestMethod] attribute. A little Google hopping and I quickly learned about Assert.xxx() methods.

When it came time to actually run the tests, I was a little stumped. I read where you could right click the method name and execute “Run Tests”, but it seems to only run one at a time. In the test results window, there is a button for “Run All test”, but it too only ran the last executed test. Finally, I changed the Test project to my Solution Start Project, and pressing F5 to execute will run all the tests.

Here is the code from my first stab at it:

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DevelopingForDotNet.AuthorizeNet;

namespace TestAuthorizeNet
{
    ///
    /// Summary description for UnitTest1
    ///
    [TestClass]
    public class UnitTest1
    {
        public UnitTest1()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        private TestContext testContextInstance;

        ///
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        // Use TestInitialize to run code before running each test
        // [TestInitialize()]
        // public void MyTestInitialize() { }
        //
        // Use TestCleanup to run code after each test has run
        // [TestCleanup()]
        // public void MyTestCleanup() { }
        //
        #endregion

        [TestMethod]
        public void TestCreditCardNumberWithCharactersConvertedToJustNumbers()
        {
            TransactionRequestInfo req = new TransactionRequestInfo();
            string testValue = "1234-5678-9012-3456";
            req.CardNumber = testValue;
            Assert.AreEqual("1234567890123456", req.CardNumber);
        }

        [TestMethod]
        public void TestZipCodeNotNumericThrowsArgumentException()
        {
            TransactionRequestInfo req = new TransactionRequestInfo();
            string testValue = "034JB";
            try
            {
                req.Zip = testValue;
                Assert.Fail("Exception not thrown.");
            }
            catch (ArgumentException aex)
            {
                Assert.IsTrue(true, "Exception Thrown Properly");
            }
        }

        [TestMethod]
        public void TestZipCodeNumericButGreaterThan99999()
        {
            TransactionRequestInfo req = new TransactionRequestInfo();
            string testValue = "58634789";
            try
            {
                req.Zip = testValue;
                Assert.Fail("Exception not thrown.");
            }
            catch (ArgumentException aex)
            {
                Assert.IsTrue(true, "Exception Thrown Properly");
            }
        }

        [TestMethod]
        public void TestZipCodeValidReturnsLeadingZeros()
        {
            TransactionRequestInfo req = new TransactionRequestInfo();
            string testValue = "586";
            req.Zip = testValue;
            Assert.AreEqual("00586", req.Zip);
        }
    }
}

A few notes worth mentioning:

  1. I found a bunch of sites that talked about Testing in Visual Studio, about half and half claiming it was a good thing. What I did not find so readily was a good tutorial. I did finally come across a good post at http://www.geekzone.co.nz/vs2008/4819, a blog I had never visited before.
  2. What I have done so far would certainly not qualify as TDD, I’m just experimenting at this phase. I did, however, try to write tests that failed before correcting them to pass, but they were all on pre-existing methods.
  3. I tried to follow the “use long, descriptive test method names” rule.
  4. I need to understand mocking. Right now, I am creating full fledged class instances.
  5. It seems a tad slow. I can’t imagine what this would be like with hundreds of tests to run. I’m sure there are ways to handle this issue.

My plan is to include the test Project along with the entire Authorize.Net Solution. Whether it will be helpful or not, I don’t really know.

Updating from ASP.NET MVC Preview 2 to Preview 3

June 11, 2008 6 comments

I have been using Preview 3 since it was recently released, but only in a couple of test projects and in conjunction with learning more about my new found love: jQuery. This morning, I thought I would undergo the task of updating one of my “real” projects from Preview 2 to Preview 3. Unfortunately, it wasn’t as straight-forward as I had hoped, so I wanted to share the process with you.

Updating References

First things first: my project is set to automatically copy the DLL references to the Bin directory, so even though Preview 3 is installed on my machine, pre-existing projects have no knowledge of it. This was confirmed by trying to use the new View method to call a view page. This is actually pretty obvious and was expected.

To correct it, I first had to remove the References to System.Web.Abstractions, System.Web.Mvc, and System.Web.Routing. Maybe it is available but I just don’t know about it, but I was sort of surprised that there is not an “Update Reference” feature in VS.

Then I had to add references to their new versions, found in the “C:\Program Files\Microsoft ASP.NET\ASP.NET MVC Preview 3\Assemblies” directory (default install location: YMMV).

Finally, to ensure there was still no confusion, outside of Visual Studio I navigated to the Bin directory and deleted the previously copied DLLs. This may not be necessary, as I expect the IDE to properly detect that a different version is now in play and copy the new version over the old. Since I am not so optimistic, however, I went ahead and deleted them manually. The next Build properly copied in the updated DLLs.

Correcting Compiler Errors

At this point, the Solution would not compile for two reasons. First, RenderView no longer exists since it was replaced with the simpler View method. I’m sure that if this had been a Beta or RC that they would have provided a new RenderView that simply wrapped the new View method and returned null. This would have preserved backwards compatibility, but hey, as good as this stuff is it is still just a Preview level technology, so I can’t complain. Besides, I ultimately agree with their decision because it would be silly to retain a method you don’t want available in the final Release.

Now, if you have a lot of RenderView calls and are Find-And-Replace averse, you can add a simple local method to your Controller class to do just what I was suggesting:

private void RenderView(string viewName)
{
    View(viewName);
}

I did not do this, but I don’t see why it wouldn’t work. And of course, if you are using any more complicated signatures you’ll have to replicate them as well.

Second, all of the ViewPages that use a custom ViewData type, you have to change all the property calls to now reference ViewData.Model.xxx. I just let the compiler direct me to where I had done so and updated them manually.

After making these changes, the solution compiled successfully.

Updating Web.Config

And now for the part that wasn’t as straight-forward. Web.Config contains “Add Assembly” tags that hard code references the assembly names and PublicKeyTokens for several assemblies, including System.Web.Abstractions and System.Web.Routing assemblies mentioned above. At run-time, the assemblies could not be loaded. I’m not sure why the refence replacement did not update these, but I believe the PublicKeyTokens had been changed. To correct them, I opened the Web.Config of a working Preview 3 project and copied those two lines.

Running the site again produced a separate instance of the same error, this time in the HttpModules section trying to add “UrlRoutingModel”, so I copied the appropriate line from the new Web.Config to the old one. I went ahead and went through the entire Web.Config looking for references to any of the three DLLs in question and found a couple more which I also replaced.

The Dreaded Blank Page Issue

At this point, the Solution compiled, but trying to run the site produced a blank page. Unsure as to the cause, I copied the entire Web.config file contents over (retaining my custom mods, of course), but to no avail. If I typed in the full URL of the default {controller}/{action} the page threw an error, but at least that was progress! It turns out in the Index.aspx I was using the ViewData.ContainsDataElement(“key”) method, which no longer exists. I changed this to ViewData.Keys.Contains(“key”) and the page would now load. When I tried it again from the root, however, I still received a blank page.

I remembered having a frustration right after switching to Preview 3 that no matter what Routing I added, the Default would always go to the Home controller. I found the answer at the ASP.NET MVC Forums: in Preview 3, the Default.aspx Code Behind includes a hard-coded Response.Redirect(“~/Home”) in the Page_Load method. I changed it to my default Controller name and everything began to function as expected. Remembering this experience led me to wonder if the problem was somehow related to Default.aspx, which would produce a blank page if successfully called. I have a Routing that is supposed to address this that worked fine in Preview 2, but apparently it no longer functions in Preview 3. Anyway, to make a long story shorter, I was going to add this to the Default.aspx Code Behind only to find that there was no Code Behind file in Preview 2.

Not being an ASP.NET developer, I’m not sure what to think of this, and I did not know any other way to handle the problem. I deleted the original Default.aspx file and added a new Web Form to my Project. I replaced the default Designer Code and the relevant Code Behind code to match my successful Preview 3 Default.aspx file, and I also updated the Response.Redirect line to point to my desired Controller. Finally, all seems to have been returned to normal.

Conclusions

While it was frustrating to work through, in hindsight it wasn’t all that bad. The changes are pretty easy to implement, once you know where the traps lie. And the moral of the story is simple: this is Preview technology, expect breaking changes.

Categories: ASP.NET MVC

I'm Back!

June 6, 2008 Comments off

If you are (were?) a regular reader, I’m sure you’ve noticed that the site has been unavailable for a while. Long story short, our local power company decided to shut our power grid down one weekend for ‘upgrades’, and in the process my MySQL server suffered a catastrophic power spike. Both the power supply (easy to fix) and the mother board (not-so-easy and d*mned expensive to fix) were fried and the server never breathed again.

Are there a bunch of things I could have done to restore it? Yes. Did I want the site back? Mostly (more in a minute). Did I have the time to do it? No. Sort of like how the Contractor’s house is always in a state of disrepair, the developer’s site just wasn’t a priority. A friend of mine was messing around in here today and we were finally able to do the necessary work to get another install of MySQL running on a different server and import the database, and so as of today the site is back.

It’s hard to believe it, but it has been about 5 weeks since the site went down. I’ve had lots of adventures in that time, but most notably I’ve been very productive. I can only think that some of that was because I was not spending any time working on the site: no postings, no tracking, no blogging, etc. It was a nice little holiday, but I have to admit that I missed the outlet.

The Bad News

The bad news is that I know I lost some posts. Basically, anything written in April is gone. I think I had a couple of good posts about using Func<> to create local methods, but apparently my last backup was from before those were written. So if you find a bad link or can help me remember, maybe I’ll try to duplicate them.

ASP.NET MVC

My MVC adventures are moving on full bore. Preview 3 was released, and I am very happy with the updates. Last night I presented on MVC at RVNUG so I got to show off some of the recent goodies. I have two concurrent development efforts going on in MVC right now and will soon be adding a third. I’ve really been trying to dig into Routing, because I think my understanding of this core technology is lacking. I should be posting on this in the near future.

jQuery

I’ve done plenty of JavaScript in the past, but I’ve never employed a JavaScript library before now. I found out about jQuery while researching MVC and AJAX and let me tell you: I am WAY impressed! This is one awesome piece of software! I’ve spent a good bit of this week reading and playing with it and this is one tool that is definitely going in my bag of tricks.

I incorporated some of it into my presentation last night, which was part of a larger ASP.NET and AJAX group of presentations. What struck me most was that I actually find using jQuery for AJAX easier than the ASP.NET AJAX implementation. The code is certainly easier to read, and learning jQuery itself will add a lot more skill to my resume than just dropping an UpdatePanel. And we had a good discussion about how the term “AJAX” is frequently misapplied to more general DHTML rather than specific Server calls.

I’ll certainly be posting about using jQuery in MVC shortly.

My Laptop

I finally had a “Vista” moment, you know, the bad ones everyone talks about. I had previously installed the Beta of Vista SP1. Since the release version has been available for a while, on Friday I finally decided that I would upgrade. So I got on line, read the instructions, and followed the procedures. I uninstalled the beta (which took hours) and installed SP1. It cycled through all of its processes, the last of which is “Updating Configuration, Step 3 of 3”. This step completed and then entered Shut Down for like the 20th time. The problem is, it never came back.

I think now that this was because I was connected to my docking station and the prompts were sent to the wrong display – which was no longer visible – a mistake I’ll not repeat (more on this later). Since the machine would not come back, I restored the OS from a Rescue Disk. All seemed to be well, and I finished the week on a high note.

Unfortunately, Monday morning started on a low note: the machine would not start up. Instead, it was caught in some infinite loop between “updating configuration step 3 of 3” and Shut Down. It simply toggled back and forth between these two steps ad infinitum. I finally got the rescue disk back out and tried it again, which worked. I did a few things I had to get done, and then I rebooted: same problem. This tune was getting old quickly. So I tried the rescue trick one more time, except now the backups were no longer available. I was stuck with the “Restore to Factory Settings” option, which meant losing all data and applications. Not catastrophic, because I had backups, but annoying and time consuming.

And then the kicker: the rescue disk installed XP instead of Vista even though the machine’s “factory settings” were OEM Vista Business. Fortunately, I had an upgrade disk to Ultimate available through my Microsoft Action Pack subscription, so I installed that. I then spent most of Tuesday reconfiguring my system. And this is where the display issue comes in: because I was connected to the docking station during all of this, the default display for my machine is now the monitor, which Vista incorrectly set to 800×600 (instead of its 1600×1050 default). Worse yet, it would not offer me the correct resolution and Vista refused to install the driver from the disk that came with the monitor. Several Windows Updates and reboots later, and the device was finally recognized. I have now finally managed to get the settings corrected, although for my presentation last night it caused some issues with the projector, but we got through it.

Two final notes: the upgrade from XP to Vista seems to have wiped out the OEM FingerPrint reader software, so my T61 FingerPrint reader will not function. Also, there is an update that refuses to install because the system is missing files. And I thought “Ultimate” had everything.

Windows Live OneCare

In all this hubub, I lost my Norton 360 software and information, so I installed Windows Live OneCare instead, and so far I like it. It appears to be less resource intensive than 360 was and less intrusive. As of yet, I’m not subscribing, but I probably will eventually do so. I’d be happy to hear any of your experiences with the product.

So in conclusion, I’ve been busy busy busy, but I’m glad to be back amongst the living.

Categories: .NET

Too cool…Bloglines saves the day!

June 6, 2008 Comments off

So I noticed in my BlogLines page that the Feed for DevelopingFor was no longer showing. I guess after so long of being unavailable it automatically deleted it. So I clicked on the RSS Feed to subscribe, and lo-and-behold, the missing articles showed up! These were the articles that were written after the last backup, and a couple of good ones to boot.

So I am going to copy and paste them to repost. I cannot guarantee the quality as they are not entered properly through WordPress, but at least the general content should be recovered… if nothing else, it will be interesting to see how it turns out.

Posts marked with [REPOST] are ones that were done in this fashion. If anyone has linked to any of them, I’m sure the links will fail, but I may be able to recapture those thanks to WP 2.5’s Permalink editor. It will also take a little while to get all the categories straightened out, but overall I am very happy. Who knew?

[UPDATE] Amazing! Bloglines retained the entire HTML, so all the source code samples and all formatting was recaptured by simply copying it from their online feed!

[UPDATE 2] I was able to get all the old post permalinks reset, and I just wanted to share how to do it in case any of you find yourselves in this strange situation. Here are the steps (for each post):

  1. After creating the post and copy and pasting the contents, save the post (since this is the most important step we want to make sure it gets done)
  2. Go to the Bloglines feed and look at the link – this will tell you what the original Category was. Now go edit the Category on the post and Save the post.
  3. Click the Edit link next to the Permalink. Paste the link in from Bloglines. Remove the parts of the link up to and including the category and the “.html” suffix.
  4. Now, in order for this to take, you must press “Save” again!

And Viola, restored Permalinks.

Categories: This Site

[REPOST] – RVNUG May 2008

June 6, 2008 Comments off

Last night I attended the monthly RVNUG (Roanoke Valley .NET User’s Group) meeting. Kevin Hazzard gave a good presentation on Silverlight 2.0, which I have been eager to try. After what I saw last night, and now that I have a little experience with WPF, I am even more eager to give it a shot. What I am not eager to do is what I saw last night, and that is Silverlight development in Visual Studio. More specifically, I have no desire to hand code XAML, which is why I like Blend so much.

Today I’ll be downloading and installing the Silverlight 2.0 Beta 1 Tools, and I may install Blend 2.5 Preview (which I hear is far from rady for prime time). I’ll be putting together a couple Silverlight samples in the next week or so. If I come up with anything interesting, I’ll be sure to share it.

Categories: .NET 3.5

[REPOST] – Local Method Practical Example

June 6, 2008 1 comment

I recently wrote about the idea of using Generic Delegates to create Local Methods (methods wholly defined within the scope of another method). Today, I had a practical application for this technique so I wanted to share it.

In this example, our task is to build a portion of an SQL update string that contains only the fields within a class that have been changed. The class stores original values and current values, so finding the changed fields is a simple matter of comparison. We are going to use a StringBuilder to construct the string. The problem comes in properly appending a comma between each name-value pair string. You cannot always add one after adding a new string since it may be the last, so the solution is to check the length of the StringBuilder before appending the string: if it is greater than 0, then we append a comma first.

The task is simple enough, but what we end up with is a lot of redundant code:

StringBuilder updateString = new StringBuilder();
if (this.FIELD1 != this.o_FIELD1 )
{
updateString.Append( “FIELD1 = ‘” + this.FIELD1 + “’” );
}
if (updateString.Length > 0)
{
updateString.Append(“,”);
}
if (this.FIELD2 != this.o_FIELD2 )
{
updateString.Append( “FIELD2 = ‘” + this.FIELD2 + “’” );
}
if (updateString.Length > 0)
{
updateString.Append(“,”);
}
if (this.FIELD3 != this.o_FIELD3 )
{
updateString.Append( “FIELD3 = ‘” + this.FIELD3 + “’” );
}
if (updateString.Length > 0)
{
updateString.Append(“,”);
}
// Etc.

As you can see, this repeatedly defines the same behavior. It is especially aggravating when dealing with some of our legacy database tables that have hundreds of fields. While it may not be likely in this example, if we had to change this behavior it would be very tedious and some changes could easily be missed. This action is only relevant within the context of our Update method, so I really don’t want to outsource this to a private class method. Instead I will use a Generic Delegate to create a Local Method.

Since I am updating a local variable, I really don’t need to pass it: I’m going to take advantage of local variable access to reduce the parameter list and simplify the method signature. I do not need a return value, so I am going to use Action<T> to define a method that accepts a string and appends it to the StringBuilder and handles the commas as necessary. To ensure I can access the desired StringBuilder variable, I need to define it before defining my Local Method:

StringBuilder updateString = new StringBuilder();
Action AppendUpdateString = new Action(s =>
{
if (updateString.Length > 0)
{
updateString.Append(“,”);
}
updateString.Append(s);
});

Now, I simply call the method at each desired instance (also defined after the Local Method declaration):

if(this.FIELD1 != this.o_FIELD1 )
{
AppendUpdateString( “FIELD1 = ‘” + this.FIELD1 + “’” );
}
if (this.FIELD2 != this.o_FIELD2 )
{
AppendUpdateString( “FIELD2 = ‘” + this.FIELD2 + “’” );
}
if (this.FIELD3 != this.o_FIELD3 )
{
AppendUpdateString( “FIELD3 = ‘” + this.FIELD3 + “’” );
}
// Etc.

And this code could probably be simplified a little more, but I think this is adequate to the task. Hopefully, you’ll agree that this technique has merit. It’s very clean and easy to implement. I really like this, so much so that I am going to need to be careful to take my own advice and not go crazy with this approach.

Categories: .NET 3.5

[REPOST] – Deploying ASP.NET MVC on IIS6.0

June 6, 2008 2 comments

Last week, I finally got the ball rolling on our IIS server. With a little help from a friend, I managed to get the SSL Certificate installed. A quick tutorial, and the site was moved to the server but it would not respond. Monday, I managed to get the site to respond by installing the .NET 3.5 framework on the server and I mistakenly thought it was up and running, so I released it to the beta testers. Of course, immediately the testers informed me that only the home page was showing, while all other links returned a 404 message.

I went through several efforts and can now happily say that it does work, so I am officially saying it is deployed. It is far from finished, but it is live on the web (sorry, I can’t share the address at this time). Here are the steps I followed that got it running:

  1. Install .Net Framework 3.5 on IIS Server
  2. Change Route URLs in Global.aspx.cs to include the .mvc extension (this is in the comments for that file)
  3. Install ASP.NET MVC Preview 2 on the IIS Server.
  4. Add an ISAPI extension to the application for .mvc that points to “c:\windows\microsoft.net\framework\v2.0.50727\aspnet_isapi.dll”.
  5. Uncheck the “Verify that file exists” box on the Extensions configuration dialog.

The last one is what finally made all the pieces fall into place. I don’t know if it is a “DUH” sort of a thing, but you have to remember that I am not an IIS or ASP.NET guy.

I found information on all but the last entry scattered across the web. Hopefully by putting them all in one place it will help some poor wayward soul in the future. According to those resources, these steps should also work for IIS7 in classic mode (integration mode? are those the same?) but should be unnecessary in the default IIS7 configuration.

At any rate, it lives!

Categories: ASP.NET MVC

[REPOST] – Geeking on a Saturday

June 6, 2008 Comments off

In a recent post entitled I am a Professional Geek, I mentioned that I only geek at work. Well, Saturday I had the opportunity to prove just how deep that particular Rabbit hole goes… I gave a presentation on .NET 3.5 Language Enhancements at the Richmond Code Camp Saturday morning, and boy did I stink! I really had trouble focusing my message and expressing myself. I was live coding and kept screwing up the syntax (to those attending, I was missing the delegate keyword on the Local Methods demonstration). We have a tendency to judge ourselves harshly, so I can only hope that the attendees didn’t think it went as poorly as I felt.

I guess every one has off days: Babe Ruth struck out a lot and Edison found 2,000 ways not to make a light bulb. Even Einstein stank up the joint on occasion (read about “The Ether” sometime). Not that I am Einstein, Edison, or Ruth: clearly I’m not. But I believe it is important to give ourselves these pep talks when we mess up. Let’s face it: as programmers, we mess up a lot!

So what’s the lesson? For me it is that weekends and technology don’t mix. Hopefully I can redeem myself in June when I will be presenting at RVNUG on ASP.NET MVC. At least that is during the week!

Categories: Miscellaneous

[REPOST] – Of Mice and Men(tors)

June 6, 2008 Comments off

Just a weekly update…

When I bought this machine, I picked up a new wireless mouse and keyboard. About a week ago, I noticed that my mouse had a flashing red light on it. I had never seen it before, and I quickly realized that this is a battery low indicator light. I had mixed feelings about this. First, I appreciate the notice, because there is nothing more frustrating than being deep in the zone and the mouse or keyboard runs out of power. But when I got to thinking about it, I thought that in a way it is foolish. Just when the power is getting low, you add an additional energy draw by powering a flashing light! I even went around the office showing everyone and commenting about how dumb it was. I likened it to the bank drawing an overdraft charge when you bounce a check. Hello! The problem is there is no money in there in the first place! <sheesh>

Well, today it finally died… right in the middle of a great coding session. Naturally, I was annoyed, both at the interruption and (sheepishly) at the realization that I should have obeyed the warning and replaced the stinking batteries. But I did learn two things: first, the light flashed for over a week before the batteries finally died, and second I learned that the mouse will function on a single battery (which I discovered when I was replacing the batteries). Interesting.

On the Mentor side (to make the title work), I will be giving my “.NET 3.5 Language Enhancements” presentation tomorrow morning at the Richmond Code Camp. Unfortunately I’ll be driving in and immediately driving out and will miss some of the presentations I would like to see. If you see me there, mention the blog and say hello.

Categories: Miscellaneous