January 2006 - Posts

My Own Blog Engine Software
28 January 06 06:08 PM | Scott Mitchell | with no comments

Today I spoke at a one-day class at UCSD Extension titled .NET 2.0 University, giving a 90 minute presentation on new features in ASP.NET 2.0. My presentation focused on:

  • The provider model
  • Membership
  • Site Navigation
  • Master Pages
  • Data binding / Data Source controls
  • The Login and Navigation Web controls

I had a slew of demos showing each of these neat features in their own right, but no single, unifying, semi-real-world demo to illustrate the use of many of the above concepts in one fell swoop. This lack of a unified demo nagged at me a bit during the week, but I had a full plate. Today, though, after the lunch break, still 90 minutes away from my talk, I decided to see if I couldn't create such an encompassing demo in the hour and a half I had before I was slated to speak. Being able to create such an app, I figured, would not only be a fun race against the clock, but would highlight the developer productivity improvements baked into 2.0.

So I set out to create a very, very simple blogging engine, a website that used master pages, would allow visitors to create accounts / login, add entires to their blogs, view the 10 most recent blog entires on the homepage, provide site navigation using a menu with a list of the bloggers and their three most recent posts, and a page to see a list of all of the site's bloggers, when they started blogging, their last login date, and so on. It uses a custom site map provider to base the navigation structure on the bloggers and their three most recent posts. (To be fair, the custom provider involved a little cutting and pasting from another example I had done a few months back, although I still had to write a sproc and change the meat of the code in the BuildSiteMap() method.) As a testament to ASP.NET 2.0, I was able to create such a site in a little under 75 minutes. I contemplated adding some additional features - a page to view all of the posts for a particular user, or an aggregate RSS feed for the site (or by user, perhaps), but figured such demos were tangential to the features I was presenting in 15 minutes (that and my batteries were nearly zapped and I wasn't near an outlet).

If interested, you can grab the Visual Studio 2005 project here. If you've yet to explore 2.0, I think you'll be heartily impressed with what is accomplishable in such a short window of time. Of course this application is very trivial and not even close to being ready for prime time, but I still think it's impressive to have gone from literally ziltch to what I had in 75 minutes, to which the ASP.NET team deserves the credit.

Filed under:
Adding Keyboard Shortcuts to PowerPoint
27 January 06 02:04 PM | Scott Mitchell | with no comments

Caveat: I am pretty green when it comes to VBA and Office automation, so take my comments as my (probably incorrect) educated guesses. I could be, and likely am, misspeaking in a number of ways in this blog entry, but hopefully the comments here will help someone else struggle through some of the limitations of PowerPoint. I do heartily recommend the PowerPoint newsgroup - good volume and knowledgeable folks.

If you use PowerPoint a fair bit like yours truly, you'll quickly discover that there are no configurable keyboard shortcuts in PowerPoint. Constrast that to Word, for example, which makes it easy to assign various actions to keyboard shortcuts (go to the Tools menu, choose Customize, and then click the Keyboard button in the lower right corner of the Customize dialog box). For example, in Word I have the keyboard combo Ctrl+C mapped to applying a particular style that provides a nice-looking format for source code (Courier New in a smaller font size).

In my PowerPoint presentations I like to format classes, properties, methods, events, and so on using the same Courier New font in a smaller font size. But in PowerPoint I've had to always use the mouse to select the text, go to the font drop-down list, choose Courier New, and then click on the icon to decrease the font size. This is a pain when creating, over a number of weeks, several hundred slides with typically three to five words needing to be formatted in this manner per slide. Double ick.

After putting up with it long enough (for years, now), I figured there has to be a better way. I went out and searched the microsoft.public.powerpoint newsgroup and found some helpful hints. While you cannot create customizable keyboard shortcuts like in Word, you can create a macro and then add the macro as a Toolbar icon that has a keyboard shortcut. This technique is discussed by poster Jeff Chapman in this newsgroup thread. Therefore I created the following macro in a Module in one of my PowerPoint presentations (you can get to the Macro Editor by hitting Alt+F11):

Sub CodeFormat()
ActiveWindow.Selection.TextRange.Font.Name = "Courier New"
ActiveWindow.Selection.TextRange.Font.Size = ActiveWindow.Selection.TextRange.Font.Size - 4
End Sub

