Blog Home  Home Feed your aggregator (RSS 2.0)  
Implements IVillage - Tuesday, December 05, 2006
It takes a village to keep up with .Net
 
 Tuesday, December 05, 2006

When workin with the Accordion control in my previous post, I encountered a bug that made life a bit frustrating.  Everytime I broke into the debugger on the ItemDataBound event handler and expanded the event - Crash!  Whenever the display got to e.Item, things stopeed and got funky.  Stop debug and restart.  Create a watch for e.AccordionItem... don't expand the evil e.  I finally took some time and dove into the Accirdion's source code.

I kept looking at this over and over again and could not figure out what was going on and then it clicked - Stack Overflow!  There is a recursive call in the AccordionItemEventArgs class:

        /// <summary>
        /// Container
        /// </summary>

        private IDataItemContainer DataItem
        {
            get { return Item as IDataItemContainer; }
        }

        /// <summary>
        /// DataItem being bound to the Container
        /// </summary>

        public object Item
        {
            get { return DataItem.DataItem; }
        }

When the debugger evaluates Item to display it for you, it calls the DataItem property which in turn calls the Item property and so on...

Going to submit this to the Ajax bug list.  I am modifying my copies definition of the Item property as follows:

        /// <summary>
        /// DataItem being bound to the Container
        /// </summary>
        public Object Item
        {
            get { return _item.DataItem; }
        }  
Wednesday, December 06, 2006 12:59:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]    |  |   | 
 Monday, December 04, 2006

I was recently using the Ajax Accordion control on a project which required me to do some databinding with it.  I was accessing more than one object to fill out the Accordion panels so I wanted to set alot of the controls during the ItemDataBound event of the control.  I quickly became frustrated as I could not find the controls in the AjaxContentPanel being made available to me in the AccordionItemEventArgs.  Here is what I was working with:

<form id="form1" runat="server">
   
<asp:ScriptManager ID="ScriptManager1" runat="server" />
      <div>
         
<cc1:Accordion ID="Accordion1" runat="server">
            
<Panes></Panes>
            
<HeaderTemplate>
               
<div style="background-color:blue;cursor:pointer;"> 
                  Header:
<!--%# Eval("Key") %-->
                  
<asp:Label ID="lblHeader" runat="server" Text="Label"></asp:Label>
               
</div>
            
</HeaderTemplate>
         
<ContentTemplate>
            
<div style="background-color:Silver;padding:5px;border:thin white inset;">
               
Data: <!--%# Eval("Value") %--> 
               
<asp:Label ID="lblData" runat="server" Text="Label"></asp:Label>
            
</div>
         
</ContentTemplate>
      
</cc1:Accordion>
   
</div>
</form>

I built a simple dictionary for this example to do the data binding.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

   If Not IsPostBack Then

      Dim values As Dictionary(Of String, String) = New Dictionary(Of String, String)()
      values("A") = "This is the value for A"
      values("B") = "This is the value for B"
      values("C") = "This is the value for C"
      values("D") = "This is the value for D"
      Accordion1.DataSource = values
      Accordion1.DataBind()

   End If

End Sub

This is what my first attempt to set the labels in the code.

Protected Sub Accordion1_ItemDataBound(ByVal sender As Object, ByVal e As AjaxControlToolkit.AccordionItemEventArgs) Handles Accordion1.ItemDataBound

   Dim myDictEntry As KeyValuePair(Of String, String)
   Dim lblHeader As Label
   Dim lblData As Label

   myDictEntry = e.AccordionItem.DataItem
   lblHeader = e.AccordionItem.FindControl("lblHeader")
   lblHeader.Text = myDictEntry.Key
   lblData = e.AccordionItem.FindControl("lblData")
   lblData.Text = myDictEntry.Value

End Sub

I kept getting null reference exceptions on the 'lblData.Text = myDictEntry.Value' line.  I went into the locals to see what was going on with my eventArgs.  I rapidly found out that you don't want to touch e.Item*.  Any attempt to look at these caused the debugger to drop.  Not fun.  I poked around extensively in e.AccordionItem which is an AccordionContentPanel.  So it became apprent after digging around in the controls source that there are two types of ContentPanels in each AccordionItem.  There is a Content and Header panel.  And you can tell which is which by examining e.AccordionItem.ItemType. 

This is the second attempt which now workd flawlessly.

Protected Sub Accordion1_ItemDataBound(ByVal sender As Object, ByVal e As AjaxControlToolkit.AccordionItemEventArgs) Handles Accordion1.ItemDataBound

   Dim myDictEntry As KeyValuePair(Of String, String)
   Dim lblHeader As Label
   Dim lblData As Label

   myDictEntry = e.AccordionItem.DataItem
   If e.AccordionItem.ItemType = AjaxControlToolkit.AccordionItemType.Header Then
      lblHeader = e.AccordionItem.FindControl("lblHeader")
      lblHeader.Text = myDictEntry.Key
   Else
      lblData = e.AccordionItem.FindControl("lblData")
      lblData.Text = myDictEntry.Value
   End If

End Sub

I was suprised how this particular attribute was buried so deeply in the eventArgs.  I would have expected to see an e.AccordionItemType hanging out to make it a little more obvious.  Overall, I do love this control.  A nice way to present a large amount of content on a page without it running off the bottom of the screen.  And the panel sliding is just too cool.

Tuesday, December 05, 2006 12:35:55 AM (Eastern Standard Time, UTC-05:00)  #    Comments [6]    |  |   | 
 Friday, December 01, 2006

