How VirtualPathUtility combines paths in .Net 2.0 – level 100

This is a warning that the VirtualPathUtility class in .Net 2.0 takes
some time to understand the rules under which it operates.  It
wasn’t obvious to me, and I had to do some investigation to learn it’s
behavior.  I expected the following test to pass.  It didn’t.

        [Test]
        public void ShouldCombineTwoWebsitePaths()
        {
            string parentPath = “/websiteRoot”;
            string subDirectory = “newPage”;
            string expected = “/websiteRoot/newPage”;

           
string actual = VirtualPathUtility.Combine(parentPath, subDirectory);
            Assert.AreEqual(expected, actual);
        }

I expected it to actually “Combine” the base path and the path that was
relative to the base path.  After all, if these combine, the
product will be the sum of both, right?  Not really.  Here’s
my test output:

    String lengths differ.  Expected length=20, but was length=8.
    Strings differ at index 1.
   
    expected:<“/websiteRoot/newPage”>
     but was:<“/newPage”>
    ————^

Thanks to the first comment below, I realized that this method
tries to act like a web browser in resolving relative paths.  If I
add a “/” to the end of “/websiteRoot”, the test would have
passed.  As it stands, it assumes that “websiteRoot” is a page and not
a directory.

Hiding errors is evil – level 200

Hiding errors:

  • Swallowing informative excpetions
  • Returning a magic value instead of the error
  • Ignoring errors

I’m sure many can relate this this experience:  I’m using an application or a programming API.  The code runs and returns.  I move on.  I find out later that the code failed, and the work was never done.

This scenario can kill an application’s reliability and reputation.  When this happens, you don’t find out about errors until some time later.  Because of this, you really can’t say that the application is working correctly at any point in time unless you explicitly investigate a log somewhere where errors are stored.

Hiding errors makes life harder.  Finding out about errors when they happen makes for more reliable systems.  I’ll give one quick example from the .Net Framework v2.0.  This example uses C#.
            

string loweredUrl “/mypage.aspx”;

string loweredApplicationPath = “/myApplication”;

 

string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

Console.WriteLine(appRelativeUrl.Length);

This seems simple enough.  We’re using the VirtualPathUtility class to convert a url to it’s application-relative form.  In this case, I’m passing an invalid argument in.  The rule this method uses is that if the url is not a part of the given application path, it’s invalid.  What does VirtualPathUtility do in this case?  It returns NULL!  I passed in an invalid argument, and it returns null.  The more appropriate response would be throwing an ArgumentException.  Because of this error hiding, I have to know the internal rules of this method and code around them.  I can’t afford for this code to continue while appRelativeUrl is null.  The next line would throw a NullReferenceException.

Because of the error hiding, my code ends up like this:

string loweredUrl “/mypage.aspx”;

string loweredApplicationPath = “/myApplication”;

 

if (!loweredUrl.Contains(loweredApplicationPath))

{

    throw new ApplicationException(string.Format(“url {0} is not in application path {1}”, loweredUrl, loweredApplicationPath));

}

 

string appRelativeUrl = VirtualPathUtility.ToAppRelative(loweredUrl, loweredApplicationPath);

Console.WriteLine(appRelativeUrl.Length);

I have to do an explicit check and compensate for the undesirable behavior of the API.

If an error condition happens, I want to know about it.  The term “fail fast” is very popular.  It means that if the application encounters a condition where it can’t continue, stop now and output the exception information.  Don’t have the application limp along until it crashes in flames.  If you break your arm, you stop what you are doing and get a cast put on.  Yes, you _could_ go to work if it’s not your mousing arm, but you cause less damage if you stop right away and address the problem.

SOA has not lived up to it’s hype – level 200

A quick google search will reveal a raging debate on the merits of SOA.  It has cooled down a bit from 2005 where every time I turned around, there was another session at Tech Ed on SOA.  The talk about SOA has just started if its landscape is going to be anything like the adoption landscape for OOP.  SOA has not lived up to it’s hype yet, but to be fair, we have to give it another two decades. 