This macro, when executed, sets the selected text's font to Courier New and knocks down the font size by 4 pts. With this macro created, I was able to customize the Toolbar in PowerPoint and add an icon to run my CodeFormat macro and set its Text to &Code Format, which made Alt+C keyboard shortcut for the macro (Alt+X becomes the shortcut, where X is the character following the ampersand (&).). In short, I could now click Ctrl+C and have the selected text formatted in the font/style I like for code. Wonderful.

One problem with the macro-based approach is that, in PowerPoint, it seems that macros are assigned to a particular PowerPoint file. That is, I couldn't reuse a macro defined in one PowerPoint presentation in another one without going through the steps of recreating the macro. In order to make “global” macros, from what I've read you need to use an Add-In. This FAQ - Create an Add-In with Toolbars that Run Macros - proved to be helpful. Check out the FAQ for information on how to create and program the Macro/Add-In. In the end, I ended up using the following code for the Add-In:

Sub Auto_Open()
Dim oToolbar As CommandBar
Dim oButton As CommandBarButton
Dim MyToolbar As String

' Give the toolbar a name
MyToolbar = "Code Format"

On Error Resume Next
' so that it doesn't stop on the next line if the toolbar's already there

' Create the toolbar; PowerPoint will error if it already exists
Set oToolbar = CommandBars.Add(Name:=MyToolbar, _
Position:=msoBarTypeNormal, Temporary:=True)

If Err.Number <> 0 Then
' The toolbar's already there, so we have nothing to do
Exit Sub
End If

oToolbar.Top = 0

On Error GoTo ErrorHandler

' Now add a button to the new toolbar
Set oButton = oToolbar.Controls.Add(Type:=msoControlButton)

' And set some of the button's properties
With oButton
.DescriptionText = "Format the selected text as code."
'Tooltip text when mouse if placed over button
.Caption = "&Code Format"
'Text if Text in Icon is chosen
.OnAction = "Button1"
'Runs the Sub Button1() code when clicked
.Style = msoButtonIconAndCaption
' Button displays as icon, not text or both
.FaceId = 52
'52 is my favorite pig;
' chooses icon #52 from the available Office icons
End With

' Repeat the above for as many more buttons as you need to add
' Be sure to change the .OnAction property at least for each new button

' You can set the toolbar position and visibility here if you like
' By default, it'll be visible when created
oToolbar.Visible = True

NormalExit:
Exit Sub ' so it doesn't go on to run the errorhandler code

ErrorHandler:
'Just in case there is an error
MsgBox Err.Number & vbCrLf & Err.Description
Resume NormalExit:
End Sub

Sub Button1()
' This code will run when you click Button 1 added above
' Add a similar subroutine for each additional button you create on the toolbar
' This is just some silly example code.
' You'd put your real working code here to do whatever
' it is that you want to do


ActiveWindow.Selection.TextRange.Font.Name = "Courier New"
ActiveWindow.Selection.TextRange.Font.Size = ActiveWindow.Selection.TextRange.Font.Size - 4
End Sub

I then added the Add-In through the Tools menu's AddIns menu item. And now I have a little pig icon in all my PowerPoint presentations that can be executed by hitting Ctrl+C, making PowerPoint much more user-friendly for yours truly.

Filed under:
SubmitDisabledControls - A New Property in ASP.NET 2.0
23 January 06 01:37 PM | Scott Mitchell | with no comments

Last week I blogged about the differences between read-only and disabled HTML elements, the main one being that read-only controls' values are posted back to the server on form submission, while disabled controls' values are not. With ASP.NET 2.0, the behavior changes slightly such that the ASP.NET TextBox, when its ReadOnly property is True, will not pick up any changes to the value it sent down to the client. This change in behavior can introduce a subtle bug for those relying on that behavior, as evidenced by this blog entry by Rick Strahl.

