Programming Microsoft® ASP.NET 3.5

Errata for Programming Microsoft® ASP.NET 3.5




The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update



Version Location Description Submitted By Date Submitted Date Corrected
Printed
Page 49

Location of Manage Styles item incorrect On page 49, the 2nd sentence under the "CSS Designer" contains an incorrect menu location for the Manage Styles menu item. Change: "When an ASP.NET page is being edited, a Format menu appears on the menu bar that contains a Manage Styles item." To: "When an ASP.NET page is being edited, a Manage Styles menu item appears in the View menu."

Microsoft Press  May 06, 2010 
Printed
Page 55

Incomplete sentence regarding creating a new web site On page 55, the third sentence on the page is incomplete. Change: "The dialog box that appears prompts you for the" To: "The dialog box that appears prompts you for the template to use and a filename for the web site."

Microsoft Press  Jul 13, 2010 
Printed
Page 109

.dll missing four times On page 109, the first column of the last four rows of table 3-8 are missing .dll from the file name. Change: "System.Runtime.Serialization System.ServiceModel System.ServiceModel.Web System.WorkflowServices" To: "System.Runtime.Serialization.dll System.ServiceModel.dll System.ServiceModel.Web.dll System.WorkflowServices.dll"

Microsoft Press  May 06, 2010 
Printed
Page 118

Extra closed parenthesis not required On page 118, the 2nd line of the code sample has too many closed parenthesis. Change: img.ImageUrl = Page.GetWebResourceUrl(typeof(TheControl), GifName));To: img.ImageUrl = Page.GetWebResourceUrl(typeof(TheControl), GifName);

Microsoft Press  Jul 13, 2010 
Printed
Page 148

Missing closed slash in code sample On page 148, the 7th line of the code sample at the bottom of the page is missing a /. Change: To:

Microsoft Press  May 06, 2010 
Printed
Page 166

/ missing from code sample On page 166, the second line of the code sample should be a closed tag. Change: "" To: ""

Microsoft Press  Jul 13, 2010 
Printed
Page 196

"Microsoft" needs to be removed from "Document Object Model" On page 196, the third bullet on the page is incorrect. Change: "The Microsoft Document Object Model" To: "The HTML Document Object Model"

Microsoft Press  May 06, 2010 
Printed
Page 243

"Visual Studio .NET 2005" should be "Visual Studio 2008" On page 243, the third sentence on the page incorrectly references an older version of Visual Studio. Change: "To do so, you use the Website menu in Visual Studio .NET 2005 to start the ASP.NET site administration tool." To: "To do so, you use the Website menu in Visual Studio 2008 to start the ASP.NET site administration tool."

Microsoft Press  Jul 13, 2010 
Printed
Page 258

Code sample incorrect On page 258, the only line of code on the page is incorrect. Change: To:

Microsoft Press  May 06, 2010 
Printed
Page 273

class missing from code sample On page 273, the second line of the second code sample is missing a class declaration. Change: public MyControl : ControlTo: public class MyControl : Control

Microsoft Press  Jul 13, 2010 
Printed
Page 308

"DataSource" is not an IDbConnection Interface Property On page 308, on Table 6-7 the DataSource row is missing a value in the IDbConnection Interface Property column. Instead of a blank space it should be: "No"

Microsoft Press  May 06, 2010 
Printed
Page 312

"Chapter 10" should be "Chapter 9" On page 312, the last sentence in the Note box contains an incorrect reference to Chapter 10. Change: "Data binding, on the other hand, will be the subject of Chapter 10." To: "Data binding, on the other hand, will be the subject of Chapter 9."

Microsoft Press  Jul 13, 2010 
Printed
Page 329 & 330

"Property" should be "Method" On pages 329 and 330, on Table 7-11 the first column title is incorrect. Change: "Property" To: "Method"

Microsoft Press  May 06, 2010 
Printed
Page 431

"original_{0}" should be "{0}" On page 431, the last sentence in the 5th paragraph uses an incorrect value. Change: "The default value is original_{0}." To: "The default value is {0}."

Microsoft Press  Jul 13, 2010 
Printed
Page 437