We don’t think about it much, but object-oriented programming began in the 1960’s with the Simula language.  Smalltalk helped the movement, but C++ brought object-oriented development into the mainstream in the late ’80s when the ANSI group was formed.  From 1962 to 1989, OO was a lot of talk and theory with handfuls of folks implementing real systems using the concepts.  When C++ hit, many more programmers came on board.  Java furthered the adoption of object-oriented concepts, and .Net seems to have pulled the remaining part of the programming market into OO.  When I think about how long it has taken for the average programmer to ackowledge OOP, I wonder if it will take that long for other paradigm shifts.

It remains to be seen if SOA really has the merits granted it by all the marketing hype or if it is just a new name for integration.  We won’t really know for at least another decade, I imagine.  Folks have been integrating systems when necessary for years, so it remains to be seen if this new (everything is exposed as a service) strategy works.

I like the way Jeremy Miller puts it:  “The ‘if you build it, they will come’ approach doesn’t work.”  I agree.  As with any part in programming, building something with the wish that someone will use it someday doesn’t work.  If you are adding a service endpoint to a system out of necessity because someone else need to integrate NOW, then the business value is there, and it’s the same kind of integration that has been going on for years.  Some large companies need to integration now, and we see case studies galor: google search.

What we won’t find out until many moons from now is if these SOAs worked.  Every project is declared a success immediately after completion, so we can’t count on reported results right now.  The true test is if these integrated enterprises are maintainable and cost-effective.  Architects from big companies are saying “yes they are” right now, but no one thinks their child is ugly.

Austin MSDN Code Camp was a huge success – level 000

This past Saturday, March 4, my user group, ADNUG, hosted its first MSDN Code Camp.  We had some cool sponsors including Microsoft, St. Edward’s Professional Education Center, Wrox Press, 101X radio station, CyberJocks, and Catapult Systems

We had 17 unique sessions from local developers on tracks: Web, Smart Client, Data, and Agile.  My talk was “Pragmatic ASP.NET 2.0:  What features do I need?”.  All the sessions got very positive comments on our survey.  We targeted 150 developers, and we hit very close to our goal.  At one point, we thought we were going to be swamped because of the huge number of registrants, but the event went off really well.

Thanks to all our sponsors for helping make this event a success.

Oracle-style joins in Sql server. There is no performance difference – level 300

I recently came across some sql code that caught me off guard.  Here is is:

select something
from table1, table2
where table1.id = table2.id

I immediately thought that a Cartesian product was happening and the rows were being filtered afterward.  All my database experience has been with Microsoft databases, so I didn’t know that this syntax used to be the way most people did sql..  Like any good engineer, I set out to find out for myself what was really going on.

I used the Northwind database to compare the following two queries:  the first with Sql server syntax, and the second with “old school” syntax (which Sql server 2000 suppports).
SELECT    *
FROM    Orders o
    INNER JOIN Customers c ON o.CustomerID = c.CustomerID
    INNER JOIN [Order Details] od ON o.OrderID = od.OrderID
    INNER JOIN Products p ON od.ProductID = p.ProductID

SELECT    *
FROM Customers c, Orders o, [Order Details] od, Products p
WHERE o.CustomerID = c.CustomerID
    AND o.OrderID = od.OrderID
    AND od.ProductID = p.ProductID

I ran these two queries many, many times together and in isolation, and I examined the execution plans, the client statistics as well as the Sql trace.  It appears that at a lower level, these two operations are identical.  Both queries took the same Duration, CPU cycles, and Reads to execute.  Here is the Execution plan.  Both queries have this same exact exectuion plan:

Personally, I like the INNER JOIN syntax.  It’s very explicit, and it’s easy to add RIGHT and LEFT to dictate OUTER joins.  A plus is that it is the ANSI standard and Microsoft’s recommendation for Sql Server. 

The objective conclusion of this experiment is that the style picked for a query will not affect the speed at which that query runs.  The differences are subjective.  My advice, however, is that a single style be adopted as part of the team’s coding standard.