A simple asp:Repeater replacement for simple needs

How many times have you had to parse through a collection of objects, outputting nothing more than a comma-delimited list of items in the result set. Typically, you’ll do this:

<asp :repeater runat="server">
	<separatortemplate>, </separatortemplate>

If you were parsing a list of states, it might look like this:

Alabama, Alaska, Arizona, Arkansas

There’s an easier way to handle these simple needs: create a CollectionToString() method. This method would accept an IEnumerable and, using reflection, read a property and return a delimited string. Of course, you choose the property and delimiter.

Note that we have two versions of this method: one which accepts an IEnumerable, the other which accepts an object. This is done to avoid the necessary typecasting in your code, since Eval() returns everything as an object.

public static string CollectionToString(IEnumerable collection, string property, string delimiter)
	IEnumerator enumerator = collection.GetEnumerator();
	if (enumerator == null || enumerator.MoveNext() == false)
		return String.Empty;

	Type type = enumerator.Current.GetType();
	PropertyInfo propInfo = type.GetProperty(property);
	if (propInfo == null)
		throw new Exception(String.Format("Property '{0}' not found in collection", property));

	StringBuilder output = new StringBuilder();
	output.Append(propInfo.GetValue(enumerator.Current, null).ToString());

	while (enumerator.MoveNext())
		output.Append(propInfo.GetValue(enumerator.Current, null).ToString());

	return output.ToString();

public static string CollectionToString(object collection, string property, string delimiter)
	return CollectionToString(collection as IEnumerable, property, delimiter);

This method — which I typically apply to a StringHelper class whose namespace is added to my web.config (more on that another day) — can replace the Repeater code above as follows.

<!-- you must first expose the collection to the ASPX page as a public property -->
< %= StringHelper.CollectionToString("ListOfStates", "Name", ", ") %>

A similar method could be added to a helper class in Castle MonoRail to do the same without using foreach loops in your view.

Installing Systems Center Essentials fails: “The specified domain does not exist or cannot be contacted.”

I’m trying to evaluate Microsoft’s Systems Center Essentials 2007. I say “trying” because every time I install it, I get an error in the setup log file.

The specified domain does not exist or cannot be contacted.

This makes no sense, because I’m logged in with a domain administrator account and the setup program is validating the domain-level service account. What gives? After two failed tries, I searched Microsoft’s web site, and I found this:

(KB 937831) The installation of System Center Essentials 2007 fails during the Reporting part of Setup and the following information is logged: “The specified domain does not exist or cannot be contacted”
– Fixes a problem that occurs if the computer’s NetBIOS domain name does not match the domain or if the computer’s domain suffix does not match the domain.

There’s a hotfix for the setup program (go figure) that fixes the problem. Unfortunately, the symptom (NetBIOS name discrepancies) is not the case in my situation, but the error message is the same. I tried applying the hotfix, and — guess what — SCE installed successfully.

Here’s the oddest part of it all. Why doesn’t Microsoft pre-apply the hotfix to the evaluation installer that they make available on their web site?

A day in the life (of me)

While trying to reduce the number of unread items in Google Reader to a sub-200 number, I came across AgileJoe‘s post, “Curious, What does your day look like?

Well, here’s my typical day:

  • 5:00AM: Wake up! I sleep with my alarm clock under my pillow so as to not wake up anyone else in the house.
  • 5:45AM: Showered and dressed (I get my stuff ready the night before to avoid turning on lights and making too much noise), I get in my car and drive to work.
  • ~7:00AM: Arrive at work. (Yes, the drive takes between 60 and 75 minutes.)
  • 7:00AM to 4:00PM: Work work work (I rarely get out at my scheduled 3:00PM).
  • 4:00PM: Drive home, hoping for the best.
  • 5:30PM: Get home (usually 60-90 minutes getting home) and spend time with my family.
  • 6:30PM: Dinner!
  • 7:30PM: Give my daughter a bath (I refuse to let anyone else do it whenever I’m home).
  • 8:30PM: Daughter gets ready for bed, and I read her books, tell her a story, sing her a song, and turn out the lights.
  • by 9:30PM: Finally able to settle down and do my own thing, which usually entails working on CSFBL, doing some side work, or playing a little World of Warcraft.
  • 11:00PM (or so): Go to bed. Rarely earlier, sometimes later (like last night, when I went to bed at 11:45PM).

And yes, your math is correct: I get between 5 and 6 hours sleep a night.

Defeating WebSense

I have two laptops (one personal, one work) and one home desktop PC. It would be nice to have some files synchronized between them all. I already use Mozy to back up my personal laptop, but that doesn’t address synchronization issues.

I wanted a web-based solution (similar to Mozy), so I did a quick Google search to see what my options were. The first item in the list was FolderShare (by Microsoft), so I figured I’d check it out. I went to http://www.foldershare.com Here’s what I saw:

Blocked by WebSense

Damn… Well, not a big deal. Since I’m a sys admin here, I can just configure WebSense to ignore requests from my IP address. Before I did that, I tried changing the URL to https://www.foldershare.com.

And guess what? It worked!

Apparently, WebSense sees an SSL site as different from the non-SSL site. I have no idea if this is an oversight just for FolderShare, or some weird configuration thing here, or something related to the version of WebSense we’re running… but it is interesting to know that such a simple workaround exists.