Code sample missing closed parenthesis On page 437, the 5th line of the second code example is missing a closed parenthesis. Change: using (SqlConnection conn = new SqlConnection(ConnectionString)To: using (SqlConnection conn = new SqlConnection(ConnectionString))

Microsoft Press  May 06, 2010 
Printed
Page 461

Close tags missing from code example On page 461, the last 2 lines in the first code example are missing close tags. Change: To:

Microsoft Press  Jul 13, 2010 
Printed
Page 471

Two missing quotation marks in code sample On page 471, the fourth and eighth lines of the code sample are missing quotation marks. Change: new XElement(“Author”, Dino Esposito”)To: new XElement(“Author”, "Dino Esposito”)

Microsoft Press  May 06, 2010 
Printed
Page 478

.Length missing from code sample On page 478, the third line of the third code sample is incorrect. Change: new {City = c.City >5} into gTo: new {City = c.City.Length >5} into g

Microsoft Press  Jul 13, 2010 
Printed
Page 478

Semicolon in the wrong place in code samples On page 478, the last two lines of each code sample contain a misplaced semicolon. Change: where g.Count() >1 ; select gTo: where g.Count() >1 select g;

Microsoft Press  May 06, 2010 
Printed
Page 481

First should be SingleOrDefault On page 481, the 12th line of the code sample refers to the First method, rather than the SingleOrDefault method. Change: ).First(x => x.Country == “USA”);To: ).SingleOrDefault (x => x.Country == “USA”);

Microsoft Press  Jul 13, 2010 
Printed
Page 503

UpdateCheck.Never should be UpdateCheck=UpdateCheck.Never On page 503, the first line of the last code sample is incorrect. Change: [Column(Storage=”_CompanyName”, UpdateCheck.Never)]To: [Column(Storage=”_CompanyName”, UpdateCheck=UpdateCheck.Never)]

Microsoft Press  May 06, 2010 
Printed
Page 509

"Chapter 10" should be "Chapter 9" On page 509, the 3rd sentence of the first paragraph contains an incorrect reference to Chapter 10. Change: "We already mentioned data-bound controls in Chapter 10 and reviewed their basics." To: "We already mentioned data-bound controls in Chapter 9 and reviewed their basics."

Microsoft Press  Jul 13, 2010 
Printed
Page 539

Closing brace missing On page 539, a closing curly brace "}" should be added to the end of the first code sample.

Microsoft Press  May 06, 2010 
Printed
Page 544

"LoadByCountry" should be "return LoadByCountry" On page 544, the second line of the second code sample is incorrect. Change: "LoadByCountry(country, -1, 0);" To: "return LoadByCountry(country, -1, 0);"

Microsoft Press  Jul 13, 2010 
Printed
Page 557

> missing from code sample On page 557, the 9th line of code in the 1st code sample is missing a >. Change: AutoGenerateEditButton=”true”To: AutoGenerateEditButton=”true”>

Microsoft Press  May 06, 2010 
Printed
Page 615

"UseAccessibleHeader" is not a "DetailsView" property On page 615, the last row of table 13-1 can be removed as UseAccessibleHeader is not a DetailsView property. Remove the following text: "UseAccessibleHeader Determines whether to render tags for the column headers instead of default tags."

Microsoft Press  Jul 13, 2010 
Printed
Page 651

session-state should be role management On page 651, the description of the RoleManager Module in tabel 14-2 is incorrect. Change: "Provides session-state services for the application. Not installed in ASP.NET 1.x." To: "Provides role management services for the application. Not installed in ASP.NET 1.x."

Microsoft Press  May 06, 2010 
Printed
Page 671

Server.CreateObject(strClsid) should be Server.CreateObjectFromClsid(strClsid) On page 671, the method used in the last line of the code example on the page is partially incorrect. Change: Dim comObj As Object = Server.CreateObject(strClsid)To: Dim comObj As Object = Server.CreateObjectFromClsid(strClsid)

Microsoft Press  Jul 13, 2010 
Printed
Page 700

Figure 15-3 is incorrect On page 700, figure 15-3 is incorrect and should be disregarded.

Microsoft Press  May 06, 2010 
Printed
Page 740

")" should be "}" On page 740, the 8th line in the first code sample uses a parenthesis instead of a bracket. Change: set {ViewState[“SortDirection”] = value;)To: set {ViewState[“SortDirection”] = value; }

Microsoft Press  Jul 13, 2010 
Printed
Page 742-745

