# Wednesday, October 31, 2007

Since learning about the SubSonic project last week, I have spent a bit of time reading up on it, watching screencasts about it, playing with it, and reading the blog of its creator, Rob Conery. In his post "How MVC, jQuery, and SubSonic Will Make You Smile," Rob talks about the use of .NET 3.5's extension methods, in particular extending a Dictionary<string, string> to return HTML for a drop down list (HTML select); here is what his version of the extension method looks like:

 

 1: public static string ToHtmlSelect(this Dictionary<string, string> listItems, string name,
object selectedValue, object attributes)
 2: {
 3:  // input formats
 4:  string selectFormat = "<select name='{0}' id='{0}' {1}>\r\n{2}\r\n </select>";
 5:  string optionFormat = "\t<option value='{0}' {1}>{2}</option>\r\n";
 6:  
 7:  // output
 8:  StringBuilder sb = new StringBuilder();
 9:  
 10:  foreach (string s in listItems.Keys)
 11:  {
 12:  string selectedFlag = "";
 13:  string text = listItems[s];
 14:  string value = s;
 15:  if (value.ToLower().Equals(selectedValue.ToString().ToLower()))
 16:  selectedFlag = "selected=true";
 17:  sb.AppendFormat(optionFormat, s.ToString(), selectedFlag, text);
 18:  }
 19:  string result = string.Format(selectFormat, name, attributes.ToAttributeList(), sb.ToString());
 20:  return result;
 21: }



 

He also mentions that (on line 19) there is another extension method that "hangs off the object class" which basically enumerates all of the properties of an object, creating a name/value pair attribute list. He doesn't give the code of that extension method, which he states "is ScottGu magic at work and something he shows in his MVC demos." I have yet to watch those demos myself, but the code is probably something akin to this:

 

 1: public static string ToAttributeList(this object attributes) 
 2: {
 3:  StringBuilder sb = new StringBuilder();
 4:  foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(attributes)) 
 5:  {
 6:  sb.AppendFormat("{0}='{1}' ", property.Name, property.GetValue(attributes).ToString());
 7:  }
 8:  return sb.ToString();
 9: }

 

This allows you to pass anonymous types, specifying what might normally be optional parameters, a la something I have been doing in JavaScript for a while using MochiKit (other JavaScript libs exploit the same literal JavaScript object notation in their function signatures). The idea is that you don't need to have a structured method signature that accepts all possible options - you can pass in what you want to specify as a part of an anonymous object. This will make more sense if you have spent any time doing this in JavaScript or want to wait a moment and read on.

Anyway, the whole reason I was even posting on this subject is because of a comment made on Rob's post by one Joe Chung, wherein he states:

"Seeing StringBuilder-generated HTML makes me sad for the future of ASP.NET. Object-oriented ASP spaghetti code is still spaghetti code."

He is referring to the string hacking done in the ToHtmlSelect extension method. I too don't care for it, and simply wanted to show a nicer way of doing this, which leverages objects we already have access to in ASP.NET which do that grunt work for us.

Here is my version of Rob's method (which I still have issues with, but for now we will let those go for the sake of staying on topic) - note, there are no literal strings for those that despise them:

 1: public static string ToHtmlSelect(this Dictionary<string, string> listItems, object selectedValue,
object attributes)
 2: {
 3:  DropDownList htmlSelect = new DropDownList();
 4:  htmlSelect.Attributes.AddAttributes(attributes);
 5:  foreach (string key in listItems.Keys)
 6:  {
 7:  ListItem item = new ListItem(listItems[key], key);
 8:  item.Selected = (key.ToLower().Equals(selectedValue.ToString().ToLower()));
 9:  htmlSelect.Items.Add(item);
 10:  }
 11:  return htmlSelect.ToHtml();
 12: }

 

Now, my version does not use the ToAttributeList() extension method hanging off of  object - mine uses something a bit different, but an extension method nonetheless (although a bit naive, it will suffice for our purposes):

 

 1: public static void AddAttributes(this System.Web.UI.AttributeCollection attributeCollection,
object attributes)
 2: {
 3:  foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(attributes))
 4:  {
 5:  attributeCollection.Add(property.Name, property.GetValue(attributes).ToString());
 6:  }
 7: }

 

My extension method hangs instead off of System.Web.UI.AttributeCollection because my version of the ToHtmlSelect() method works with the System.Web.UI.DropDownList object, which uses that as the place to store its attributes.

The other key to mine is the following extension method which wraps a technique I have been using for over 2 years to create HTML (I didn't figure it out on my own, but can't remember where I saw this exactly - I think in the Google Group for the AjaxPro.NET component back when it was simply Ajax.NET):

 

 1: public static string ToHtml(this Control control)
 2: {
 3:  StringWriter sw = new StringWriter();
 4:  HtmlTextWriter htw = new HtmlTextWriter(sw);
 5:  control.RenderControl(htw);
 6:  return sw.ToString();
 7: }

 