Anyway, I’ll be testing FolderShare now — and will blog about that in due time.

Goodbye, old friend

It was the first day of spring, 1994, when I adopted you into my family. For the next thirteen years, we were there for each other through good times and bad. Through it all, you never complained; all you wanted was to be accepted as part of the family — and in every way, you were just that.

Of course, I’m talking about my dog, Thea. To say she was a good dog is an understatement. She epitomized what a best friend is: loyal, reliable, unwavering in her commitment. She was in all ways a people dog: she was a bully around other dogs, and adored every human who crossed her path. She was a healthy, happy, active, youthful dog for a long time. Even when she was 11 years old, people would think she was a puppy.

Everything changed a year ago, when her health started to deteriorate quickly—the result of a degenerative spinal disorder. We knew then that it was a matter of time, and on October 4, 2007, that time came to an end.

Putting down a dog that is a part of your life for so long is hard; hard enough for me that I’ve rewritten this blog post three times in the past week trying to get it right. Words can’t describe what it’s like to hold your beloved family dog’s paw in your hand, petting her ears, in her final moments. I wish it ended some way other than it did, but I’m glad it ended how it did; she was comfortable, with the person she loved most. It’s hard saying goodbye; instead, I’ll say, “until we meet again.”

Thanks for everything, old friend. You’ll be missed.

Thea, my dog
Thea DeMarzo, Jan 13 1994—Oct 4, 2007

Continue reading

Verizon, where’s the customer service?

When I got home last night, I found out that I have no phone service. I did the usual — unplugged all phones, made sure everything was on the hook, checked for a dial tone using an old analog phone — and there was still no dial tone. Calling my home phone number from a cell phone resulted in ring, ring, ring… Time to call Verizon support.

After a few misdirections through the automated call screening process, I finally spoke to a human being who was able to resolve the problem. I was told a technician would come out between 2PM and 6PM the next day to troubleshoot.

The next day (which is the day I’m writing this), I received a voice mail message at a little before 2PM. It was an automated message that said something akin to this…

Hello, George… We are confirming your appointment today between 2PM and 6PM at xxyy Carlton Blvd…

Two things concerned me about this message. First, my name is Brian, not George. Second, I don’t live on Carlton Blvd (which is a block away from where I live). Sensing problems, I called Verizon to get some clarification. Continue reading

Dvorak, ye shalt not throw stones

PC Magazine author John C. Dvorak, whose work I enjoy thoroughly, threw the proverbial boomerang stone today in his column AJAX and the Road to Bad Web Sites, where he criticized a web site:

Holy crap! The Web site usctrojans.cstv.com is far worse than the football team. I’m not sure what they are hoping to accomplish with a site like this, but if you want to see the site at its worst, use Firefox and make the text two sizes bigger by hitting Ctrl+ twice. That way you can see the problem with Web sites that use AJAX.

Dvorak is correct in his statement, and his statement came right back to haunt him. Compare the two images below. The first is a screenshot of his column as viewed without any font size changes; the second is a screenshot of his column after hitting Ctrl+ twice to increase font size.

Screenshot of Dvorak's column (normal font size)
Screenshot of Dvorak’s column (normal font size)
Screenshot of Dvorak's column (large font size)
Screenshot of Dvorak’s column (large font size)

I know how important advertising is to PC Magazine, but increasing the font size caused the ad to appear twice, and covered some of the text of the article. Let’s hope their web designers read Dvorak’s article, too.

The ultimate launcher: Launchy

William of Bug this! Technie Journal writes about how he likes Vista’s start menu search feature, which lets you quickly find programs in the start menu (Tools that save you headache on trying to find your program in 100+ items start menu). I also liked the feature, and I agree with him in that the feature is not good enough to warrant a Vista upgrade. However, while he found a solution in Colibri, I prefer Launchy.

What does Launchy let you do? To understand, let’s look at some ways to open Remote Desktop Connection:

  1. Click Start, then All Programs, then Accessories, then Remote Desktop Connection.
  2. Press Windows-R to open a command prompt, then type mstsc, then press enter.
  3. Press ALT-Enter, type rem, then press enter.

Launchy screenshot#3 is Launchy in action. You can mistype commands, and it’ll still find reasonable matches — type reno and you’ll still likely find Remote Desktop Connection. Multiple matches? Choose from a drop-down list that puts the most recently used and best matches at the top. It’s super-productive.

With Launchy, here’s how I open Mozilla: ALT-Enter, moz, enter. Visual Studio? ALT-Enter, vis, enter. Cisco VPN Client: ALT-Enter, vpn, enter. This is very cool.

Thinking of how much I love Launchy reminds me that I’ve totally skipped the month of September in my drive to donate $5 per month to a free software product, so I’m going to donate $10 to Launchy — because it is that cool. My donation history to date far is as follows.

Thanks to Josh Karlin for writing such a great utility!

Make your web site accessibile, else the courts will force you

It was bound to happen eventually…

SAN FRANCISCO–(BUSINESS WIRE)–A federal district court judge issued two landmark decisions today in a nationwide class action against Target Corporation. First, the court certified the case as a class action on behalf of blind Internet users throughout the country under the Americans With Disabilities Act (ADA). Second, the court held that Web sites such as target.com are required by California law to be accessible. (read more)

What makes the site not accessible? Apparently, the lack of ALT tags.

Continue reading