"Creating a View-State-Less Page" section needs to be replaced On pages 742 through 745, from the section "Creating a View-State-Less Page" to the "Conclusion" the entire text needs to be replaced. Additionally, Figure 15-10 is incorrect and should be disregarded. Change: "Creating a View-State-Less Page The Page class provides a couple of protected virtual methods that the run time uses when it needs to deserialize or serialize the view state. The methods are named LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium: protected virtual void SavePageStateToPersistenceMedium(object viewState); protected virtual object LoadPageStateFromPersistenceMedium();If you override both methods, you can load and save view-state information from and to anything. In particular, you can use a storage medium that is different from the hidden field used by the default implementation. Because the methods are defined as protected members, the only way to redefine them is by creating a new class and making it inherit from Page. The following code gives you an idea of the default behavior of LoadPageStateFromPersistenceMedium: string m_viewState = Request.Form[“__VIEWSTATE”]; ObjectStateFormatter m_formatter = new ObjectStateFormatter(); StateBag viewStateBag = m_formatter.Deserialize(m_viewState);The structure of the page we’re going to create is as follows: public class ServerViewStatePage : Page { protected override object LoadPageStateFromPersistenceMedium() { ... } protected override void SavePageStateToPersistenceMedium(object viewState) { ... } }Saving the View State to a Web Server File The tasks accomplished by the SavePageStateToPersistenceMedium method are easy to explain and understand. The method takes a string as an argument, opens the output stream, and calls into the LosFormatter serializer: protected override void SavePageStateToPersistenceMedium(object viewStateBag) { string file = GetFileName(); StreamWriter sw = new StreamWriter(file); ObjectStateFormatter m_formatter = new ObjectStateFormatter(); m_formatter.Serialize(sw, viewStateBag); sw.Close(); return; } private string GetFileName() { // Return the desired filename. ... }How should we choose the name of the file to make sure that no conflicts arise? The view state is specific to a page request made within a particular session. So the session ID and the request URL are pieces of information that can be used to associate the request with the right file. Alternatively, you could give the view state file a randomly generated name and persist it in a custom hidden field within the page. Note that in this case you can’t rely on the __VIEWSTATE hidden field because when overriding the methods, you alter the internal procedure that would have created it. The GetFileName function in the preceding code could easily provide the file a unique name according to the following pattern: SessionID_URL.viewstateNotice that for an ASP.NET application to create a local file, you must give the ASP.NET account special permissions on a file or folder. I suggest creating a new subfolder to contain all the view-state files. Deleting files for expired sessions can be a bit tricky, and a Windows service is probably the tool that works best. A Windows service, after all, can auto-start on reboot and because it runs autonomously from the ASP.NET application it can clean out files in any case. Loading the View State from a Web Server File In our implementation, the LoadPageStateFromPersistenceMedium method determines the name of the file to read from, extracts the Base64 string, and calls ObjectStateFormatter to deserialize: protected override object LoadPageStateFromPersistenceMedium() { object viewStateBag; string file = GetFileName(); try { StreamReader sr = new StreamReader(file); string m_viewState = sr.ReadToEnd(); sr.Close(); } catch { throw new HttpException(“The View State is invalid.”); } ObjectStateFormatter m_formatter = new ObjectStateFormatter(); try { viewStateBag = m_formatter.Deserialize(m_viewState); } catch { throw new HttpException(“The View State is invalid.”); } return viewStateBag; }To take advantage of this feature to keep view state on the server, you only need to change the parent class of the page code file to inherit from ServerViewStatePage: public partial class TestPage : ServerViewStatePage { }Figure 15-10 shows the view-state files created in a temporary folder on the Web server machine. FiGURE 15-10 View state files created on the server. The folder must grant write permissions to the ASP.NET account. The page shown in Figure 15-10 enables view state, but no hidden field is present in its client-side code." To: "Creating a View-State-Less Page The Page class provides a couple of protected virtual methods that the run time uses when it needs to deserialize or serialize the view state. The methods are named LoadPageStateFromPersistenceMedium and SavePageStateToPersistenceMedium: protected virtual void SavePageStateToPersistenceMedium(object viewState); protected virtual object LoadPageStateFromPersistenceMedium();In ASP.NET 1.x, you just need to override both methods to load and save view-state information from and to anything. In particular, you can use a storage medium that is different from the hidden field used by the default implementation. Because the methods are defined as protected members, the only way to redefine them is by creating a new class and making it inherit from Page. In ASP.NET 2.0 and ASP.NET 3.5, the whole procedure of viewstate persistence has been refactored. As a result, the two aforementioned methods have been moved upper in the call stack and leverage other methods for the physical persistence of the view state. The following code snippet illustrates the current behavior of the method SavePageStateToPersistenceMedium. protected virtual void SavePageStateToPersistenceMedium(object state) { PageStatePersister pageStatePersister = this.PageStatePersister; if (state is Pair) { Pair pair = (Pair) state; pageStatePersister.ControlState = pair.First; pageStatePersister.ViewState = pair.Second; } else { pageStatePersister.ViewState = state; } pageStatePersister.Save(); }The view state persistence is managed by a page persister object that you reach programmatically through the property PageStatePersister—a protected readonly property defined on the Page class. The property returns an instance of the PageStatePersister class. To modify the storage of the view state in ASP.NET 2.0 and newer versions, you derive a new class from System.Web.UI.Page and override the property, as shown below: public class ServerViewStatePage : Page { private PageStatePersister _persister = null; protected override PageStatePersister PageStatePersister { get { if (this._persister == null) this._persister = new MyOwnPageStatePersister(this); return this._persister; } } } The persister class is actually responsible for loading and saving viewstate. By default, ASP.NET uses a class named HiddenFieldPageStatePersister—a public class in the System.Web assembly. This class inherits from a public abstract class named PageStatePersister. Creating a File-based State Persister The following code snippet shows a sample class named FilePageStatePersister that saves the page’s state off to a server-side disk file. public class FilePageStatePersister : PageStatePersister { public FilePageStatePersister(Page page) : base(page) { } public override void Load() { string pageState = String.Empty; // Load the viewstate from a file string file = GetFileName(); StreamReader reader = new StreamReader(file); pageState = reader.ReadToEnd(); reader.Close(); // Attach the viewstate to the page if (!string.IsNullOrEmpty(pageState)) { Pair pair = (Pair) base.StateFormatter.Deserialize(pageState); base.ViewState = pair.First; base.ControlState = pair.Second; } } public override void Save() { string pageState = String.Empty; // Get control and view state to save if ((base.ViewState != null) || (base.ControlState != null)) { pageState = base.StateFormatter.Serialize( new Pair(base.ViewState, base.ControlState)); } // Save it off to a file. // The name of the file is determined using file name and session ID string file = GetFileName(); StreamWriter writer = new StreamWriter(file); writer.Write(pageState); writer.Close(); return; } private string GetFileName() { string url = base.Page.Request.ServerVariables["Path_Info"]; url = url.Replace("/", "_"); // Place the file in a temp folder (with write permissions) string fileName = "{0}/{1}_{2}.viewstate"; fileName = String.Format(fileName, "ViewStateTemp", base.Page.Session.SessionID, url); return base.Page.Server.MapPath(fileName); } }As you can see, the persister base class holds both the view state and control state collections in inherited members. Another class member—the StateFormatter property—returns the system-provided formatter to use to serialize state. The state is first serialized to a Base64 string and then saved to a disk file. Whether you use a disk file, a database table, or perhaps in-process memory you need to find a unique identifier for each page instance the user visits. In other words, if the user navigates repeatedly within the same page in the same session, you need to persist a copy of view state for each page displayed. This is necessary to maintain the Back/Forward navigation. And this is indeed what happens when the page itself incorporates the view state. Worse yet, you need to figure out a reliable algorithm that allows to determine the unique identifier looking at the sole context of the HTTP request. Finally, you should arrange a server-side tool to clean up old view state in memory, database, or the file system. As you can see, keeping the view state on the server is definitely possible, but requires some forethought. In the end, if you decide to go for it, then you need to create your own persister class and bind it to a custom base page class. Next, you change the parent class of any page where you need server view state to inherit from ServerViewStatePage: public partial class TestPage : ServerViewStatePage { }The folder must grant write permissions to the ASP.NET account."

