Ambiguous match really is ambiguous in ASP.NET

I just love days of lost productivity. You know, the ones where you pine away at some problem, retracing every change you made, every source control update you performed, attempting to track down the offending bug in code. Days like yesterday, for example. I was working on a fairly nondescript ASP.NET web page, but every time I would attempt to run it I would get the following error:

Parser Error

Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately. Parser Error Message: Ambiguous match found. Source File: /Default.aspx Line: 1

The only thing that is typically on Line 1 of any ASP.NET web page is the Page declaration, which specifies the CodeBehind and Inherits properties, so naturally my first thought was that perhaps the class name for the page conflicted with another class in the same namespace. But this was an erroneous assumption, and after renaming the file several times I decided that was probably not the case. After a few hours of searching, I realized that I had a button on my page declared something like this:

<asp:Button ID=”cancel” runat=”server” Text=”Cancel” />

and an event on the same page (in CodeBehind) declared like this:

public event EventHandler Cancel;

As it turns out, when ASP.NET parses a page’s controls, it does so in a case insensitive manner, which means that the two “cancel” properties (a button is really a protected property declared in the designer) conflict. This, of course, is completely contradictory, since the code will actually compile (case matters; there should be no name conflict) and only crashes at runtime. This reeks of FAIL, especially since the whole point of ASP.NET is to make web pages more “object-like”. All the more reason to use MVC.

<asp:Button ID=”cancel” runat=”server” Text=”Cancel” />