Note - this can be used for all sorts of Control-derived ASP.NET HTML wrapper objects to get you some HTML without string hacking in your layers of code:

 

 1: Calendar c = new Calendar();
 2: string calendarHtml = c.ToHtml();

 

Notice Joe - no literal strings! That should make you happy (I know it makes me happy!).

Now, I love hacking JavaScript as much as the next guy (been doing it hardcore for the last 2.5 years even with ASP.NET because it is too much fun!), but hacking strings to create HTML is still not that fun. Even in JavaScript I don't do it if I don't have to, preferring to use functions that handle that for me (MochiKit has some simple DOM functions for handling HTML creation).

Anyway, hope this is of some use to someone out there!

 

Technorati Tags: , , , ,
Kick It on DotNetKicks.com

posted on Wednesday, October 31, 2007 12:38:37 PM (Mountain Standard Time, UTC-07:00)  #    Comments [11]
# Wednesday, October 10, 2007

Say what you will about Microsoft and/or its founder, but you can't deny that Bill Gates is now doing a lot of good in this world. A recent Q&A with him and an article he wrote both highlight some charitable work being done by the Bill & Melinda Gates Foundation.

So, if you don't buy Microsoft products you may be hurting your fellow man. :P

Kick It on DotNetKicks.com

posted on Wednesday, October 10, 2007 10:53:56 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [4]
# Wednesday, May 02, 2007

My daughter came up to me yesterday and said "09 F9 11 02 9D 74 E3 5B D8 41 56 C5 63 56 88 C0" - I have absolutely no idea what she was talking about, but I thought was interesting nonetheless.

Kick It on DotNetKicks.com

posted on Wednesday, May 02, 2007 5:47:06 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Friday, April 20, 2007

I loved seeing this story today; Vista is a worthless upgrade IMNSHO.

Kick It on DotNetKicks.com

posted on Friday, April 20, 2007 2:43:40 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]
# Wednesday, April 04, 2007

ARGH! While reading comments on a blog today, I came across someone using a phrase which, for some reason, really gets to me: "I could care less." Reading it or hearing it, it really gets me. It is almost as bad as hearing someone say "irregardless," which, unfortunately, seems to be making inroads among those that should know better.

Okay people - think about things before you say or write them. Help me live...

Kick It on DotNetKicks.com

posted on Wednesday, April 04, 2007 10:19:50 PM (Mountain Daylight Time, UTC-06:00)  #    Comments [2]
# Friday, March 02, 2007


