Tuesday, February 10, 2009

Ugly .Net Bug - asp:hyperlink

Recently, my crew and I ran across one of those painful bugs that takes up too much time. Ultimately, we marked it up to an ASP.NET problem. Here are the details.

We have several environments set up at work ranging from our local/developer system to our production system. In only one of our environments, the navigation in our application would disappear when a postback would occur. We use master pages and several user controls throughout the site. However, since nearly every page that performed a postback experienced the problem, we narrowed our search to the master page. Why didn't we just attach and run the application in debug mode you ask? Well, as it turns out the local environment did not exhibit the behavior. Talk about bringing debugging back to the 90s.

Further logging and testing limited the focus to the Page_Load inside the master page. Setting test points throughout the method, we narrowed it down to some extremely inconspicuous code. Here is an example of that code (obviously not the real code):

hlNav1.NavigateUrl = hlNav1.NavigateUrl.Contains("xyz") ? hlNav1.NavigateUrl : hlNav1.NavigateUrl + "&xyz=123";
hlNav2.NavigateUrl = hlNav2.NavigateUrl.Contains("xyz") ? hlNav2.NavigateUrl : hlNav2.NavigateUrl + "&xyz=123";
hlNav3.NavigateUrl = hlNav3.NavigateUrl.Contains("xyz") ? hlNav3.NavigateUrl : hlNav3.NavigateUrl + "&xyz=123";
hlNav4.NavigateUrl = hlNav4.NavigateUrl.Contains("xyz") ? hlNav4.NavigateUrl : hlNav4.NavigateUrl + "&xyz=123";
hlNav5.NavigateUrl = hlNav5.NavigateUrl.Contains("xyz") ? hlNav5.NavigateUrl : hlNav5.NavigateUrl + "&xyz=123";

As it turns out, we tried several variations of that code. Checking for null, empty, converting to an if statement, blah blah blah. We even wrapped the code above in an "if (!Page.IsPostBack)," to no avail. Here is where it gets interesting. The first time this code executes, it works perfectly. However, in this particular environment, the code blanks out any child entities when you replace the NavigateUrl (only during a postback). We had a <div> inside of each asp:HyperLink which ended up being nuked.

The solution, get rid of asp:HyperLink and use a plain old <a href="" runat="server">. How Glamorous.

At any rate, I hope this keeps someone else from burning time.

Posted via email from A Bit of Everything