Monday, June 27, 2005

web.config Intellisense

A recent CodeProject article discusses Howto: Enable Intellisense Support for Configuration Files In VS.NET 2003.

Seems to work pretty well and I can see how the same technique could be applied to custom XML files in applications. The one problem I found seems to be that the XSD provided with the article download doesn't appear to support the tag of the config. I couldn't find it in anywhere in the XSD and unfortunately my XSD skills aren't so great otherwise I'd fix it. I may try at some point once I get some more understanding of building XSDs.


It turns out the article's comments section had some suggestions on fixing the element problem. So I did some reading and tweaked the XSD. It seems to now validate properly with elements where they are allowed. You can download my modified XSD here:

Another update (6/27):

Apparently, putting that xmlns attribute in the element of a web.config causes it to break. There was no mention of this in anything I read about it. It makes intellisense work when it's there and used in Visual Studio, but completely seizes the application. Not such a good thing.

Saturday, June 25, 2005

A Page.GetUrl() Method

A recent post on the Wrox/Wiley programmer to programmer forum asked the question:

"How do I get the URL to a page without hardcoding the page URL?"

While it would be a very nice feature to have in .NET it seems to make sense that there is no method that will generate a URL for you to a page even though we have strongly typed code-behind classes that often times drive the page. Consider that the pages are just ASPX files that can be named anything and can live anywhere in your application structure. They can be derived from any page-derived class in the accessible namespaces (the framework supplied System.Web.UI.Page class, or any class that you create in your application assemblies that was derived from the framework's web page class). This provides us with very flexible design and application structure but as a result we don't have a reliable way to say "give me the URL for X".

A possible solution to this that solves two problems at once is to create a shared/static "GetUrl" method on the pages. This method provides the root-relative URL to the page that owns the code-behind class as well as specifying required parameters so you don't have to guess at them or encounter problems later on.

Let's take an example of a class that shows the attributes for some item. This class lives at the root of our application:


Here's the code-behind class:

Public Class ItemAttributes
Inherits System.Web.UI.Page
Public Shared Function GetUrl(itemID As Integer, page As Page) As String
Return page.ResolveUrl("~/ItemAttributes.aspx?itemID=" & itemID)
End Function
End Class

The GetUrl() method expects a couple of arguments: first an itemID because we need a reference to some item so we know what item's attributes to show; second, an instance of a Page class. We need the instance of the page class so we can access the ResolveUrl() method. Now, any other pages in the application can create links to this page by calling the public shared method:

   ItemAttributes.GetUrl(12, Me)
'returns "/ourApplication/ItemAttributes.aspx?itemID=12"

A benefit of this technique is that we get a more robust application that is not quite as suceptible to growing pains. Let's say that we move this page because our application is getting bigger and the pages are getting cluttered. We'll move the page to a directory of common pages:


We can just modify the GetUrl method and all the pages that consume this page link will follow along without a glitch:

   Return page.ResolveUrl("~/common/ItemAttributes.aspx?itemID=" & itemID)

Now let's imagine that we have to add another querystring value to the page because we now need to get information about the category that this item is in. When we modify our page to look for the querystring value all the page requests will start failing. We don't know all the places that this page is called in the application so we will have to do a pretty good job testing the application to find the now-broken references. However, there is salvation! All we have to do is change the method signature to expect the new argument:

   Public Shared Function GetUrl(itemID As Integer, categoryID As Integer, page As Page) As String

Now when we try to the build the application we'll get compile errors everywhere that this method is called. We can go and repair all those broken calls. Of course, depending on how you build your pages, you could add an overloaded method that still accepts the original set of arguments and have it call the new method with a default value so you don't have to repair broken calls. This is a great approach if you can build the page to function without the additional information.

By using this technique you get several advantages:
1. Flexibility to move pages
2. Compile-time debugging (reduces testing and potential customer discoveries of overlooked bugs)
3. Multi-developer teams don't have to waste precious time researching what the page expects for a querystring because the calls have a strongly typed and descriptive signature.

Tuesday, June 07, 2005

Religious development

I just read a short post on the Wrox/Wiley programmer to programmer forum. The poster's signature read:
Writing software to specification and walking on water is easy.. as long as both are frozen.
How true that is.

Friday, June 03, 2005

Link: Just ignore me when I get crabby like this

Eric Sink writes about basic airport etiquette.

In addition to his comments, I'd like to add the following rule:

- Stand a minimum of 10 feet away from the baggage claim carousel and do not approach until you think you SEE your bag.