Just released this today - it yet needs a bit of work; the only major part not completed are the methods that provide metadata for stored procedures (mainly because I don't need this feature at the moment, so it was the lowest on my list of priorities), which I am planning on finishing within the next two weeks.

You can download it at www.sapientdevelopment.com.

Kick It on DotNetKicks.com

posted on Friday, March 02, 2007 5:09:47 PM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Tuesday, February 27, 2007

 

The company I work for is hiring -  whether you are a project manager, senior-level Java developer, Microsoft application developer or a web design/usability expert, Software Technology Group has something for you.

I have worked for STG for over 2 years now and can tell you that, without a doubt, working for STG has been one of the highlights of my career.

Kick It on DotNetKicks.com

posted on Tuesday, February 27, 2007 9:28:28 AM (Mountain Standard Time, UTC-07:00)  #    Comments [0]
# Sunday, October 29, 2006


For the last client I worked for, we extensively modified a MochiKit port of a well-known 'Lightbox' implementation so that it would utilize IFrames - the users of the application loved it because they were used to primitive JavaScript alert and confirm boxes, and since a modal dialog was still the appropriate thing to do, it worked well.

A short time later, I found ThickBox - seems to be a much better implementation of this now-common technique, and I thought it might prove useful to have a MochiKit version of it in case I decide I want to use it (it is built on jQuery, which I don't personally use or care for, notwithstanding the library having a few useful constructs that I would like to see ported over to MochiKit).

In porting this script, I tried not to 'improve' it at all; i.e. I left nearly everything as-is with regards to naming conventions, use of certain constructs that I would like to improve, etc. and leave it up to you, if you choose to download it, to make any changes you see fit. Of course, any bugs you find would be great to know about, as well as ideas for enhancements, etc. and I will probably update this when I get time, because I would like to do things much differently (maybe I am smoking crack, but this whole idea of connecting to things based on the value of the 'class' attribute of a tag just seems stupid to me...).

My port of ThickBox isn't perfect and I did it as quickly as I could because I wanted to get it into the hands of those smarter than I - that means you. There are places in the code that are inconsistent and I will be working on that, but for now it does the job and should be a good starting point for those that find this useful.

Download ThickBox for MochiKit.

Kick It on DotNetKicks.com

posted on Sunday, October 29, 2006 11:02:53 AM (Mountain Standard Time, UTC-07:00)  #    Comments [2]
# Wednesday, September 13, 2006

It seems that Ajax.NET Pro has finally been open-sourced, and with a great license. I have been waiting for this to happen for a very long time now; Michael has released source code before, but it was just a snapshot of a specific version and you couldn’t really do anything with it according to the license he released it under. It seems that things are finally changing for the better with this library, this is a step in the right direction. Of course, as soon as Atlas is finally released, will it matter?
Kick It on DotNetKicks.com

posted on Wednesday, September 13, 2006 10:05:06 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [1]
# Tuesday, August 15, 2006

A few years ago, for a short time, I worked at Neumont University (was "Northface University" until a certain company had issues with the name) with one Jonathan Ellis; a few months after he left NU, he told me about his new job at Berkeley Data Systems: they have a great product/service called Mozy which provides a really simple-to-use application that does backups of the data on your Windows machine. In the past I would back-up my data to DVDs and CDs, and while I still do that from time to time, the main problem is location – I store these discs in the same location as the computer that contains the data, so that if my house went up in flames or was broken into, I could still lose my data. Obviously, offsite storage is the answer, but what am I going to do? Run some discs over to my in-laws? It would work, but that is not the most convenient option, and what if the data changes on a fairly regular basis?

You may already know that offsite backup solutions have been around for a long time, and this is an established means for solving the “problem” of how to handle data backups, but Mozy is much cheaper than any other similar service available. In fact, if you don’t mind them emailing you once a month or so with some targeted advertising (i.e. ‘spam’ – but this is actually worthwhile spam), you can get 2GB of free backup storage space. Now, 2GB isn’t much if you are interested in backing up images, video, music, etc., but if you have a lot of source code or Word documents, etc. it may be adequate – and they will give you an extra 256MB for every user you refer, once that user has completed their first backup. If you don’t mind paying a little bit of money, you can upgrade to 30GB for $4.95 a month. Compare that to other services – you will be amazed at what a great deal Mozy represents; here is their (humorous) list of alternatives to using it:

  • Burn a new CD or DVD every Sunday night and store them at your brother-in-law's office.
  • Pay $200/year for an online backup service that uses old, mediocre software.
  • Buy a $200 external hard drive and hope your office doesn't burn down.
  • Do nothing and don't worry about backup. (We suggest closing your eyes, plugging your ears and repeating "I'm in my happy place, I'm in my happy place.")
  • Run a cron job of rsync, gzip and mcrypt piped over ssh to your friend's server over his DSL line.

Obviously, this is a slightly biased list, but there is truth to it nonetheless. A few things to note: their backup of your data is secure – SSL over the wire and then the data itself is encrypted using a key you provide or you can trust their use of the 448–bit power of the Blowfish algorithm; the backup is differential, so you don’t have to worry about large, time-consuming backups (except for the first time or any subsequent points in time where you decide to backup new, large files or sets thereof); Mozy does in-place upgrades to its software, automagically notifying you when they are needed; the application is small and uses a small amount of memory (usually around 12MB of my RAM).

I have been using Mozy for over a year now, if I remember correctly, and I have loved it. I have never needed (thankfully) to perform a restore on any files, so I can’t speak to how easy that is, but from all appearances, it doesn’t look like rocket science. The peace of mind I have from using it has been worth every piece of email I have ever received from Mozy. Give it a try and see if you don’t discover the same.

For some captioned screenshots of various aspects of the Mozy experience, expand this section:

Mozy runs in the system tray, and a tool tip tells you when the last backup occurred:

System Tray Tooltip

The context menu is fairly simple:

System Tray Menu

Choosing Status from said context menu gives you the following:

Status Dialog

If you choose Configure from either the context menu of the system tray item or the above status dialog:

LoadingConfig

If you know that you want to backup all files of a few certain types, the Backup Sets feature is nice:

BackupSetsTab

If the Backup Sets feature is too high-level for you, the File System tab lets you get as granular as you want:

FileSystemTab

There are three types of backups: manual (see the earlier Status dialog), automatic (checks CPU usage stats as well as idle time), and scheduled. You can specify that you want to be alerted if a backup has not occurred in n days.

ScheduleTab

The options are pretty self-explanatory:

OptionsTab

Want to know specific details about a given backup incident? This History is also available via a button on the Status dialog.

HistoryTab

Kick It on DotNetKicks.com

posted on Tuesday, August 15, 2006 8:51:47 AM (Mountain Daylight Time, UTC-06:00)  #    Comments [0]