The Orbit Notebook Software Architecture, Development and Design Thoughts

31Dec/110

" href="http://blueorbitsoftware.com/blog/?p=168" rel="bookmark">Make your enumeration values friendlier with this Enum Description extension method

I like to DataBind. In fact, I love to DataBind. It makes my job as a programmer extremely easy, and gives me the ability to write less code with the payoff of faster performance.  Sold.

Typically, when writing ASP.NET websites, I'm using data binding to attach a collection to a control, let's say a DropDownList. In most cases, my data source is a database and the values that I show in my DropDownList are from a Description (or other user-friendly-type) column.

But what happens when I want to data bind to an enumeration? Doesn't seem like a big deal, until you realize that many enumerations contain multi-word values. For example, an enumeration of colors can be easily data bound to a DropDownList and looks relatively clean when your color has a simple one-word name:

But what happens when you have a color that has a multiple-word name, like this:

Gross.  That just isn't acceptable.

As you know, .NET enumerations allow for a Description attribute, and this thing is a lifesaver. It allows you to attach pretty and user-friendly text to an enumeration, as a description. For instance:

Okay, cool.  So we've attached some user-friendly descriptions to our enumerations.  How do we get those descriptions out of the enum, for our data binding?

This is where extension methods come in to play.  There is an extension method that's been floating around the interwebs for a while that allows you to generically pass your enumeration type, while returning you the description of the value you're in need of.  Here's the snippet and some comments that we'll use in our example, below.

/// <summary>
/// Allows a description "friendly value" to be retrieved for an enumeration.
/// i.e.;
///
/// [Description("Built-In Microwave")]
/// BuiltInMicrowave = 9
///
/// </summary>
public static class Enum<T>
{
   public static string Description(T value)
   {
     DescriptionAttribute[] da = (DescriptionAttribute[])(typeof(T).GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false));
     return da.Length > 0 ? da[0].Description : value.ToString();
   }
}

In essence, you qualify the Enum object with the type of enumeration, and then you pass the enumeration number to the Description method.  Using the "Built-in Microwave" example in our code comments, you would call this extension method like so:

string friendlyDescription = Enum<ApplianceType>.Description(9);

This will return the friendly description, "Built-In Microwave" which you can pull directly into a List, Dictionary, or IEnumeration, and quickly databind into your page controls.

Filed under: Programming No Comments
24Aug/101

Linking Changesets to Work Items in TFS (after the fact)

Lately, I’ve had a few occasions in Team Foundation Server, where I’ve checked in a bunch of code and forgotten to associate the files with a work item. Not a huge deal, but I like to have my changes grouped-up by the bug or work item, so it’s been worthwhile for me to make the association.

Linking a changeset to one or more work items after the initial check-in is really easy, although it's not too intuitive. The easiest way that I’ve found to accomplish this is to open your bug or work item in TFS and scan about a third of the way down the page to a group of tabs. Within these tabs is a “Links” tab:

Now, click this “Links” tab, to see any changesets (or test results, or other work items) that have already been associated with this work item:

From here, you can click “Add” and choose Changeset from the Link type dropdown list. Enter the number of the changeset and a comment, and voila.

Link added! I hope this saves you some time and searching.

Filed under: ASP.NET, C#, Programming 1 Comment
16Aug/100

Ugly Javascript Error when Downloading PDF Files (or other Response.Write files)

This past week, I had a creepy error hit me in an ASP.NET website that I inherited a few weeks ago.

Basically, the website allows you to click on a LinkButton to view a .PDF of a warranty's brochure.  When debugging the site in Firefox, nothing happened when I'd click the LinkButton.  And, I mean nothing.  Fortunately, the console in Firebug let me drill-in and view the details.  (IE also gave me the little "hazard sign" in the bottom left-hand corner, with the details)

Here's the error message:

Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.

After doing some research, I found a pretty simple solution for the error.

I'm not going to go into specifics about what and why the error occurred (Eilon Lipton does that for me, here) but I will tell you that the basic explanation is that my LinkButton was inside an UpdatePanel, and rendering from UpdatePanels (asynchronous postbacks) can get a little squirrely.

So, how did I fix it?  Directly under the declaration of my UpdatePanel, I added a PostBackTrigger, and pointed it at my LinkButton.  Voila.  Problem solved.

Here's the code snippet:







...

Hopefully, this one saves you some time. Cheers.

12Feb/1032