Microsoft Press  May 06, 2010 
Printed
Page 768

Square brackets placed incorrectly On page 768, the fourth line of the code sample is incorrect. Change: CacheDependency deps[] = {dep1, dep2};To: CacheDependency[] deps = {dep1, dep2};

Microsoft Press  Jul 13, 2010 
Printed
Page 870

"Windows 2008 Server" should be "Windows Server 2008" On page 870, the last sentence in the Note box includes an incorrect title sequence for Windows Server 2008. Change: "The “real” IIS 7.0 for Web developers and administrators will ship in 2008 with Windows 2008 Server." To: "The “real” IIS 7.0 for Web developers and administrators will ship in 2008 with Windows Server 2008."

Microsoft Press  May 06, 2010 
Printed
Page 947

"Events of ScriptManager" should be "Property of ScriptReference" On page 947, in Table 19-6 the title of the table is incorrect. Change: "Events of ScriptManager" To: "Property of ScriptReference"

Microsoft Press  Jul 13, 2010 
Printed
Page 1063-1064

30 should be 45 On pages 1063-1064, the overlapping sentence contains two references to 30 pixels rather than 45 pixels. Change: "The following example composes three Ellipse elements by placing each 30 pixels from the left and 30 pixels from the top of the Canvas." To: "The following example composes three Ellipse elements by placing each 45 pixels from the left and 45 pixels from the top of the Canvas."

Microsoft Press  May 06, 2010 
Printed
Page 1085

Note should be removed On page 1085, the note is incorrect and should be removed. The section to be removed reads: "Note In the book’s sample code, you also will find a Silverlight 2.0 version of the advertisement document featured in Figure 21-15." Microsoft Press is committed to providing informative and accurate books. All comments and corrections listed above are ready for inclusion in future printings of this book. If you have a later printing of this book, it may already contain most or all of the above corrections.

Microsoft Press  Jul 13, 2010