Essential ASP.NET with Examples in Visual Basic .NET

Reported Errata

Date Chapter Page Description
4/14/03 1 25 Table 1-2: The default values are supposed to be underlined but are not. A corrected version of the table can be viewed here
4/14/03 2 49 Figure 2-5: It should be clarified that the event sequence shown here occurs during a Post-back sequence. When an initial GET request is made to a page, the CreateChildControls event actually occurs after the Load event of the Page class fires.
4/14/03 2 51 In Listing 2-11: Declaration of OnEnter subroutine should read:
Protected Sub OnEnter(src As Object, e As EventArgs) _
                   Handles _enterButton.ServerClick
Note the Handles statement uses the ServerClick event, not Click.
11/21/03 3 80 Table 3-2: The description for the maxWorkerThreads attribute should read:
Maximum number of worker threads per CPU in the thread pool

The text incorrectly states I/O threads instead of worker threads.
1/6/05 4 136 Listing 4-24: The interface methods are incorrectly annotated with 'public'. The listing should look like:
  Public Interface IAsyncResult
    ReadOnly Property AsyncState As Object
    ReadOnly Property CompletedSynchronously As Boolean
    ReadOnly Property IsCompleted As Boolean
    ReadOnly Property AsyncWaitHandle As WaitHandle
  End Interface
	  
5/1/03 4 137 Figure 4-25: There is a potential race condition in the implementation of the AsyncWaitHandle property implementation which is fixed in the following code (note the passing of _isCompleted into the constructor of the ManualResetEvent):
    Public ReadOnly Property AsyncWaitHandle As WaitHandle _
           Implements IAsyncResult.AsyncWaitHandle
      Get
        SyncLock Me
          If _callCompleteEvent Is Nothing Then
            _callCompleteEvent = New ManualResetEvent(_isCompleted)
          End If
          Return _callCompleteEvent
        End SyncLock
      End Get
    End Property
        
Note that this will never cause a problem with the async handler implementation in ASP.NET, but in other async callback situations, reuse of this class without the above fix, could cause a race condition.
4/14/03 5 155 Listing 5-4: defaultredirect should be defaultRedirect. Also statuscode should be statusCode
10/17/05 5 159 2nd line: To add a handler to this even,...
should read:
To add a handler to this event,...
10/17/05 5 160 1st line: a Server.Redirect() ...
should read:
a Response.Redirect() ...
3/21/04 6 179 Table 6-2: The description for \W should read [\t\n\r\f\v] (note the lack of the ^ character at the beginning of the expression).
3/21/04 6 179 Table 6-2: The odd arrow characters for the two entries {n,m} and {n,} should be greater-than signs (>) or less-than signs (<) instead of arrows.
{n,m}    Match the previous item >= n times, <= m times
{n,}     Match the previous item >= n times
7/1/03 7 188 Figure 7-3: in order to match the code listing in listing 7-2, the DropDownList control should appear after the CheckBoxList.
7/1/03 7 198 Second paragraph: the phrase 'the total number if items' should read 'the total number of items'.
4/14/03 7 212 Figure 7-14: The 6th line in the second box of code should read:
Container = CType(ctrl.BindingContainer, RepeaterItem)
(variable is ctrl, not SenderControl)
5/14/03 7 214 Listing 7-13: the following line:
  <%# DataBinder.Eval(Container.DataItem, "Age","{0:2d"}) %>
should be:
  <%# DataBinder.Eval(Container.DataItem, "Age","{0:2d}") %>
Note the inclusion of the last brace in the string.
4/14/03 8 284 In the paragraph preceding section 8.6.3, the reference to ExpandableObjectTypeConverter should read ExpandableObjectConverter
4/14/03 8 266 Listing 8-33: <eadn:SimpleComposite id="MyCtrl" should be
<eadn:CalcComposite id="MyCtrl"
4/14/03 8 273 Listing 8-38: the DataSource property should read:
Public Property DataSource As Object '...
Note the Overrides keyword should not be present.
4/14/03 8 272 In the paragraph preceding listing 8-38, m_DataTextField should be _DataTextField.
1/15/04 8 272-275 Listing 8-38: the DataBoundControl sample incorrectly renders the DataValueField. It should instead render the DataTextField as the text, and perhaps render the DataValueField as a hidden attribute (this is how the HtmlSelect control behaves, for example). Below is the GetDataItem method re-written to return the DataTextField property (the references to _dataValueField have simply been changed to _dataTextField:
  Protected Function GetDataItem(item As Object) As String
    Dim ret As String
    If item.GetType() Is GetType(DataRowView) Then
      Dim drv As DataRowView = CType(item, DataRowView)
      ret = drv(_dataTextField).ToString()
    ElseIf item.GetType() Is GetType(DbDataRecord) Then
      Dim ddr As DbDataRecord = CType(item, DbDataRecord)
      ret = ddr(_dataTextField).ToString()
    Else
      ret = item.ToString()
    End If
    Return ret
  End Function
	
Also, here is an updated version of the control that supports rendering the DataValueField as a hidden attribute.
3/11/04 8 286 In Figure 8-8, the Editor attribute on the Url property should read:
<Editor(GetType(System.Web.UI.Design.UrlEditor), GetType(UITypeEditor))>
3/23/04 9 295 Line 4, 'Ouput-Cache' should be 'Output-Cache'
7/2/03 9 304 The last sentence of the first paragraph in section 9.2.3 states "When that user control is loaded into a page at runtime, it is cached, and all subsequent pages that reference that same user control will retrieve it from the cache, thus improving throughput."

By default, this is not quite true - the user control will be drawn from the cache on a per-page basis unless you set the shared attribute in the @OutputCache directive to true (it defaults to false).

11/24/03 9 316 Listing 9-18: The StreamReader used in Application_OnStart() is not properly disposed of - the corrected function looks like:
  
Public Function LoadPi()
  Dim sr As System.IO.StreamReader
  Dim pi As String
  Try
    sr = New System.IO.StreamReader(Server.MapPath("pi.txt"))
    pi = sr.ReadToEnd()
  
    Context.Cache.Add("pi", pi, new CacheDependency(Server.MapPath("pi.txt")), _
                    Cache.NoAbsoluteExpiration, _
                    Cache.NoSlidingExpiration, _
                    CacheItemPriority.Default, _
          New CacheItemRemovedCallback(AddressOf OnRemovePi))
  Finally
    If Not sr Is Nothing Then
      CType(sr, IDisposable).Dispose()
    End If    
  End Try

  Return pi
End Function
      
11/24/03 9 317 Listing 9-19: The casting syntax is incorrect in the Page_Load handler, the corrected code should read:
Protected Sub Page_Load(src As Object, e As EventArgs)
  If Cache("pi") Is Nothing Then
	  ' Refresh pi in app
  	pi.Text = CType(Context.ApplicationInstance, global_asax).LoadPi()
  Else
    pi.Text = CStr(Cache("pi"))
  End If
End Sub
      
4/14/03 10 350 Listing 10-21: Within the definition of Page_Load the For Each statement should read:
      Dim it As Item
      For Each it in cart
        totalCost = totalCost + it.Cost
        '...
    
In the text item.Cost was used instead of it.Cost.
4/14/03 11 367 Listing 11-12: 6th line from the bottom should read:
<asp:Button text="Login" OnClick="OnClickLogin"
In the text OnClick_Login is used as a handler name incorrectly.
4/14/03 11 374 Listing 11-18: The declaration of this function should look like:
    Shared Sub HashWithSalt(algName As String, _
                            plaintext As String, _
                            ByRef salt As String, _
                            ByRef hash As String)
    
Note the use of ByRef for the last two parameters.