I know the content is still a little thin and eclectic, but if you could take a minute to post a comment.  I see visitors in the logs.  Please tell me if you found the content helpful, correct, incorrect, etc. 

Saturday, December 02, 2006 1:25:57 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]    | 
 Monday, November 20, 2006

We recently had some Microsoft PFE's (Premier Field Engineers) in to Harris Corporate to give us the crash cource in Team Foundation Server.  Apparantly Microsoft has a whole department (Premier Field Engineering) dedicated to customer's like Harris who back up a truck full on money to Redmond each year for licensing.  And what a department it is.  We traded in some of our support hours for the class as it has been a pretty good year for things not going too wrong.  The class was taught by Hamid Safi who was being shadowed by Cory Foy from the Tampa office.  Both guys were incredibly knowledgeable about TFS and almost any other Microsoft product we aksed about.  The class size was quite small and we got the opportunity to go off on some tangents when the in depth TFS discussion was beating our attention spans into submission.

Cory gave the presentation on the Testing portion of TFS / Visual Studio Team Edition where he used a great little Bowling Score class to demonstrate testing.  The discussion then worked its way down to the Agile / TDD.  His initial class was rudimentry and simply added scores.  Test cases were written for several of the simpler scenarios like frames of all zeroes and frames that did not include strikes or spares.  Youc an actually read about this in Cory's Blog entry here: http://www.cornetdesign.com/2006/11/bowling-revisted.html#links.  The demonstration and interactive portion of the talk began when we started covering the spare and strike cases.  Cory went into covering the spare scenarios and we quickly came up with a solution.  But while designing the solution, it became clear to me that the way we were implementing it was not very 'friendly' for implementing the upcoming strike cases.  And this is where the fun began... Cory preached the Agile / TDD gospel here: solve the problem you are workin on and then move on.  I was a bit resistant to his at first but also see its wisdom.  More time than I care to admit, I get bogged down in trying to design out the entire solution for eevery possible case before I get heavy into coding.  And I consequently do not start coding soon enough, do not have prototypes ready on time, and generally cut down on the time I have available to code.

Looking at the world with Agile / TDD glasses on is kind of nice.  I don't necessarily need to have the weight of the whole app or system on my shoulders at once.  I concentrate on getting done what needs to be done now and adding or refactoring in the next features that come down the pipe.  I shouldn't be afraid to write code that I will be throwing away in a few weeks.  The important thing is not the code but an understanding of the system that is being built and its rules.  Well written code will be adaptable to a degree, but when there is a signicant change to the system's requirements, we can't be afraid to throw that code away while retaining its tests and wisdom.

I am going to put an Agile / TDD book on the Christmas list.

Monday, November 20, 2006 9:01:57 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]    |   | 
 Tuesday, October 10, 2006

I recently had an issue where a contractor provided one of our divisions with a web service to deploy on of their servers.  When everything was deployed and the web.config all modified, we kept getting errors IIS 500 errors with:

Requested registry access is not allowed

After much finger pointing, and use of the phrase, "I can't suplicate the problem in my development environment".  I isolated the problem down to this one call in the contractor's web service:

evntLog.WriteEntry( sOut, System.Diagnostics.EventLogEntryType.Error);

The contractor had specified a custom event source for the EventLog control.  A Source being the value that appears in the source column of the event log.  Custom being that the source is not currently registered in the event log.

The evntLog object, which has its Source property set to CustomSrc, attempts to make a log entry.  The operation of this method is detailed in the Framework docs and is as follows: 

You must set the Source property on your EventLog component before writing entries to the log. You can call CreateEventSource on a new source to register it before writing to the event log, but this is not necessary. If the source specified in the Source property of this EventLog instance is not registered on the computer your component is writing to, WriteEntry calls CreateEventSource and registers the source.

So when the web service attempts to write the the log entry for the first time using its custom source, it calls CreateEventSource - which brings us to the KB article http://support.microsoft.com/default.aspx?scid=kb;en-us;842795:
This problem occurs because the user account that you used to log on does not have sufficient permissions.

The first time that you call the EventLog.CreateEventSource() method to create a custom event log, the custom event log entry is created under the following registry subkey:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog

To create this subkey entry, you must have permission to write. However, the regular user account does not have permission to write. Therefore, you receive the error message that is mentioned in the "Symptoms" section.
The reason the developer did not see this problem on his development environment is that the event source was already registered while the web service was running with Administrator privileges.  So, when he later lowered the web service's account priveledge, subsequent calls to WriteEntry did not trigger a call to CreateEventSource.  So rather than keep banging my head against the wall on this, I wrote a simple application that an administrator can run on the server to register the event source:  RegEventSource.exe (28 KB)
So, in a nutshell... if you make use of System.Diagnostics.EventLog.WriteEntry with a custom Event Source, provide your client with an installer or some way to register the event source in their production enironment.  This is just another reason why I love VirtualPC.  It gives you an ideal environment to test these sort of deployments out to ensure you don't waste your client's time with trivial issues like this.
Tuesday, October 10, 2006 9:03:12 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]    | 
Come join the Space Coast .Net User Group to hear Russ Nemhauser speak about ASP.Net 2.0 Web Parts. Web Parts offer ASP.NET 2.0 applications the ability to provide powerful personalization functionality. In this session, you'll learn how Web Parts are implemented in ASP.NET 2.0, how to get up and running with Web Parts quickly, and how to extend the Web Parts framework. You will also learn how Web Parts functionality ties into the built-in membership features.
 
Tuesday, October 10, 2006 4:44:16 PM (Eastern Daylight Time, UTC-04:00)  #    Comments [0]    | 
Copyright © 2008 Christian M Loris. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.