One of the issues with disabled controls is that if controls are marked disabled on the client-side, the values are not posted back and therefore any changes are lost from the previous visit. To demonstrate this, check out this demo. ASP.NET 2.0 adds a new property to the HtmlForm class (the server-side Web Form) that it designed to mitigate this problem. When set to True, the SubmitDisabledControls property injects a morsel of JavaScript in the <form> element's onsubmit event handler that sneakily goes in and marks all disabled form fields as enabled, in order to have their form values returned by the browser on postback. This property, as well as other workarounds to this problem (for those still in ASP.NET 1.x), are discussed in greater detail in my latest 4Guys article, Subtleties in Providing a Read-Only User Interface.

Filed under:
SoCal CodeCamp THIS WEEKEND
19 January 06 12:56 PM | Scott Mitchell | with no comments

If you're in Southern California this weekend, why not drop by the free, two-day SoCal CodeCamp conference? It's hosted in Fullerton, CA with sessions on both Saturday the 21st and Sunday the 22nd. A complete schedule is available here.

As I blogged about before, I'll be giving two talks on Sunday the 22nd:

  • Syndicating and Consuming RSS - RSS is an increasingly popular XML-based syndication format used by websites to keep interested visitors abreast with the site's latest news and information. News sites like CNN, MSNBC, and Yahoo! News provide their latest headlines through RSS; virtually every blog offers an RSS feed. In this talk we'll look at RSS's structure and see how to both syndicate content using RSS and how to consume remote RSS content through a website.
  • Working with HTTP Handlers and Modules - HTTP Handlers and Modules provide a low-level way for developers to tap into the ASP.NET HTTP pipeline. When a request arrives for an ASP.NET resource, a number of events can fire during the request's lifecycle. HTTP Modules are managed components that you can create and attach to these request cycle events. To render the request, the ASP.NET engine instantiates an HTTP Handler based on the incoming request. To handle special types of requests, you can create your own HTTP Handler.

Hope to see you there!

Filed under:
More Debugger Visualizer Goodness
17 January 06 12:13 PM | Scott Mitchell | with no comments

Last week I blogged about Visual Studio 2005's Debugger Visualizers, and mentioned K. Scott Allen's control hierarchy visualizer, one of many free, community-driven visualizers that you can download and plug into Visual Studio 2005 today. I've been tinkering around with Scott's and others' visualizers over the weekend and decided to write an article on 4Guys about debugger visualizers: Improved Debugging with Visual Studio 2005's Debugger Visualizers.

In the article I present my first “from scratch” visualizer, one that applies to the System.Web.UI.Page data type and, when utilized, shows the server variables collection in a ListView. It's pretty trivial but provides a good starting point for those who are interested in creating their own custom visualizers. You can download the code from the article or from the My Code Projects page. Enjoy!