ASP.NET and jQuery DataTables – The Basics, Part II

Okay, we left off having coded our data object, which will store our Oscar nominees. Now, here's where it gets fun. Let's add some markup to the .aspx page and get this thing running. First, add our link to the default stylesheet and our jquery javascript files into the section of the XHTML:








So, our links are in place, now let's add the Repeater. Keep in mind, the magic of jQuery DataTables lies in the fact that they will operate on any HTML tables. In fact, their website states that DataTables, "add advanced interaction controls to any HTML table". So, we're going to embed a table into our Repeater. I'm guessing most of you (if you've read this far) have worked with Repeaters and tables before, so I'm going to post the code, and you'll see the table structure embedded right into the Repeater. You'll want to place this code inside of the

and specifically, inside of a
.




  


    
Movie Lead Actor Lead Actress Director
<%# Eval("MovieTitle") %> <%# Eval("LeadingActor") %> <%# Eval("LeadingActress") %> <%# Eval("Director") %>

As you can see, our column names are within tags, and our databound elements are within tags. The DataTables library will take care of being the brains of this operation. Speaking of the DataTables, now would be a good time to add the actual jQuery code to the section of this document. In fact, place the following code directly underneath our

This code launches the DataTable functionality against our "tblOscarNominees" table, and even sets a few properties.

In case you were wondering, the "oLanguage and sSearch" properties allow us specify our search bar text. The "iDisplayLength" property sets the default number of rows displayed, and the "aaSorting" property allows us to set the default sort column. If you check the DataTables website, there are tons of configurable properties for this plug-in.

Okay, last but not least, we need to databind our Repeater. Pop back over to the Default.aspx.cs codebehind class. Directly below the code where we added "Milk" to our list of nominees, we need to set the datasource and databind the repeater:



rptOscarNominees.DataSource = nominees;
rptOscarNominees.DataBind();


Build the website and run it. Your page should pop, and it should look just like this:

Go ahead, enter something in the search field. No postback! Sort the columns. Quick and easy. Paginating with no custom code. This plug-in would have saved me countless hours a few years ago. I love it.

Now, keep in mind, this is a very simple example, just to help you get your hands around the technology. But using this example, you can tweak the stylesheet to pretty up the table, and use the concept in your own day-to-day development. Hopefully, with this amazing plug-in, you can be a hero for your clients, too. Cheers!

12Feb/1014

ASP.NET and jQuery DataTables – The Basics, Part I

Okay, here's the story. About three months ago, I started designing and developing a website for a client which allows Real Estate Agents to (among other things), purchase home warranties for their clients.  A chief business requirement for this site was the ability for an agent to have a central "sandbox" from which they can view, drill-down, convert, sort, and search their warranties. This "sandbox" was best represented as a grid - but how would I make an ASP.NET
GridView/Repeater/DataGrid perform all of these functions without handwriting a metric ton of custom code?

That's where the jQuery DataTables plug-in came to the rescue.  And this thing is sweet.  I've demo'd the functionality several times for my clients, and they go crazy over the quick and seamless searching, sorting and ordering. No postbacks!  I look like a hero.  Little do they know.

When I was starting out with DataTables, I found their documentation sparse and hard to follow. Then I tried some googling for a tutorial of DataTables with ASP.NET and found little to nothing. So, I decided to throw a very quick and simple tutorial together.

Okay, to get started with DataTables, you'll need to navigate to the DataTables website, and download the latest version.  This files come wrapped in a .zip file, containing the jQuery script libraries, the DataTables script libraries, some default stylesheets and some sample code. Note: I'm working with the DataTables version 1.6.1 in this tutorial, so these examples may become outdated with future versions.

Unzip the file to an easy-to-remember location and open up Visual Studio 2008.  Let's fire up a brand new website, by selecting File > New > Web Site.  We'll make this a "File System" website, so choose a location and click "OK".

New Web Site

You'll see that this default website has a default page, a web.config file, and that's about it.  And that's close to all we're going to need, for this tutorial.

Let's go ahead and pull our DataTables files that we downloaded into the project.  In the Solution Explorer, right-click on the project name and select "New Folder".  Name the new folder "DataTables".  Now, go unzip the DataTables .zip file that we downloaded, drill-down to the "media" directory and copy the contents of this directory into the new folder we created.  You should be copying a "css" folder, an "images" folder, and a "js" folder into our new "DataTables" folder.  Skip the "unit_testing" folder, as I won't be covering that in this tutorial.  Your Solution Explorer should look like the following:

Still with me?  Good!  My plan is for us to use an ASP.NET repeater as the data structure, and we'll lay the DataTables on top of the repeater.  So, let's click through to our code-behind and build a quick-and-dirty data structure that we can bind to our Repeater.  In the Solution Explorer, right-click on Default.aspx and choose "View Code".

Since I'm a big movie buff, I figured we'd build a list of a few of the 2009 Oscar Best Picture nominated movies, and some minor details about each.

In the codebehind (outside of the _Default class), create a new class or struct and call it "BestPictureNominee". Here's what the code for this class will look like:



public class BestPictureNominee
{
    public string MovieTitle { get; set; }
    public string LeadingActor { get; set; }
    public string LeadingActress { get; set; }
    public string Director { get; set; }
}


Okay, back to our Page_Load event. Instantiate the new class and set it's properties. We'll use a generic List<> as our collection class, since it's simple to use and databind. So, here's my Page_Load event, so far:



protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        List nominees = new List();

        BestPictureNominee slumdog = new BestPictureNominee()
        {
            MovieTitle = "Slumdog Millionaire",
            LeadingActor = "Dev Patel",
            LeadingActress = "Freida Pinto",
            Director = "Danny Boyle"
        };
        nominees.Add(slumdog);

        BestPictureNominee benjamin = new BestPictureNominee()
        {
            MovieTitle = "The Curious Case of Benjamin Button",
            LeadingActor = "Brad Pitt",
            LeadingActress = "Cate Blanchett",
            Director = "David Fincher"
        };
        nominees.Add(benjamin);

        BestPictureNominee milk = new BestPictureNominee()
        {
            MovieTitle = "Milk",
            LeadingActor = "Sean Penn",
            LeadingActress = "Alison Pill",
            Director = "Gus Van Sant"
        };
        nominees.Add(milk);
    }
}


So we've got a web project, our DataTables files, and a bindable list of our data, all ready for our UI. In Part II, we'll create the XHTML markup in our .aspx page, add the jQuery DataTable function, and finally, bind the data in our codebehind. Stay tuned - I should have it posted in the next day or so!

Update: Here's the link to Part II.

28Jan/102

ASP.NET Repeater – Get A Handle On Your Row

When it comes to the ASP.NET Repeater, I'm coming to find that there are twenty ways to "skin a cat", when it comes to getting a handle on the data and controls within the Repeater.  After writing entirely too much code and eventually finding a much easier way to handle this, I decided to pop a post.

Now, if you've worked with the Repeater for a while, you're familiar with the ItemDataBound event, and how you can get a handle on your controls by calling FindControl() to get a (boxed) instance of your control with which you may then set values, styles, etc.

But, what if you're handling an event of another control that's within your Repeater?  How, then can you get an instance of the Repeater -- or better yet, how can you get a handle on a different control in that row?  NamingContainer is how - it will give you the row that the current event call fired from.

Take this method, for example.  It's the SelectedIndexChanged event for a dropdownlist that's inside of my Repeater.  Not a big deal, but I want to update a label that's in the same row, but in a different column of my repeater.  Here's how it's done:

Filed under: ASP.NET, C#, Programming 2 Comments
17Dec/091

WCSF Model-View-Presenter and Moq Issue

I've got an ASP.NET Model-View-Presenter website that was generated by the WCSF (Windows Client Software Factory).  When it created the solution a few weeks ago, WCSF laid down my test project, yet didn't automatically include a reference to System.Core.dll.  Aside from a "The type or namespace name 'Linq' does not exist in the namespace 'System'" error, this wouldn't typically cause me problems in a test project.  In fact, when it first occurred, I removed the "Using System.Linq;" directive and rebuilt and didn't think about it again.

Until I decided to use Moq.

I was starting to think that I'd been sipping on grampy's cough medicine, when my test class recognized the Moq.Mock class, yet when I'd call Setup() and try to enter my predicate, it wouldn't allow a predicate to be typed - nor would it give me Intellisense for any of my interface methods.

After hunting around for a while, I figured out that the System.Linq error message that I saw a few weeks ago was the root of the problem.  Without a reference to System.Core.dll, the Linq libraries that support predicate recognition weren't loaded, and I wasn't able to run my mock setups.

Ahh, good times with WCSF.

Filed under: ASP.NET, C#, Programming 1 Comment