(I banged my head against a wall for several hours this weekend trying to get a visualizer to display the rendered contents of a control at any point in the page lifecycle. I know that Brett Johnson offers such a visualizer, but this control simply calls the RenderControl() method of the specified control, which carries with it some baggage. It's a technique I've discussed before, in Emailing the Rendered Output of an ASP.NET Web Control. Some potential issues with RenderControl() in ASP.NET 2.0 arise if you try to render a Web Form, since it tries to add the hidden input field to register events validation script. Of course this blows up because the Page will only happily do this if we're in the render phase of the page lifecycle. Similarly, if a user wants to render a TextBox directly, it'll complain that it's not within a Web Form. I tried to work around this by creating a faux Page class that overrode the VerifyRenderingInServerForm() method and EnableEventValidation property, but there are still some spots in certain controls that blindly reference the page's HttpContext object, which doesn't exist in the faux Page class. Urg.

If you have any ideas/workaround/solutions, I'd be delighted to hear them. Thanks!)

Filed under:
ReadOnly vs. Enabled in Version 1.x and Version 2.0 for ViewState-Disabled Forms
16 January 06 09:41 AM | Scott Mitchell | with no comments

All ASP.NET Web controls have the Enabled property, which, when set to False, renders the associated HTML element as “disabled,” which grays it out and prohibits the user from interacting with the control. For example, in IE a disabled TextBox's text is grayed out and the user cannot focus on the TextBox, change its value, etc. (In FireFox, the text and background of the TextBox are both grayed out.) Often, web developers will use the Enabled property when displaying a read-only or locked data input screen.

However, if you examine the TextBox class you'll find a ReadOnly property in addition to Enabled, which can understandably be a bit confusing especially considering that the other standard input Web controls - the CheckBox, RadioButton, DropDownList, RadioButtonList, CheckBoxList, ListBox, etc. - lack the ReadOnly property and offer only Enabled. If you set the ReadOnly property to True for the TextBox you'll find that the text/background is not grayed out (as with setting Enabled to False), but that the text content is uneditable (as expected per the property's name).

So what's the difference between these two properties and why do both exist? There are two differences between these two properties, a trivial difference and a subtle, profound one:

  1. The two properties emit different markup. When you set Enabled to False, the TextBox injects the attribute disabled="disabled" into its rendered HTML. When you set the ReadOnly property to True, the attribute readonly="readonly" is injected.
  2. According to the W3C spec on HTML forms, disabled controls are NOT "successful," while read-only controls MAY BE "successful." A "successful" control is one whose name/value pair is sent back to the browser through the POST headers or querystring. Therefore, disabled controls are NOT sent back to the ASP.NET page, while read-only controls may be, depending on the User Agent. (In my tests, both IE 6 and FireFox 1.5 send along the read-only TextBox input.)

For most scenarios, this subtle difference in postback between read-only and disabled controls is not an issue... it becomes an issue, however, when using these controls in a page with its ViewState turned off and when these control values are set programmatically.

Since disabled input control values are not sent back when the form is submitted, the only way that the page can remember these values is if they are specified statically (i.e., specified directly in the markup portion of the ASP.NET page in the TextBox control's declarative syntax) or if they are set programmatically and ViewState is enabled for the control and page. If ViewState is disabled and the control value is specified programmatically, it will be lost on postback because the actual value in the disabled TextBox won't be sent back to the server (because it's not a “successful” control) and the server won't remember the value in ViewState since ViewState is disabled).

If you encountered this problem in ASP.NET version 1.x you might have found the TextBox's ReadOnly property and used that instead of setting Enabled to False. You could still have a page's ViewState disabled and set a read-only TextBox Web control's Text property programmatically because the TextBox value is sent back through the form submission for read-only controls. However, in ASP.NET version 2.0, things change just a bit, as noted by Rick Strahl in his blog entry ASP.NET 2.0 ReadOnly behavior change when EnableViewState is false. With 2.0, the TextBox control's ReadOnly property's behavior has changed slightly. From the technical docs:

The Text value of a TextBox control with the ReadOnly property set to true is sent to the server when a postback occurs, but the server does no processing for a read-only text box. This prevents a malicious user from changing a Text value that is read-only. The value of the Text property is preserved in the view state between postbacks unless modified by server-side code.

What happens is that the client sends along the value of the read-only TextBox through the form values, but the ASP.NET 2.0 engine does not take that value and assign it to the Text property of the TextBox on postback to help protect against a malicious user changing the read-only TextBox value themselves. But this brings us back to our earlier problem - if the value isn't specified in the postback (or is ignored, in this case) and ViewState is disabled, the value will be lost. Eep.

Rick's workaround was to just manually read the value from the request headers (this.TextBox1.Text = Request[this.TextBox1.UniqueID];), which poses a security risk and introduces the problem that 2.0 addresses. The optimal approach is to requery the value from the database (or wherever you initially got the programmatically-set value for the read-only TextBox).

The moral of this blog post is that if you have read-only data you can use either disabled or read-only form fields, it really doesn't matter whether or not you receive back the value of the form field in the form's submissions. It shouldn't matter because you shouldn't be trusting/using that data to begin with! If you have read-only data, don't re-read it from a data stream that the end user can tinker with!

Filed under:
Debugging Visualizers in Visual Studio 2005
13 January 06 12:27 PM | Scott Mitchell | with no comments

One of the cool new features of Visual Studio 2005 is the Debugger Visualizer, which provides an alertnate way to view an object in the VS 2005 debugger. What's especially cool about these little gems is that not only does Visual Studio ship with a number of buit-in visualizers for viewing long strings, XML, HTML, images, and so on, but also provides a mechanism for developers to be able to create their own visualizers and plug them into Visual Studio. (See Creating a Debugger Visualizer Using Visual Studio for more information.)

Yesterday, Scott Guthrie posted a blog entry about free debugger visualizers released by various folks in the community, such as an XML visualizer, and a regular expression visualizer. What really caught my eye, though, was K. Scott Allen's control hierarchy visualizer. With this visualizer you can view the control hierarchy rooted at the control whose little magnifying glass icon you click to load the visualizer.

Since Scott kindly gives the source code for his visualizer, I was able to poke around and add a new feature: in addition to seeing the controls in the hierarchy I also added nodes for the controls' properties (and their values). This required just a few lines of code to perform the reflection on each control in the hierarchy. (FYI, it takes a couple seconds to load up on pages with rather large control hierarchies...) Plus I added a little color and icons, just to spruce things up a tad. :-)

You can download my additions to Scott's visualizer: WebVisualizers.zip. To quote from Scott's blog entry:

To install the a visualizer you have to build the source code. You can build with Visual Studio, or from the command line msbuild OdeToCode.WebVisualizers.csproj, assuming msbuild.exe is in the path. Copy the .dll from underneath the bin directory into MyDocuments\Visual Studio 2005\Visualizers. VS will automatically load the assembly when debugging, and inspect the metadata inside to know what types to visualize. Note: custom visualizers won't load for a web site running at less than full trust.

Filed under:
Referencing the ASPNETDB Database
13 January 06 09:09 AM | Scott Mitchell | with no comments

One of ASP.NET 2.0's coolest new features is the Membership system, which provides a standardized means for implementing user accounts on a system along with an API for interacting with the user accounts in the system. The Membership system using the provider model, meaning that you can customize the inner working of Membership if needed in order to use your custom user account data store. You can learn more about Membership and its cousin systems, Roles and Profile, in the multi-part article series Examining ASP.NET 2.0's Membership, Roles, and Profile (subscribe).

As discussed in the article series, the default SQL-server based implementation of ASP.NET 2.0's Membership system uses a predefined SQL Server database format that includes tables to support user accounts, membership details, roles, and profiles. When you configure your website to use forms-based authentication through the ASP.NET Website Administration Tool, it automatically creates a SQL Server 2005 database that has this schema and places it in your App_Data folder.

You can customize the default Membership settings - such as allowing passwords with just five characters, or requiring two non-alphanumeric characters - by adding a new Membership provider in the Web.config that uses the same type (SqlMembershipProvider), but uses custom values for properties like minRequiredPasswordLength, minRequiredNonalphanumericCharacters, and so on. When you do this, however, you must also provide a value for the connectionStringName property, which indicates the name of the connection string to use to connect to the SQL database that implements the default Membership schema.

In Part 1 of the article series I show how to specify a custom connection string name, but recently was asked how to have it just use the default ASPNETDB database. The answer: use the connection string name LocalSqlServer. That is, you'd add something like the following to your Web.config file:

<membership defaultProvider="CustomizedProvider">
<providers>
<
add name="CustomizedProvider"
type="System.Web.Security.SqlMembershipProvider"
connectionStringName="LocalSqlServer"
minRequiredPasswordLength="5"
minRequiredNonalphanumericCharacters="0" />
</
providers>
</
membership>

That's it! In theory, you could also use this connection string to directly reference the ASPNETDB database through code, such as in a SqlDataSource control. However, ideally you will only interact with this database through the API (i.e., the Membership class).

You can see where this connection string name is defined if you look in the machine.config file in the WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG directory. This file contains default settings for all websites on the web server. In there you'll find:

<connectionStrings>
<
add name="LocalSqlServer"
connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true"
providerName="System.Data.SqlClient"/>
</
connectionStrings>

When this connection string is used, ASP.NET automatically resolves the substring |DataDirectory| to the executing application's physical path's App_Data folder. (You'll have to look into the bowels of the .NET Framework using Reflector to see where that's done.)

Filed under:
SoCal Code Camp - A FREE Two-Day Conference!
11 January 06 09:53 AM | Scott Mitchell | with no comments

Live in Southern California? Interested in attending a free two-day conference with talks from dozens of great presenters? If so, check out the SoCal CodeCamp, which runs from Saturday, January 21st through Sunday, January 22nd 2006 at Cal State Fullerton (location/lodging information). While the sessions appear to be a bit heavy on the .NET side, there are talks on non-.NET topics, such as Python, J2EE, EJB, and Ruby. Furthermore, there are a slew of “concept talks,” which focus on a software design methodology (agile development, test driven development, etc.), or an overall technology paradigm (an overview of Web Services, for example) without delving into a specific technology. Of course there are also dozens of talks on specific technologies, such as Rick Strahl's A Low Level Look at the ASP.NET Architecture, and Chris Rolon's C# 2.0 Language Changes.

I'll be at the CodeCamp myself, I'm presenting two talks:

  • Syndicating and Consuming RSS - RSS is an increasingly popular XML-based syndication format used by websites to keep interested visitors abreast with the site's latest news and information. News sites like CNN, MSNBC, and Yahoo! News provide their latest headlines through RSS; virtually every blog offers an RSS feed. In this talk we'll look at RSS's structure and see how to both syndicate content using RSS and how to consume remote RSS content through a website.
  • Working with HTTP Handlers and Modules - HTTP Handlers and Modules provide a low-level way for developers to tap into the ASP.NET HTTP pipeline. When a request arrives for an ASP.NET resource, a number of events can fire during the request's lifecycle. HTTP Modules are managed components that you can create and attach to these request cycle events. To render the request, the ASP.NET engine instantiates an HTTP Handler based on the incoming request. To handle special types of requests, you can create your own HTTP Handler.

Hope to see you there!

February's Toolbox Column in MSDN Magazine
10 January 06 08:40 AM | Scott Mitchell | with no comments

My second Toolbox column in the February 2006 edition of MSDN Magazine is now available online. The February issue of Toolbox examines the following three products:

The article also explores Framework Design Guidelines : Conventions, Idioms, and Patterns for Reusable .NET Libraries, a highly recommended book by Microsoftees Krzysztof Cwalina and Brad Adams. Here's a snippet from the Toolbox column:

While the mechanics of building a reusable .NET library are trivial, it is anything but to design an easy-to-use library that will gracefully handle future changes and additions. The naming conventions, types, members, exceptions, and design patterns that make up the library greatly affect its overall success. Code libraries that aren't intuitive, that are inconsistent, or that deviate from standard conventions are apt to frustrate its users. When designing a code library, then, why not turn to Microsoft for advice? After all, Microsoft has released the largest reusable code library for .NET—the .NET Framework Base Class Library! Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Addison-Wesley, 2005), by Krzysztof Cwalina and Brad Adams, shares the framework design lessons learned by Microsoft since .NET development began in the late 90s.

You can keep abreast of the latest Toolbox articles through the column's RSS feed or the Toolbox column category here on my blog.

Your Help is Needed!

The most challenging aspect of authoring this monthly column is finding products to review! If you have any ideas or suggestions for products or books to review, please don't hesitate to send them to toolsmm@microsoft.com (which gets auto-forwarded to me).

The only requirements for reviewed products are that:

  • They are useful by developers in their day-to-day operations
  • The use/run on Microsoft technologies
  • They are commercial applications (i.e., not freeware)
  • They are not overly complex/costly.
Filed under:
Reminiscing About Websites Back in the Day
05 January 06 09:55 PM | Scott Mitchell | with no comments

Today I stumbled across a link on a rather old SQL article that referred to the site swynk.com. I don't know how many folks remember Stephen Wynkoop's SQL resource website, but back when I was cutting my teeth on classic ASP swynk.com was one of my regular stops. In 1999 Stephen sold his site to Internet.com and moved on to other things; today Swynk.com redirects to Internet.com's Enterprise IT Planet website's Networking section.

Another regular stop of mine was ASPHole.com, which today no longer exists. (Although I could have sworn that a year or two ago the site made a comeback, but it looks like that comeback faltered.) I have no idea what happened to ASPHole, originally, or after their attempted comeback. Anyone know? And of course there was Charles Carroll's very popular ActiveServerPages.com (which was later renamed to LearnASP.com), which was shut down for sometime starting in 2002 (although it is back online today).

A large part of the reason I started 4Guys a little over seven years ago was because, at the time, there were not many classic ASP websites out there. Other than ActiveServerPages.com, the only other professional classic ASP websites (that I recall) were 15Seconds.com and (to a lesser extent) ASPHole.

Were there any websites back in your day that you used regularly, but disappeared for whatever reason over the years?

Filed under:
skmMenu now on Expedia.de
05 January 06 09:05 AM | Scott Mitchell | with no comments

skmMenu, a free, open-source ASP.NET menu control that I developed sometime back, is now being used on the German Expedia site, Expedia.de. To my knowledge, this is the largest, most public site that skmMenu's been deployed. I started skmMenu back in November 2003 for a pair of ASP.NET Developer Center articles: Building an ASP.NET Menu Server Control and Examining the skmMenu Server Control.

This menu control's success and popularity have been a bit of a surprise to me, to be honest. skmMenu has two benefits:

  • It's free
  • It's open source (allows for customization, provides a means for developers to learn about ASP.NET server control building concepts)

However, I always thought that these benefits were outweighed by the following disadvantages:

  • No official support. Have a question or technical problem with the control? You either have to figure it out yourself or hope someone on the skmMenu messageboard can assist.
  • Lack of exciting features. skmMenu's look and feel is pretty vanilla (my artistic skills are nil). While it can be customized to look appealing, that responsiblity falls on the shoulders of the page developer. Commercial menu controls, like telerik's r.a.d. menu, come with prepackaged themes that produce slick-looking results.
  • A provided Menu server control in ASP.NET version 2.0

Regardless, the skmMenu.com website still averages over 300 unique visitors per weekday.

Don't get me wrong, I'm not bashiing skmMenu and saying, Don't use it. I think skmMenu's price and customizability (by virtue of it being open-source) can't be beat. However, if you need just a standard, nice looking menu control that can be deployed and setup quickly, with dedicated technical support backing the product, the couple hundred dollars charged by the third-party commercial menu controls are definitely worth the investment. Where skmMenu might be the best choice is if you need to highly customize the output/appearance of the menu's markup, or the underlying logic, or if your budget for third-party apps is $0, or if you are interested in learning more about building real-world server controls.

Filed under:
Free, Focused ASP.NET Headlines - Consolidated Your Way!
03 January 06 10:54 AM | Scott Mitchell | with no comments

Ever since creating RssFeed (an open source ASP.NET control designed to display content from an RSS feed in an ASP.NET web page), I've used the control to display the latest headlines from www.asp.net on the 4Guys ASP.NET homepage. About a month ago fellow MVP Sonu Kapoor dropped me a line and we discussed integrating feeds from his site - DotNetSlackers - onto the 4Guys homepage. DotNetSlackers slurps ASP.NET-related websites and blogs from around the Internet and provides a consolidated feed along with category-specific feeds. Initially I used Sonu's ASP.NET category feed on 4Guys, but, since the feed included blogs, found there to be too many off-topic posts (i.e., headlines not focused strictly on ASP.NET content). Furthermore, the feed URLs point back to a summary on DotNetSlackers rather than to the actual syndicated item.

After brainstorming a bit, Sonu came up with a neat solution. Since he already was culling the Internet grabbing various feeds from various focused websites, why not create a page where visitors could say, “I am interested in feeds X, Y, and Z,” and then have DotNetSlackers provide a single feed that consolidated those feeds? For example, you could say, “I am interested in 4GuysFromRolla.com's latest articles, ASPAlliance.com's latest articles, and K. Scott Allen's excellent blog.” After selecting these three blogs, DotNetSlackers would create a single feed for you that you could display on your website or add to your feed reader. Not only does this free service provide a way to selectively consolidate various .NET-focused feeds, but Sonu is kind enough to link directly to the syndicated content. (Sonu does ask that if you do use this combine feed service on your website that you do give a plug to his site, DotNetSlackers.com.)

You can check out the feed building service over at http://www.dotnetslackers.com/CombineFeeds.aspx

More Posts

Archives

My Books

  • Teach Yourself ASP.NET 4 in 24 Hours
  • Teach Yourself ASP.NET 3.5 in 24 Hours
  • Teach Yourself ASP.NET 2.0 in 24 Hours
  • ASP.NET Data Web Controls Kick Start
  • ASP.NET: Tips, Tutorials, and Code
  • Designing Active Server Pages
  • Teach Yourself Active Server Pages 3.0 in 21 Days

I am a Microsoft MVP for ASP.NET.

I am an ASPInsider.