Beruflich Dokumente
Kultur Dokumente
NET
Finding Your Best Starting Point
Microsoft ASP.NET Programming with Microsoft Visual Basic .NET 2 ! Ste" #$ Ste" is designed to "ro%ide a com"rehensi%e introduction and o%er%iew of de%elo"ing &e# a""lications with ASP.NET. The goal of this #oo' is to hel" $ou #ecome com"etent at the #asic s'ills necessar$ for creating and using ASP.NET a""lications. To hel" $ou get there as (uic'l$ and easil$ as "ossi#le) this #oo' has #een di%ided into four "arts) each com"osed of one or more cha"ters related to a s"ecific to"ic. *%er the course of these "arts and cha"ters) $ou+ll learn a#out the new Microsoft .NET de%elo"ment "latform and the "art that ASP.NET "la$s in it. You+ll also learn the s'ills necessar$ to ta'e ad%antage of ASP.NET &e# Forms) Ser%er ,ontrols) and -M./#ased &e# ser%ices. 0e"ending on the s'ills and e1"erience $ou #ring to this #oo') $ou might want to start with a "articular "art of interest to $ou or s'i" o%er certain "arts entirel$. The following ta#le can hel" $ou decide where to start. If you are New To "rogramming 2. 3nstall the sam"le files as descri#ed in 43nstalling the Sam"le Files5 on "age 1%ii. 2. .earn a#out the #ac'ground of the Microsoft .NET Framewor' and ASP.NET #$ reading ,ha"ters 2/6. Then either wor' through Part 333 if $ou want to 'now more a#out the technologies underl$ing ASP.NET or wor' through Part 3V if $ou want to get straight into the coding. !. &or' through the rest of the "arts and cha"ters #ased on $our interest in the %arious to"ics. 2. 3nstall the sam"le files as descri#ed in 43nstalling the Sam"le Files.5 2. 7ead or scan Parts 3 and 33 if $ou+re interested in the #ac'ground of .NET and ASP.NET. !. &or' through Part 333 for #asic &e# Forms s'ills as well as an introduction to using ASP.NET Ser%er ,ontrols and accessing data with A0*.NET. 8. &or' through Part 3V for additional ASP.NET a""lication s'ills. Follow these steps
Referencing
Follow these steps 2. 9se the inde1 to locate information a#out s"ecific to"ics) and use the ta#le of contents to locate information a#out general to"ics. 2. 7ead the :uic' 7eference at the end of each cha"ter for a #rief re%iew of the ma;or tas's in each cha"ter.
Start Microsoft Visual Studio .NET. *"en and run an ASP.NET a""lication. &or' with tool windows. E1it Visual Studio .NET.
Microsoft ASP.NET is not ;ust an u"gradeBnot #$ a long shot. ASP.NET "ro%ides the most ad%anced &e# de%elo"ment "latform created to date. &hat+s more) ASP.NET has #een re#uilt from the ground u" to create an entirel$ new and more fle1i#le infrastructure for &e# de%elo"ment. &hat ma'es ASP.NET so re%olutionar$ is that it+s #ased on Microsoft+s new .NET "latform) or more accuratel$ the Microsoft .NET Framewor'. To understand clearl$ where and when to use ASP.NET) let+s ta'e some time to go o%er the Microsoft .NET "latform) the "roducts that it com"rises) and where ASP.NET fits within Microsoft .NET.
3n the ne1t section) $ou+ll learn a#out these technologies and how $ou can use them to s"eed u" $our de%elo"ment of ro#ust) high/"erformance &e#/ or Forms/#ased a""lications on the Microsoft &indows "latform.
,om"onents written in managed code and e1ecuted #$ the ,.7 are referred to as .NET managed assemblies) or assemblies for short. Assem#lies are the #asic unit of de"lo$ment in the .NET world and are (uite similar to ,*M com"onents. The difference is that whereas a ,*M com"onent has a t$"e li#rar$ to descri#e how clients should interact with it) an assem#l$ contains a manifest) which is the set of metadata that descri#es the contents of the assem#l$. Among other ad%antages) the self/descri#ing nature of .NET com"onents means that the$ don+t need to #e registered on a com"uter in order to wor'H This metadata also descri#es the de"endencies and %ersion information associated with an assem#l$. Not onl$ does this ma'e it much easier to ensure that all necessar$ de"endencies of an assem#l$ are fulfilled) #ut it also means that multi"le %ersions of the same assem#l$ can #e run side #$ side on the same com"uter without conflict. This is a ma;or ste" in resol%ing 40.. <ell)5 the #ane of man$ de%elo"ers+ e1istence. Fust as' an$ &e# de%elo"er who+s wor'ed with more than one %ersion of Microsoft Acti%e- 0ata *#;ects ?A0*A) and $ou+re sure to get an earful a#out a""lications #eing #ro'en #$ a new %ersion of A0*. &ith .NET) this issue should #e a thing of the "ast. As long as the consuming a""lication 'nows which %ersion of an assem#l$ it+s designed to use) it can locate the correct %ersion among multi"le %ersions of the same assem#l$ #$ (uer$ing the assem#l$+s metadata. There+s a great deal more to the ,.7) which $ou+ll learn in future cha"ters. 3f $ou need further information on the ,.7) do a search on 4common language runtime5 in either the .NET Framewor' S0> documentation or the MS0N .i#rar$ documentation for Visual Studio .NET.
3nheritance "nheritance is a central conce"t in the .NET Framewor'. 3t "ro%ides a wa$ for de%elo"ers to use e1isting code in classes. A class can e1"ose #oth "ro"erties and methods that clients can use. ,lasses that are inherited from a "articular #ase class are said to #e deri%ed from that class. B$ inheriting from a class) a de%elo"er can reuse the functionalit$ that it e1"oses without ha%ing to rewrite the code. 3n addition ?and more im"ortantA) a de%elo"er creating a deri%ed class can o%erride one or more of the methods e1"osed #$ the "arent class in order to "ro%ide a s"ecialiGed im"lementation of that functionalit$. This ca"a#ilit$ will come in hand$ when $ou learn a#out custom ser%er controls in ,ha"ter 2 .
A single) unified "rogramming model for all .NET languages and for #oth &indows and &e# a""lications 0rag/and/dro" de%elo"ment for the ser%er using the Ser%er E1"lorer 0$namic <el" A ro#ust customiGation and e1tensi#ilit$ model for the 30E Strong su""ort for -M. &e# ser%ices with dramaticall$ easier cross/"latform a""lication integration
You+ll learn more a#out the Visual Studio .NET en%ironment later in this cha"ter.
,J
A new mem#er of the Visual Studio famil$) ,J is a descendent of the , language. 3t+s much li'e ,LL) #ut designed with greater sim"licit$ and ease of use in mind. Although ,J isn+t necessaril$ as eas$ to learn as Visual Basic) it+s far easier than ,LL and "ro%ides nearl$ all of the "ower a%aila#le to ,LL de%elo"ers. 3t also doesn+t re(uire $ou to manage the allocation and deallocation of memor$) as ,LL does. Because ,J) li'e Visual Basic .NET) is a managed language) all of the memor$ management is ta'en care of #$ the ,.7. This is an im"ortant ad%antage #ecause memor$ management is one of the most trou#lesome areas of ,LL de%elo"ment and is res"onsi#le for man$ a""lication crashes.
0e%elo"ers familiar with ,) ,LL) and Fa%a will (uic'l$ #ecome "roducti%e using ,J. This #oo' will include some code e1am"les in ,J to gi%e $ou a taste of this e1citing new language.
AP. ,*B*. Eiffel F*7T7AN <as'ell Mercur$ Mondrian *#eron Pascal Perl P$thon 7P@ Scheme
3t+s im"ortant to "oint out that while some of the languages shown in the "receding list will #e commercial im"lementations) some others are research "ro;ects #eing conducted #$ uni%ersities and might ne%er reach commercial status. Still) #etween the languages that shi" with Visual Studio .NET and the third/"art$ languages that are or will #e a%aila#le) there should #e a language to "lease ;ust a#out an$ de%elo"er.
The Visual Studio .NET 30E will start. The Start Page is dis"la$ed #$ default whene%er $ou start Visual Studio .NET) and "ro%ides lin's and tools to hel" $ou configure the 30E) o"en recent "ro;ects) create new "ro;ects) and man$ other tas's. B$ default) the 30E will dis"la$ the Pro;ects ta# of the Visual Studio .NET Start Page. This ta# allows $ou to (uic'l$ o"en a recent "ro;ect or to create a new "ro;ect. The *nline 7esources ta# allows $ou to find sam"le code) access online communit$ resources) find .NET downloads) and more. You+ll see more of this ta# in a #it. The M$ Profile ta# of the Start Page) shown in the following illustration) allows $ou to configure the la$out of the tool windows in Visual Studio .NET) as well as the 'e$#oard shortcuts used to accom"lish common tas's.
!. Select the M$ Profile ta#) and then change the main Profile dro"/down list from Visual Studio 0e%elo"er to Visual Basic 0e%elo"er. This will configure the 30E windows and 'e$#oard configuration to match that of Visual Basic 6) as shown in the following illustration) so that e1"erienced Visual Basic de%elo"ers can more easil$ find their wa$ around.
8. ,hange the Profile dro"/down list #ac' to Visual Studio 0e%elo"er to restore the original settings.
2. T$"e ASP.NET in the te1t #o1) and then clic' @o. A list of matching sam"les will #e dis"la$ed) as shown in the following illustration.
IMPORTANT Sam"le a""lications and code can #e useful tools for learning how to de%elo" a""lications) including ASP.NET a""lications. But 'ee" in mind that sam"les are often designed to illustrate a limited set of s"ecific conce"ts) and might not alwa$s use #est "ractices for securit$ and design. Before using sam"le code in $our a""lications) #e sure that $ou understand the securit$ and architectural im"lications of doing so.
NOTE B$ default) &indows 2 and &indows -P hide file e1tensions for 'nown file t$"es. 3f this setting is turned on) $ou will not see the .%#"ro; andEor .sln e1tensions to the files mentioned earlier. You can modif$ this setting in the &indows E1"lorer Folder *"tions dialog #o1. From the &indows E1"lorer Tools menu) select Folder *"tions and then clic' on the View ta#. 9nchec' the <ide E1tensions For >nown File T$"es chec' #o1) and then clic' *> or A""l$. The file e1tensions will now a""ear in the *"en Pro;ect dialog #o1. Solutions and Pro;ects A""lications in Visual Studio .NET are organiGed into containers called pro*ects and solutions. Pro;ects are containers for the files associated with a single a""lication t$"e) such as a &e# a""lication or control li#rar$) while solutions are containers for one or more "ro;ects. The "ro;ects that ma'e u" the sam"le files for this #oo' are contained in a single solution named as"nets#s.sln. Solutions are a useful tool for organiGing all of the "ro;ects associated with a larger a""lication) such as &e# a""lications) and the control "ro;ects or com"onent "ro;ects associated with them. 7unning &e# a""lications is a little different than running &indows a""lications or console a""lications. &ith &indows a""lications and console a""lications) running the a""lication in the 30E is as sim"le as clic'ing the Start #utton) shown in the following illustration) on the Visual Studio .NET tool#ar. Although $ou can also run a &e# a""lication using this techni(ue) it+s more common to sim"l$ #rowse to the "age in the a""lication that $ou want to test. 3f $ou want to run a &e# a""lication using the Start #utton ?or #$ selecting Start from the 0e#ug menuA) $ou need to select a "age in $our a""lication that will #e the start "age) or the first "age loaded when the a""lication is run. You+ll learn a#out these techni(ues in ,ha"ter 28) which co%ers de#ugging ASP.NET a""lications. For now) let+s ;ust test a "age #$ #rowsing it.
30E Enhancements
The new enhancements $ou+ll find in the Visual Studio .NET 30E include the following=
Start Page The Start Page) which we saw earlier in the cha"ter) is the default "age that+s dis"la$ed each time $ou start Visual Studio .NET. 3t allows $ou to set $our "references for the 30E) access recent and e1isting "ro;ects) and create new "ro;ects.
Multilanguage 30E 9nli'e Visual Studio 6) which used different 30Es for each "rogramming language ?although Microsoft Visual 3nter0e% and Microsoft Visual FLL shared an 30EA) all languages in Visual Studio .NET share the same 30E. This means that standard features such as Find And 7e"lace) de#ugging) and so on wor' consistentl$ across different languages. This alone will #e a #ig "roducti%it$ enhancer from Visual Studio 6.
,ommand window A cross #etween Visual Basic+s 3mmediate window and a command line) the ,ommand window lets $ou e1ecute Visual Studio commands or code statements) de"ending on the mode of the window. The following illustration shows a ,ommand window that+s #een switched to immediate mode using the immed command. The ,ommand window has two modes=
,ommand mode allows $ou to e1ecute Visual Studio commands without using the menu s$stem) or to e1ecute commands that don+t a""ear in an$ menu. 3mmediate mode) used in de#ugging) allows $ou to e%aluate e1"ressions) chec' the %alue of %aria#les) e1ecute "rogram statements and functions) and so on.
Ta##ed 0ocuments 0esigned to sim"lif$ the management of multi"le files #eing edited simultaneousl$) the Ta##ed 0ocuments interface allows $ou to see all of the files $ou+re editing at once. This ma'es it much sim"ler to switch #ac' and forth #etween o"en editing windows. You can still set u" Visual Studio .NET to use the old method used #$ Visual Studio 6) howe%er. Fust clic' the Tools menu) select *"tions) then select the @eneral o"tion in the En%ironment folder) switch from Ta##ed 0ocuments to M03 en%ironment) and then clic' *>. You+ll need to restart Visual Studio .NET for this change to ta'e effect.
Auto <ide M$ "ersonal fa%orite) Auto <ide wor's much li'e the feature of the same name in the &indows tool#ar. To ena#le auto/hide for a window) clic' the "ush"in icon) shown in the following illustration) in the window+s title #ar. Now the window will hide itself at the side of the 30E) where it+s doc'ed when the mouse mo%es awa$ from the window) lea%ing onl$ a ta# with the window title %isi#le. Mo%ing the mouse "ointer o%er the ta# will cause the window to rea""ear. This is a great feature for "reser%ing the ma1imum amount of screen real estate for the code window) and it can ma'e life much easier in terms of managing multi"le windows in the 30E.
3m"ro%ed <TM. editor .i'e Visual 3nter0e% #efore it) the Visual Studio .NET <TM. editor "ro%ides #oth a design %iew and an <TM. ?sourceA %iew. Visual Studio .NET has done awa$ with the :uic' View window "ro%ided #$ Visual 3nter0e%. 3nstead) $ou "re%iew "ages in an em#edded #rowser window) which "ro%ides a truer %iew of how a "age will reall$ loo'. The im"ro%ed editor also su""orts s"ecif$ing the <TM. schema $ou+re writing for %ia the targetSchema "ro"ert$. Setting targetSchema determines which elements will #e made a%aila#le %ia the editor+s statement com"letion features and allows the 30E to "ro%ide $ou with feed#ac' on s$nta1 that+s incorrect in the conte1t of $our chosen target schema.
2. Switch #etween o"en documents ?including the Start PageA #$ clic'ing on the ta# for the document $ou want to switch to. 3f there are more ta#s than will fit onscreen) $ou can scroll to %iew the hidden ta#s using the Scroll #uttons) as shown #elow) at the to" of the editor window. You can close the currentl$ selected document #$ clic'ing the ,lose #utton) as shown #elow) at the to" of the editor window.
New Features
3n addition to the 30E enhancements) a num#er of entirel$ new features ha%e #een added to the Visual Studio .NET 30E.
-M. editor This allows $ou to edit -M. data ?.1mlA and schema ?.1sdA files in source) data) or schema %iews) de"ending on the t$"e of -M. file $ou+re editing.
0$namic <el" 0$namic <el" "ro%ides conte1t/sensiti%e hel" while $ou wor' in the 30E #$ suggesting to"ics of interest as $ou add files) controls) and code to $our "ro;ect) as shown in the following illustration.
NOTE &hile the 0$namic <el" window can #e %er$ useful) it also im"oses a "erformance "enalt$Beach time $ou "erform some action in the 30E) the 0$namic <el" window searches for to"ics of interest related to that action. 3f $ou+re familiar with most of the tas's $ou need to "erform) or if $ou+re running Visual Studio .NET on an older machine) closing the 0$namic <el" window ?#$ clic'ing the ,lose #utton in the u""er right/hand corner of the windowA can ma'e the 30E more res"onsi%e.
Su""ort for &indows 3nstaller Visual Studio now su""orts this much/im"ro%ed set/u" technolog$ for &indows a""lications) including su""ort for installation roll#ac' in case of installation issues. You can e%en create de"lo$ment "ac'ages for &e# a""lications that will allow $ou to install and run ASP.NET a""lications on a machine that does not currentl$ ha%e the .NET Framewor' installed. The de"lo$ment "ac'age will install all necessar$ run/time files for $ou.
30E &indows
&hile $ou wor' with Visual Studio .NET) $ou+ll encounter a wide %ariet$ of windows in the 30E) used for a wide %ariet$ of "ur"oses. Some are new) li'e the 0$namic <el" window descri#ed in the "re%ious section) while some will #e familiar to users of "re%ious %ersions of Visual Studio. 3n this section) we+ll ta'e a loo' at the most commonl$ used windows.
0esignerESource Editor This is where $ou+ll s"end most of $our time in the Visual Studio en%ironment. This window integrates almost all of the designers and source/code editors that $ou+ll use in Visual Studio) including the &e# Forms) -M. schema) and <TM. designers) as well as a
unified source/code editor that "ro%ides su""ort for -M.) <TM.) S:.) cascading st$le sheets ?,SSA) and all of the .NET languages. The editor "ro%ides enhanced features s"ecific to each language. Two new features of the <TM. and ,SS editors that are "articularl$ e1citing are 3ntelliSense statement com"letion for #oth <TM. and ,SS) and #etter control o%er how ?or ifA the editor modifies the format of $our <TM. and ,SS documents. To change the formatting settings) from the Tools menu) select *"tions. 3n the *"tions dialog #o1) select the Te1t Editor folder) then select the <TM. ?or ,SSA folder) and then select the Format o"tion. Buttons at the #ottom of the designerEeditor window allow $ou to change #etween 0esign and <TM. %iews of ASP.NET "ages) as well as #etween different modes for other document t$"es.
Solution E1"lorer The Solution E1"lorer window should #e familiar to an$one who+s used Visual 3nter0e% 6. 3t+s one of the "rimar$ tools $ou+ll use to manage "ro;ect files and resources) including adding) remo%ing) o"ening) renaming) and mo%ing files) as well as setting a start/u" "age or "ro;ect) switching #etween code and design %iew for a file) and %iewing status information ?for e1am"le) Source ,ode ,ontrol statusA on $our files. The following illustration shows the Solution E1"lorer.
,lass View The ,lass View window ?shown in the following illustrationA) which #$ default shares a window with the Solution E1"lorer) contains a listing of all classes ?contained in .%# or .cs modulesA in $our "ro;ects and the methods) "ro"erties) and interfaces im"lemented in those classes.
Ser%er E1"lorer The Ser%er E1"lorer) as shown in the following illustration) is a new feature of Visual Studio .NET that allows $ou to %iew resources on #oth $our local machine and remote ser%ers) including configured data connections) e%ent logs) message (ueues) and "erformance counters. The Ser%er E1"lorer also lets $ou drag and dro" resources onto &e# Forms "ages or .NET com"onents) allowing some of the most "roducti%e ser%er/side de%elo"ment a%aila#le to date. 3n the Standard edition of Visual Basic .NET) the Ser%er E1"lorer is limited to connecting to and %iewing data#ase o#;ects.
Pro"erties The Pro"erties window should #e immediatel$ familiar to an$one who+s used an$ of the Visual Studio suites of de%elo"ment tools. 3t "ro%ides access to the "ro"erties of the o#;ect currentl$ selected in the 30E. The Pro"erties window allows $ou to colla"se or e1"and categories of "ro"erties to #etter %iew the categories $ou+re interested in. You can also %iew the "ro"erties in al"ha#etical order #$ clic'ing the Al"ha#etic ?APA #utton) as shown in the following illustration) ;ust #elow the o#;ect selection dro"/down menu.
The Visual Studio .NET Tool#o1 The Visual Studio .NET Tool#o1 is another element modeled closel$ on the Visual 3nter0e% en%ironment. 3t "ro%ides access to a wide %ariet$ of controls) com"onents) and <TM. elements. You can add Tool#o1 items ?essentiall$) the <TM. tags or te1t elements used to im"lement controls or com"onentsA to &e# Forms or com"onents #$ either dou#le/clic'ing the item name in the Tool#o1 ?in which case the item is inserted at the current cursor locationA or #$ using drag/and/dro" ?allowing $ou to "lace the item where desiredA. Note that some items do not ha%e a %isual re"resentation when used in a &e# Form. These items will usuall$ #e dis"la$ed in a se"arate window area at the #ottom of the 0esigner window. The following illustration shows the Tool#o1 dis"la$ing the &e# Forms controls.
TIP You can add $our own items or categories ?called ta#sA in the Tool#o1. To add a ta#) sim"l$ right/clic' in the Tool#o1) select Add Ta#) and gi%e the ta# a name. To add $our
own items) ma'e sure the "ro"er categor$ ta# is selected) select the desired item in the 0esigner ?or te1t in the code editorA) and then drag it to the Tool#o1. You can gi%e the new item a descri"ti%e name #$ right/clic'ing it and selecting 7ename 3tem.
Tas' .ist An underrated and often underutiliGed tool from Visual 3nter0e%) the Tas' .ist window allows de%elo"ers to create) sort) and trac' tas's to #e com"leted for the current solution. The Tas' .ist also can contain tas's automaticall$ generated #$ Visual Studio to hel" de%elo"ers locate and correct #uild errors. Tas's can #e categoriGed and "rioritiGed according to the de%elo"er+s needs. ,ategories include ,omment tas's ?indicated #$ comment to'ens such as T+,+) !P-./,E0T+,+) and so onA) 9ser tas's) Build Errors) Shortcuts ?created #$ right/clic'ing a line of code in the editor and selecting Add Tas' .ist ShortcutA) and 3ntelliSense tas's) which are dis"la$ed when 3ntelliSense detects an error in $our code. The following illustration shows a Tas' .ist with a Shortcut tas') a 9ser tas') and a ,omment tas'.
*ut"ut The *ut"ut window will #e familiar to de%elo"ers who+%e used Microsoft+s Visual ,LL or Visual FLL tools. *ne of the "rimar$ "ur"oses of the *ut"ut window is to dis"la$ messages related to "ro;ect #uilds. ?A build is the "rocess of com"iling all of the code files that ma'e u" a "ro;ect.A Since $ou need to #uild $our ASP.NET &e# a""lication #efore code modifications will a""ear) $ou+ll #e seeing a lot of this window. The following illustration shows the out"ut of a #uild of a sam"le "ro;ect. 3n this case the #uild was successful) with no errors or warnings. <ad there #een #uild errors or warnings) the$ would ha%e #een dis"la$ed in this window.
Now that $ou+%e seen some of the main windows in the 30E) "ut $our 'nowledge to wor' #$ following these "rocedures.
!. ,lic' the L s$m#ol ne1t to the 1ont "ro"ert$ to e1"ose its su#/"ro"erties. 8. Select the 2old "ro"ert$) and then clic' its dro"/down list to change the "ro"ert$ %alue to True. Q. Select the Si3e "ro"ert$) and then clic' its dro"/down list to change the "ro"ert$ %alue to .arge. Note how the te1t dis"la$ed is modified in the following illustration.
6. ,enter the .a#el control o%er the image #$ clic'ing and dragging the control in the designer window) and then sa%e the file #$ clic'ing the Sa%e #utton) as shown in the following illustration) on the tool#ar. K. Browse the "age #$ right/clic'ing &elcome.as"1 in Solution E1"lorer and selecting View 3n Browser. The result should loo' similar to the following illustration.
Tool#ars
To accom"lish tas's in Visual Studio .NET) $ou+ll most li'el$ use a com#ination of the 30E+s tool#ars and menus. This section will ta'e a loo' at the most commonl$ used tool#ars) and the ne1t section will loo' at the most commonl$ used menus. You can %iew the full list of a%aila#le tool#ars #$ right/clic'ing an$ tool#ar ?or em"t$ tool#ar areaA. 3n 'ee"ing with the customiGa#le nature of the Visual Studio .NET 30E) all tool#ars can #e customiGed #$ adding) remo%ing) or rearranging #uttons) mo%ing tool#ars) and showing or hiding tool#ars. NOTE @i%en the fle1i#ilit$ of the Visual Studio .NET tool#ars) it+s eas$ to end u" with $our tool#ars loo'ing nothing li'e the$ did when $ou installed Visual Studio. For some de%elo"ers this might #e a good thing) #ut if $ou want to restore $our tool#ars to their original configuration) clic' the Tool#ar *"tions #utton ?which loo's li'e the arrow of a dro"/down list controlA found at the right end of each tool#ar) then clic' Add *r 7emo%e Buttons) then clic' the menu item for the tool#ar name) and then clic' 7eset Tool#ar.
Standard The Standard tool#ar) shown in the following illustration) contains #uttons for common file and "ro;ect commands) including o"ening files and "ro;ects) creating new files and "ro;ects) and accessing %arious windows in the 30E.
Formatting The Formatting tool#ar) shown in the following illustration) contains #uttons related to the formatting of te1t) including font and font siGe) te1t alignment o"tions) and #ac'ground and foreground colors. This tool#ar is ena#led onl$ when $ou+re entering or editing te1t in 0esign %iew.
Te1t Editor The Te1t Editor tool#ar) shown in the following illustration) contains #uttons related to the o"eration of the Te1t Editor) including access to 3ntelliSense features) indenting and commenting of code) and #oo'mar's. ?You can use these to na%igate (uic'l$ to s"ecific sections of $our code.A
0e#ug The 0e#ug tool#ar) shown in the following illustration) contains #uttons related to 0e#ugging commands) from Start) Sto") and Brea' commands to #uttons for accessing the %arious 0e#ug windows. 0e#ugging is co%ered in ,ha"ter 28.
Menus
A great man$ menus are a%aila#le in Visual Studio .NET) de"ending on the tas' $ou+re wor'ing on at an$ gi%en time. &hile we won+t go o%er all of them) the menus $ou+ll encounter most fre(uentl$ in $our Visual Studio tra%els are listed here.
File menu
The File menu is used to create) o"en) and sa%e files and "ro;ects) as well as to "rint files and to e1it the "rogram.
Edit menu The Edit menu is used for wor'ing with te1t and o#;ects such as ,ut) ,o"$) and Paste) as well as te1t/s"ecific commands such as Find and 7e"lace) and formatting commands such as Ma'e 9""ercase or Ma'e .owercase.
View menu The View menu is used to access windows or %iews that are currentl$ hidden. 9se this menu to switch from source code to design %iew or to o"en u" windows such as the Tas' .ist) as well as to choose which tool#ars are dis"la$ed.
Pro;ect menu The Pro;ect menu is used to add items to a "ro;ect) add references to assem#lies or &e# ser%ices) and set the start "age and start/u" "ro;ect used for de#ugging.
Build menu The Build menu is used for #uilding and re#uilding a "ro;ect or "ro;ects) as well as commands for de"lo$ing "ro;ects.
0e#ug menu The 0e#ug menu is used to start) sto") and "ause ?#rea'A de#ugging) and to set #rea'"oints and access de#ugging windows.
Ta#le menu The Ta#le menu is used for wor'ing with <TM. ta#les. 9se this menu to insert or delete ta#les) rows) columns) and cells) as well as to merge or s"lit cells.
Tools menu The Tools menu contains commands related to customiGing the 30E and e1ternal tools. You can use this menu to access the ,ustomiGe dialog #o1 discussed earlier) as well as the *"tions dialog #o1) discussed in the ne1t section.
:uer$ menu The :uer$ menu is used for creating and running data#ase (ueries using Visual Studio+s data#ase tools.
&indow menu The &indow menu is used to na%igate and manage the o"en document windows #eing used #$ the a""lication.
<el" menu The <el" menu is used to access the Visual Studio .NET documentation) as well as to access "roduct su""ort. This menu also contains a lin' to the Visual Studio .NET start "age that a""ears #$ default when $ou o"en Visual Studio. So if $ou accidentall$ close it) $ou can use this menu item to get it #ac'.
TIP 3n addition to these menus) $ou can create $our own custom menus. To create a custom menu) right/clic' an$where in the menu #ar and select ,ustomiGe. 3n the ,ustomiGe dialog #o1) clic' the ,ommands ta#. 9nder ,ategories) select New Menu. 9nder ,ommands) clic' and drag the New Menu item to the desired location in the menu #ar. Ne1t) right/clic' the new menu heading and use the Name entr$ to gi%e $our new menu a name. Now $ou can drag items from the other menu categories to $our new menu. To create a su#menu) drag another co"$ of the New Menu item into the desired location on $our menu.
*"tions
*ne of the most dramatic areas of im"ro%ement in Visual Studio .NET is in customiGation. Much of the customiGation a%aila#le in Visual Studio .NET is controlled from the *"tions dialog #o1) shown in the following illustration. As mentioned earlier) $ou can access this dialog #o1 #$ selecting Tools) and then *"tions. Not onl$ has the num#er of o"tions increased significantl$) #ut the degree of control o%er "articular o"tions has increased as well.
*ne good e1am"le of this increased control is in the area of code formatting. Visual 3nter0e% de%elo"ers will no dou#t remem#er the frustration of ha%ing the Visual 3nter0e% editor reformat their ASP code when switching from 0esign %iew to Source %iew. Visual Studio .NET still "erforms code formatting) #ut the de%elo"er has language/#$/language control o%er how this formatting is done. ?Note that not all languages use auto/formatting) so the$ won+t all ha%e these o"tions.A @o to the Te1t Editor o"tion folder) choose the language ?for e1am"le) <TM. or ,SSA)
and set the o"tions to $our "referred setting. 3n this wa$) $ou can determine how formatting is a""lied to $our code or) for some languages) $ou can turn off reformatting entirel$. NOTE *ne new o"tion that will a""eal to longtime BAS3, users is ha%ing the 30E dis"la$ line num#ers in the te1t editor. 9nli'e BAS3,) howe%er) the line num#ers are onl$ for referenceI the$+re not actuall$ a "art of the code. You can turn this o"tion on or off for indi%idual languages) or $ou can turn it on glo#all$ for all languages.
Familiar Features
3t+s im"ortant to note that man$ things in ASP.NET will #e familiar to &e# de%elo"ers who+%e used classic ASP. The much/used .e4uest and .esponse o#;ects are still there) as are the /pplication) Session) and Ser%er o#;ects) al#eit with some new "ro"erties and methods. You can still use either Rscript runat56ser%er7S #loc's or the R8 8S ASP scri"t delimiters to denote ser%er/side scri"t. 3n fact) for the most "art $ou can write an ASP.NET "age e1actl$ the same wa$ $ou would write a classic ASP "age. *nce $ou get used to the new "rogramming model of ASP.NET) though) $ou+ll ne%er go #ac' to coding $our ASP a""lications the wa$ $ou do toda$. Also) $ou don+t need to migrate all of $our e1isting ASP a""lications at once. ASP.NET is designed to run side #$ side with classic ASP. So while $ou+re wor'ing on $our first new ASP.NET a""lication) $our current ASP a""lications can still #e running right alongside.
!hat"s New
There+s a lot of new stuff in ASP.NET) and it will ta'e time to learn all of it. But once $ou+%e learned it) $our "roducti%it$ will #e far greater than it was with classic ASP. .et+s loo' at a list of some of the new features of ASP.NET. !e# $ r%s This is the new "rogramming model of ASP.NET. &e# Forms com#ines the #est of ASP with the ease of de%elo"ment and "roducti%it$ of Visual Basic. You can drag controls onto a "age and then write code to "ro%ide interacti%it$) call #usiness o#;ects) and more. You+ll learn a#out &e# Forms in ,ha"ter K. Ser&er c ntr ls A ma;or com"onent of the &e# Forms "rogramming model) the ASP.NET ser%er controls ma" a""ro1imatel$ to <TM. elements ?"lus some additional controls $ou+ll learn a#out laterA and "ro%ide "owerful ser%er/side "rogramma#ilit$. Ser%er controls are run on the ser%er and can out"ut <TM. that+s tailored for u"le%el #rowsers) such as 3nternet E1"lorer Q.1 or later) or for an$ <TM. !.2Tcom"liant #rowser. ,ha"ter D and ,ha"ter 2 will co%er ser%er controls in de"th.
!e# Ser&ices This is a 'e$ "art of ASP.NET that allows de%elo"ers to ma'e "rogrammatic ser%ices a%aila#le to other de%elo"ers o%er the 3nternet ?or a local intranetA. &e# Ser%ices are #ased on the emerging S*AP standard) so the$ will allow relati%el$ "ainless intero"eration across di%erse "latforms. You+ll learn more a#out &e# Ser%ices in ,ha"ter 22. 'aching ASP.NET includes a "owerful new caching engine that will allow de%elo"ers to im"ro%e the "erformance of their a""lications #$ reducing the &e# ser%er and data#ase ser%er "rocessing loads. You+ll learn more a#out caching in ,ha"ter 22. ' nfigurati n i%(r &e%ents ASP.NET uses a new method of storing configuration information for &e# a""lications. 3nstead of ha%ing 33S store this information in a hard/to/access data#ase) it+s stored in -M./#ased human/ and machine/reada#le configuration files) which also ma'e de"lo$ment easier. You+ll loo' at how these configuration files wor' in ,ha"ter Q. State %anage%ent i%(r &e%ents 3f $ou+%e had to #uild an ASP a""lication to run on a &e# farm) $ou 'now all too well that there were ma;or limitations to state management in classic ASP. ASP.NET o%ercomes these limitations) "ro%iding su""ort for distri#uting session state across &e# ser%ers) "ersisting state information in a Microsoft S:. Ser%er data#ase) and "ro%iding state management without the use of coo'ies. You+ll learn how to ta'e ad%antage of these features in ,ha"ter 8. Securit) This is an e1tremel$ im"ortant function in toda$+s &e# a""lications. The securit$ model in ASP.NET has #een su#stantiall$ im"ro%ed) including new and im"ro%ed authentication methods) code access securit$) and role/#ased authoriGation. You+ll loo' at the ASP.NET securit$ model and how to im"lement securit$ in $our ASP.NET a""lications in ,ha"ter 6. New in %ersion 2.2 of ASP.NET is a feature called 7e(uest Validation. This feature) which chec's form in"ut for scri"ts or <TM. and throws an e1ce"tion if such data is found) is designed to hel" de%elo"er "re%ent cross/site scri"ting attac's.
M #ile !e# A((licati n Su(( rt Version 2.2 of ASP.NET adds #uilt/in su""ort for the ASP.NET Mo#ile controls ?formerl$ the Microsoft Mo#ile 3nternet Tool'itA) which offer su""ort for #uilding &e# a""lications for mo#ile de%ices such as Personal 0igital Assistants ?P0AsA and cell "hones. Enhancing this su""ort is a new designer in the Visual Studio .NET 30E for mo#ile ASP.NET a""lications.
,reate a new &e# a""lication with Microsoft Visual Studio .NET. Add a &e# Forms "age to a &e# a""lication "ro;ect. Add Ser%er ,ontrols to a &e# Forms "age and modif$ their "ro"erties. &rite code in e%ent handlers. Build and test a &e# a""lication.
Now that $ou+%e learned a#out some of the features of Visual Studio .NET) the ne1t ste" is to ta'e ad%antage of them in $our own a""lications. ,on%enientl$ enough) that+s "recisel$ what $ou+re going to learn how to do in this cha"ter. You+ll #egin with an o%er%iew of the two ma;or "ro;ect t$"es used for ASP.NET a""lications. Then $ou+ll loo' at the file t$"es used in ASP.NET and the "ur"ose of each. Ne1t) $ou+ll learn how to create a new &e# a""lication) add a new &e# Forms "age) and add controls to the "age and mani"ulate their "ro"erties. Finall$) $ou+ll learn how to add e%ent/handler code to the "age) #uild the "ro;ect) and test the "age.
A %irtual director$ in 33S) configured as an a""lication root) to hold the files that ma'e u" the a""lication and to control access to the files. *ne or more .as"1 files. A @lo#al.asa1 file ?analogous to the @lo#al.asa file in classic ASPA to deal with Session and A""lication startu" and clean/u" logic. This file is o"tional. A &e#.config file used to store configuration settings. This file is o"tional) and is new for ASP.NET.
For Visual Studio .NET users) the good news is that all of the "receding files are created for $ou when $ou create a new &e# a""lication "ro;ect.
a""lication with code in the actual .as"1 file and still ta'e ad%antage of com"iled code and the other im"ro%ements of .NET) 3 recommend that $ou get in the ha#it of using code/#ehind modules. Visual Studio .NET defaults to using code/#ehind for 93/s"ecific "rogramming logic.
,ode/Behind
,ode/#ehind is a new feature in ASP.NET that allows de%elo"ers to trul$ se"arate the <TM. and tag/#ased 93 elements from the code that "ro%ides user interaction) %alidation) and so on. ,ode/#ehind modules offer de%elo"ers a num#er of ad%antages=
,lean se"aration of <TM. and code ,ode/#ehind allows <TM. designers and de%elo"ers to do what the$ do #est inde"endentl$) there#$ minimiGing the "ossi#ilit$ of messing u" one another+s wor' ?something that ha""ens all too fre(uentl$ when de%elo"ing classic ASP a""licationsA.
Easier reuse ,ode that isn+t inters"ersed with <TM. in an .as"1 "age can #e more easil$ reused in other "ro;ects.
Sim"ler maintenance Because the code is se"arated from the <TM.) $our "ages will #e easier to read and maintain.
0e"lo$ment without source code Visual Studio .NET "ro;ects using code/#ehind modules can #e de"lo$ed as com"iled code ?in addition to the .as"1 "agesA) allowing $ou to "rotect $our source code. This can #e %er$ useful if $ou+re creating a""lications for clients #ut want to retain control of $our intellectual "ro"ert$.
All in all) it+s worthwhile to get into the ha#it of using code/#ehind. You+ll see e1am"les of code/ #ehind throughout the #oo'.
allows com"uters on %ar$ing "latforms) from &indows ser%ers to 9N3- wor'stations) to offer and consume "rogrammatic ser%ices o%er the <TTP "rotocol. NOTE S*AP can use other "rotocols) such as FTP or SMTP) #ut <TTP is the most common "rotocol used with S*AP and &e# ser%ices #ecause most firewalls allow communication %ia the <TTP "rotocol. ASP.NET ma'es it remar'a#l$ eas$ to im"lement &e# ser%ices. 3n fact) all it ta'es is adding an a""ro"riate declaration to an$ method $ou want to ma'e a%aila#le as a &e# ser%ice. Visual Studio .NET ma'es it e%en easier #$ ta'ing care of all the wor' necessar$ to ma'e $our &e# ser%ice a%aila#le to "otential clients. Part 3V will discuss &e# ser%ices in greater detail.
A %irtual director$ in 33S) configured as an a""lication root) to hold the files that ma'e u" the a""lication and to control access to the files. *ne or more .as"1 files. Visual Studio .NET creates a single &e# form #$ default with the name Mo#ile&e#Form2.as"1. The default &e# Form contains a s"ecial :mobile:form; element) which acts as a container for mo#ile &e# ser%er controls ?formerl$ "art of the Microsoft Mo#ile 3nternet Tool'itA. These controls allow $ou to design a 93 for $our a""lication that automaticall$ ada"ts to a wide %ariet$ of mo#ile de%ices. A @lo#al.asa1 file to deal with Session and A""lication startu" and clean/u" logic. This file is o"tional. A &e#.config file used to store configuration settings. 3n a Mo#ile &e# A""lication "ro;ect created with Visual Studio .NET) this file also contains a set of filters that hel" tailor "age out"ut to %arious mo#ile de%ices. This file is o"tional.
As with the ASP.NET &e# A""lication tem"late) Visual Studio .NET creates all of the "receding files when $ou create a new ASP.NET Mo#ile &e# a""lication "ro;ect. You+ll learn more a#out de%elo"ing ASP.NET a""lications for mo#ile de%ices in ,ha"ter D.
.as"1 The e1tension $ou+ll see most often. Analogous to the .as" e1tension in classic ASP) .as"1 is used for &e# Forms "ages.
.asc1 The e1tension used for &e# Forms user controls. 9ser controls "ro%ide one of the man$ wa$s a%aila#le in ASP.NET to reuse code. Similar to include files in classic ASP) .asc1 files can #e as sim"le as a few <TM. tags or can include com"le1 logic that the author might want to reuse in man$ "ages. 9ser controls are added to a &e# Forms "age using the @ .egister directi%e) which is discussed in Part 333.
.asm1 The e1tension used for files that im"lement &e# ser%ices. &e# ser%ices can #e accessed directl$ through .asm1 files) or the .asm1 file can direct the re(uest to a com"iled assem#l$ that im"lements the &e# ser%ice.
.%# The e1tension for Visual Basic .NET code modules. All &e# Forms "ages ?.as"1A added to a Visual Studio .NET &e# a""lication that are written in Visual Basic .NET will ha%e a corres"onding .%# code/#ehind module with the same name as the &e# Form "age to which it+s related ?pagename.as"1.%#A.
.res1 0enotes a resource file. These files are used "rimaril$ in &indows Forms a""lications) #ut are also a%aila#le to &e# a""lication de%elo"ers for storing resources such as alternati%e te1t strings for internationaliGation of a""lications.
@lo#al.asa1 9sed to define A""lication/ and Session/le%el %aria#les and startu" "rocedures. @lo#al.asa1 is used the same wa$ as @lo#al.asa is used in classic ASP. Note that while @lo#al.asa1 can #e structured li'e @lo#al.asa) with startu" "rocedures such as Session0+nStart ?Session0Start in ASP.NETA coded directl$ in the @lo#al.asa1 file in a :script runat56ser%er7; #loc') Visual Studio im"lements these "rocedures in a .%# ?or .csA code/#ehind module ?glo#al.asa1.%#A rather than in the @lo#al.asa1 file itself.
3n addition to the functionalit$ a%aila#le in a classic ASP @lo#al.asa file) which was used for handling A""lication andEor Session start and end e%ents and declaring A""lication/ andEor Session/le%el %aria#les) ASP.NET also allows $ou to im"ort names"aces) lin' to assem#lies) and "erform other useful tas's. You+ll learn more a#out @lo#al.asa1 in ,ha"ter K.
&e#.config A new file t$"e in ASP.NET) used to sol%e one of the ma;or hassles with classic ASP a""lications= configuration. The &e#.config file is a human/ and machine/reada#le -M./ #ased file that stores all of the configuration settings for a gi%en a""lication ?or segment of an a""licationA. &e#.config files are inter"reted hierarchicall$Ba &e#.config file in a su#director$ of $our a""lication will o%erride the settings of the &e#.config file ?or filesA in its "arent directories. The ad%antage is that configuration settings can #e inherited where that is desira#le) #ut $ou also ha%e %er$ granular control o%er configuration.
7o#ust management of "ro;ect files and multi"le "ro;ects 3ntegration with the Microsoft Visual SourceSafe source/code control en%ironment Visual Tools for wor'ing with &e# ser%ices) &e# Forms ser%er controls) and data#ase tools Pac'aging and de"lo$ment ser%ices for &e# a""lications Su""ort for multi"le languages within a single 30E) including cross/language inheritance and de#ugging
That+s ;ust a #rief list. There+s much more to the tool than can #e co%ered in a single cha"ter. So without further ado) let+s loo' at how to create "ro;ects and "ages in the Visual Studio .NET en%ironment.
,reating A""lications
*ne of the first things $ou+re going to want to do in order to wor' with ASP.NET in Visual Studio .NET is create a new "ro;ect) or in Visual Studio .NET "arlance) a &e# a""lication.
,lic' the ,reate A New Pro;ect lin' on the Visual Studio .NET Start Page ?dis"la$ed #$ default when $ou first o"en Visual Studio .NETA. ,lic' the New Pro;ect #utton ?shown in the following illustrationA) located on the Standard tool#ar. From the File menu) select New) and then Pro;ect.
!. 3n the New Pro;ect dialog #o1 ?see the following illustrationA) under Pro;ect T$"es) select the Visual Basic Pro;ects folder) then select the a""ro"riate tem"late ?ASP.NET &e# A""licationA. T$"e the location as htt(,--l calh st-'ha(ter./*) and then clic' *>.
Visual Studio .NET will create a new &e# a""lication along with "h$sical and %irtual directories for the "ro;ect.
That+s itH You+%e created $our first ASP.NET &e# a""lication. Note that this a""lication is se"arate from the ,ha"terO 2 "ro;ect included with the "ractice file installation) which is contained in the as"nets#s solution. Ne1t we+ll loo' at how to add new "ages. 3n $our new &e# a""lication) $ou+ll notice that Visual Studio .NET has alread$ added a "age named &e#Form2.as"1 to the "ro;ect for $ou and o"ened it in the editor. Your Visual Studio .NET screen should loo' similar to the following illustration. <owe%er) since one "age is rarel$ enough for most sites) let+s loo' at how to add a new "age to $our &e# a""lication.
3n the Solution E1"lorer window) right/clic' the a""lication name) then select Add) and then select Add &e# Form) as shown in the following illustration.
*n the Visual Studio .NET tool#ar) clic' the Add New 3tem #utton ?shown in the following illustrationA and then select &e# Form from the Tem"lates list. From the Pro;ect menu) select Add &e# Form.
An$ of these methods will o"en the Add New 3tem dialog #o1) shown in the following illustration.
2. 3n the Add New 3tem dialog #o1) %erif$ that the &e# Form tem"late is selected and name the new "age <ello.as"1. ,lic' *"en. Visual Studio .NET creates the "age) adds it to the "ro;ect) and o"ens it in the &e# Forms 0esigner) as shown in the following illustration.
TIP &hile in the Add New 3tem dialog #o1) a #rief descri"tion of each tem"late is dis"la$ed along the #ottom of the list window. 3f $ou decide to #rowse the different tem"lates) don+t forget to select the "ro"er one ?&e# FormA #efore clic'ing *"en.
!. Sa%e the "age #$ selecting File) and then Sa%e filename) where filename is the name of the file $ou+re currentl$ editing ?or #$ clic'ing the Sa%e #utton on the tool#arA. 9ntil $ou add controls ?or <TM. elementsA) the "age will dis"la$ the following message in 0esign %iew.
Q. ,lic' the #ac'ground of the "age to "lace the cursor after the <abel control $ou added to the "age. 6. 9sing the Tool#o1 as in ste" !) add a Te$t2o$ control to the "age) and then add a 2utton control to the "age. K. 9sing the same techni(ue as in ste" 8) change the Te$t "ro"ert$ of the 2utton control to Su#%it. D. Sa%e the "age #$ clic'ing the Sa%e #utton ?shown in the following illustrationA on the tool#ar. You can also sa%e #$ selecting Sa%e :filename; from the File menu.
Q. Sa%e the code/#ehind module) which should now loo' li'e the following illustration.
2. Enter $our name in the te1t #o1 and clic' Su#mit. The result should #e similar to the following illustration. ?Note that the &e# tool#ar shows the address of the "age #eing #rowsed. You can enter this address in a #rowser window on $our machine to %iew the "age in a non/em#edded #rowser window.A
9se e1"ressions) %aria#les) and constants. 9se "rocedures. 9se flow control statements. <andle errors. 9se o#;ect/oriented "rogramming techni(ues.
This cha"ter is intended for readers who ha%e little or no direct "rogramming e1"erience. 3t+s designed to gi%e a #rief o%er%iew of some #asic "rogramming conce"ts that will hel" $ou #etter understand the e1am"les "resented throughout the #oo'. 7eaders with "rogramming e1"erience might want to s'i" this cha"ter and mo%e on to ,ha"ter 8. &hile this cha"ter will "ro%ide an o%er%iew of #asic "rogramming conce"ts) 3 encourage readers with little hands/on "rogramming e1"erience to use other resources to su""lement this information. These resources include #oo's on "rogramming #asics) &e# sites such as the Microsoft 0e%elo"er Networ' ?MS0NA site ?http://msdn.microsoft.comA) and newsgrou"s and mailing lists. ?Microsoft maintains a large num#er of newsgrou"s on de%elo"ment to"ics related to Microsoft tools at news://msnews.microsoft.com. You can read from and "ost to these newsgrou"s using a newsreader such as Microsoft *utloo' E1"ress.A And the ASP.NET de%elo"ment team at Microsoft has ;ust launched a set of discussion forums on ASP.NET that "romise to #e a great resource as well. You can find these forums at http://www.asp.net/forums/. *f course) one of the #est ?and most o%erloo'edA resources for "rogramming conce"ts in Microsoft Visual Basic .NET is the MS0N documentation that shi"s with Visual Basic .NET ?a su#set of which is also a%aila#le as "art of the (uarterl$ MS0N li#rar$) which $ou can order from http://msdn.microsoft.com/subscriptionA. The MS0N documentation contains sam"les) tutorials) language references) and s"ecifications for Visual Basic .NET) Microsoft Visual ,J .NET) managed e1tensions for ,LL) and FScri"t .NET. This cha"ter will discuss how these #asic "rogramming conce"ts a""l$ to ASP.NET) and how $ou can use them to create effecti%e ASP.NET a""lications. Although most of these conce"ts aren+t language/s"ecific) there are some su#tle differences in how the$+re im"lemented in ,J %s. Visual Basic .NET or other .NET languages. NOTE 3n ASP.NET) all code is contained in either &e# Forms "ages) code/#ehind modules) or modules that ma'e u" class li#raries that are e1ternal to $our ASP.NET a""lications. The term module in this sense refers to the .cs or .%# file that contains the code) while module as referred to #$ the
Visual Basic .NET documentation is a container of code that is made a%aila#le to other classes and modules within the same names"ace. 9nless otherwise s"ecified) the term module in this #oo' has the former meaning rather than the latter. A class) as $ou+ll see in 49sing ,lasses as ,ontainers for ,ode5 later in this cha"ter) is a s"ecial t$"e of code container that "ro%ides a num#er of useful features. ,lasses are contained within modules ?that is) files with the e1tension .cs or .%#A. A namespace contains one or more classes) and can #e defined in one or more modules. Names"aces can #e used to "re%ent name collisions when two classes ha%e the same name.
E1"ressions
E1"ressions are central to %irtuall$ all com"uter "rograms. Among other ca"a#ilities) e1"ressions let $ou
An e1"ression li'e this isn+t %er$ useful #$ itself) howe%er. 9nli'e "eo"le) who can easil$ recogniGe 4one "lus one5 and fill in the #lan' ?4e(uals two5A) com"uters aren+t ca"a#le of that 'ind of lea" of logic. 3n order for the e1"ression to #e useful) it needs to tell a com"uter not ;ust to add one and one) #ut to store the result somewhere so that we can ma'e use of it later ?either #$ dis"la$ing it to the user or using it in another e1"ression laterA. This is where %aria#les come in.
Varia#les
At some "oint during the e1ecution of most "rograms) $ou+ll need to store %alues of some sort) such as the results of com"arisons or mathematical o"erations ?as in the "receding e1am"leA) or te1t in"ut acce"ted from users. Sim"l$ "ut) %ariables are storage areas for data. This data can #e numeric) te1t) or an$ one of a num#er of s"ecial data t$"es.
0ata T$"es
The data type of a %aria#le defines the t$"e of data that can #e stored in it) as well as the format in which that data is stored ?and the amount of memor$ that the s$stem needs to allocate for the %aria#leA. Ta#le !/2 lists the data t$"es su""orted #$ Visual Basic .NET and ,J) as well as the Microsoft .NET Framewor' S0> t$"es to which the$ ma". The data t$"es mar'ed with an asteris' ?VA don+t ha%e a nati%e re"resentation) #ut $ou can still access these data t$"es #$ using the a""ro"riate System ?or .NET Framewor'A t$"e when declaring the %aria#le. The data t$"e of a %aria#le is determined at the time the %aria#le is declared. This will #e discussed further in the section entitled 40eclaring Varia#les5 later in the cha"ter. Ta#le 234. ,ata Types C# Data Type bool byte sbyte char decimal double int uint long ulong ob*ect short ushort float string struct Visual Basic Data Type 2oolean 2yte ? =har ,ate ,ecimal ,ouble "nteger ? <ong ? +b*ect Short ? Single String !serC,efined Type .NET Data Type System.2oolean System.2yte System.S2yte @ System.=har System.,ateTime System.,ecimal System.,ouble System."ntA( System.!"ntA( @ System."nt&B System.!"nt&B @ System.+b*ect System."nt>& System.!"nt>& @ System.Single System.String System.DalueType ?inheritedA Size 2 #$tes 2 #$te 2 #$te 2 #$tes D #$tes 26 #$tes D #$tes 8 #$tes 8 #$tes D #$tes D #$tes 8 #$tes ?"lus the siGe of the o#;ect+s dataA 2 #$tes 2 #$tes 8 #$tes From to 2 #illion 9nicode characters Sum of mem#er siGes
IMPORTANT ASP.NET contains #oth framewor'/s"ecific data t$"es and language/s"ecific data t$"es for s"ecific .NET languages) such as Visual Basic .NET and ,J. To ta'e ad%antage of some of the multilanguage features of the .NET en%ironment) $ou need to limit $our use of data t$"es to those su""orted #$ the ,ommon .anguage S"ecification ?,.SA) a su#set of the data t$"es su""orted #$ the common language runtime ?,.7A. 3n the "receding ta#le) data t$"es mar'ed with W are not ,.S/com"liant. A%oid using them in classes that $ou want to ma'e a%aila#le for use with other .NET languages. 0ata t$"es mar'ed with V do not ha%e a language/s"ecific re"resentation) so if $ou want to use these t$"es $ou need to use the .NET Framewor' t$"e.
' x*"ession to assi)n t+e ,alue 1$3 !i"ectl' to t+e ,a"iable &'(nt = 1$3
TIP The "receding code e1am"le uses comments to "ro%ide an additional e1"lanation of what the code in the e1am"le is used for. ,omments are lines ?or "ortions of linesA of code that use a s"ecial character that tells the language com"iler to ignore them when com"iling the code. 3n Visual Basic .NET) the single (uote character ?+A is used to "recede a comment. &ith the e1ce"tion of a single (uote contained within dou#le (uotes ?which re"resents a literal stringA) e%er$thing following a single (uote on the same line is ignored #$ the com"iler. This means that $ou can "ut comments on the same line as the code the$ refer to or on their own line) as in the "receding e1am"le. For comments that s"an more than one line) each line must #e "receded with the comment character. 9sing comments is a good ha#it to get into #ecause comments ma'e $our code easier to read and understand. You should consider using comments e%en if $ou+re the onl$ one who+ll e%er see the code since comments are %er$ useful when $ou ha%e to re%ise code that $ou wrote months or $ears #efore) when it might no longer #e clear wh$ $ou wrote the code the wa$ $ou did.
7eference t$"es are data t$"es that store a reference to another memor$ location that contains the data) which is usuall$ #ased on a class) such as the String class in the .NET Framewor'. 7eference t$"es include +b*ect ?which acts as a re"lacement for Visual Basic+s Dariant t$"e) no longer su""orted in .NETA) String) and all /rrays) as well as instances of custom classes. 7eference t$"es are accessed through mem#ers of the class that the t$"e holds a reference to) as in the following e1am"le=
'%e#ine a class -lass &'.a&*le-lass /ublic &'(nt 0s (nte)e" n! -lass
' x*"ession to assi)n t+e ,alue 1$3 to &'-lass(nstance &e&be" &'(nt &'-lass(nstance.&'(nt = 1$3
0eclaring Varia#les
Before $ou can use %aria#les in $our "rograms) $ou need to declare them. Dariable declaration is the "rocess of s"ecif$ing the characteristics of the %aria#le ?name) data t$"e) lifetime) sco"e) and accessi#ilit$A so that the run/time s$stem 'nows how much storage s"ace to allocate for the %aria#le) which actions to allow on the %aria#le) and who can ta'e those actions. A %aria#le declaration ta'es the following form in Visual Basic .NET=
'%ecla"es a ,a"iable o# t'*e (nte)e" %i& x 0s (nte)e"
TIP The "receding e1am"le uses $ as the name of the %aria#le. &hile this is "erfectl$ acce"ta#le as far as the language com"ilers are concerned) $ou should consider gi%ing $our %aria#les more meaningful names) such as 1irstName ?for a string %aria#le holding a first nameA) <oop=ount ?for a numeric %aria#le used in a loo"ing structureA) or Person ?for a reference to a class re"resenting data on a "ersonA. This naming con%ention ma'es it much easier to remem#er the "ur"ose of a %aria#le) and it will ma'e $our code much easier to maintain. You can find naming guidelines for use in .NET class li#raries at http://msdn.microsoft.com/library/enC us/cpgenref/html/cpconnetframeworkdesignguidelines.asp and s"ecificall$ for Visual Basic .NET at http://msdn.microsoft.com/library/enCus/%bcn'/html/%aconD2Naming.ules.asp. The "receding declaration s"ecifies a %aria#le of t$"e "nteger ?which ma"s to the System."ntA( t$"eA. 3n this case) the %aria#le) $) would #e accessi#le onl$ within the module) "rocedure) or
#loc' in which the declaration a""eared. 3n addition to sim"le declarations li'e these) $ou can use the "lacement of the declarations) as well as Visual Basic .NET 'e$words) to modif$ the lifetime) sco"e) and accessi#ilit$ of $our %aria#les.
Varia#le .ifetime
<ifetime refers to the s"an of time from when the %aria#le is declared to when it is destro$ed. The lifetime of a %aria#le de"ends on where it is declared. For e1am"le) the lifetime of a %aria#le declared inside a "rocedure is limited to the e1ecution of the "rocedure. *nce the "rocedure has finished e1ecuting) the %aria#le is destro$ed and the memor$ it occu"ied is reclaimed. The following code illustrates a "rocedure/le%el declaration=
'Visual Basic .N T .ub *"oce!u"e .ub Hello4o"l!23 '%ecla"e *"oce!u"e5le,el st"in) ,a"iable %i& Hello.t"in) 0s .t"in) Hello.t"in) = "Hello 4o"l!!" '4"ite Hello.t"in) to b"o1se" 6es*onse.4"ite2Hello.t"in)3 'Li#eti&e o# Hello.t"in) 1ill en! a#te" next line n! .ub
&hen this "rocedure com"letes) the %aria#le <elloString no longer e1ists. 3ts lifetime has ended. 3f <elloString had #een declared outside the "rocedure) as shown in the following code e1am"le) its lifetime would ha%e lasted until the instance of the class containing it was destro$ed.
'%ecla"e &o!ule5le,el st"in) ,a"iable %i& Hello.t"in) 0s .t"in)
'Visual Basic .N T .ub *"oce!u"e .ub Hello4o"l!23 Hello.t"in) = "Hello 4o"l!!" '4"ite Hello.t"in) to b"o1se" 6es*onse.4"ite2Hello.t"in)3 'Li#eti&e o# Hello.t"in) 1ill not en! a#te" next line
n! .ub
Naming ,on%entions and ,ase The Visual Basic .NET documentation recommends that $ou use whole words when naming $our %aria#les. You should use mi1ed case) with the first letter of each word ca"italiGed) as in <elloString. This is called Pascal case. This is one of man$ "ossi#le naming con%entions $ou can use for %aria#les and other elements in $our "rograms. Naming con%entions are sim"l$ agreed/ u"on standards for how elements will #e named in a "rogram. For instance) using an initial lowercase character and ca"italiGing the first character of each word is called ,amel case. The "articular naming con%ention $ou choose isn+t im"ortant) #ut $ou should choose one and use it consistentl$. 0oing so will ma'e it easier for $ou to maintain $our code and will hel" others understand what $our code is doing. ,onsistent use of a %aria#le naming con%ention is es"eciall$ im"ortant when se%eral de%elo"ers are wor'ing together on the same "ro;ect. You can e1tend the lifetime of a "rocedure/le%el %aria#le through the use of the Visual Basic .NET Static 'e$word in "lace of the ,im 'e$word used earlier. ?3n ,J) $ou would use the static modifier.A 3n the following e1am"le) 9y"nt is declared within the "rocedure) #ut #ecause it+s declared as Static) its lifetime continues until the class or module containing the "rocedure has finished running=
'Visual Basic.N T .ub *"oce!u"e .ub 0!!(nt23 '%ecla"e a static (nte)e" ,a"iable .tatic 7'(nt 0s (nte)e" ' 0!! 8 to 7'(nt 7'(nt += 8 '4"ite 7'(nt to b"o1se" 6es*onse.4"ite27'(nt.To.t"in)233 'Li#eti&e o# 7'(nt 1ill not en! a#te" next line n! .ub
Because 9y"nt is declared as Static) each call to /dd"ntE F will result in 9y"nt #eing incremented #$ Q. 3f 9y"nt was instead declared using ,im) each call to /dd"ntE F would result in 9y"nt #eing set to Q.
Sco"e
Scope refers to the region of code in which a %aria#le can #e accessed. The sco"e of a %aria#le de"ends on where the %aria#le is declared) and in Visual Basic .NET it can include the following le%els.
Bloc' le%el Varia#les declared within statement #loc's such as "f G Then) 1or G Ne$t) or ,o G <oop. Although the sco"e of #loc'/le%el %aria#les is limited to the #loc' in which the$+re declared) their lifetime is that of the "rocedure in which the #loc' a""ears.
Procedure le%el These %aria#les are %isi#le onl$ within the "rocedure in which the$+re declared.
Module le%el 3n modules) classes) or structures) an$ %aria#le declared outside of a "rocedure is referred to as a module/le%el %aria#le.
Names"ace le%el Varia#les declared at module le%el) #ut gi%en "u#lic accessi#ilit$ ?Public or 1riendA) are referred to as names"ace/le%el %aria#les. The$+re a%aila#le to an$ "rocedure in the same names"ace that contains the module in which the %aria#le is declared.
NOTE The accessi#ilit$ of names"ace/ and module/le%el %aria#les is determined #$ an$ accessi#ilit$ 'e$words used in their declaration. ?See 4Accessi#ilit$5 later in this cha"ter.A Names"aces A namespace is a container used for sco"ing. Names"aces can contain classes) structures) enumerations) interfaces) and delegates. B$ using names"aces) $ou can ha%e more than one class in a gi%en "rogram with the same name) as long as the classes reside in different names"aces. 9sing names"aces can hel" ensure that code created #$ multi"le teams of de%elo"ers can #e com#ined to create larger s$stems without name collisions. Names"aces are declared in Visual Basic .NET using the Namespace G End Namespace s$nta1) where these statements #rac'et the classes) structures) and so on to #e contained within the names"ace. ,J uses the namespace H I s$nta1) where the classes and other t$"es to #e contained within the names"ace are #rac'eted #$ the curl$ #races. Names"aces can also #e nested within other names"aces) forming a hierarch$. This structure allows $ou to com#ine classes into logical grou"ings) ma'ing it easier for those using $our names"aces to find the classes the$+re loo'ing for. Effecti%e use of names"aces will ma'e $our a""lication more memor$/efficient and will ma'e maintaining $our code easier. The im"ortant distinction #etween lifetime and sco"e is that a %aria#le might #e out of sco"e ?that is) una%aila#leA without ha%ing reached the end of its lifetime. The "receding e1am"le of a
Static %aria#le that+s declared within a "rocedure is a good illustration of this distinction. 3n that e1am"le) the %aria#le 9y"nt will continue to e1ist e%en after the "rocedure in which it+s declared has com"leted) #ut #ecause it has "rocedure/le%el sco"e) it+s onl$ accessi#le within the "rocedure. <ere are some good "rogramming "ractices to follow=
.imit $our %aria#les to the narrowest "ossi#le sco"e that will allow $ou to accom"lish $our o#;ecti%es. A%oid using the same name for %aria#les of different sco"e within the same module) e%en where it is allowed. 9sing the same name in such situations can lead to confusion and errors. Since module/le%el and Static %aria#les all continue to consume memor$ as long as the class or module is running) use them onl$ when necessar$.
Accessi#ilit$
The last im"ortant conce"t in %aria#le declaration is accessi#ilit$. The accessi#ilit$ of a %aria#le determines whether it can #e accessed from outside the module ?or a""licationA in which it+s declared. 3n Visual Basic .NET) accessi#ilit$ is determined #$ declaring $our %aria#le with one the following 'e$words) instead of ,im.
Public Varia#les declared with the Public 'e$word are accessi#le from an$where in the same module ?or classA in which the$+re declared) from the names"ace containing that module) and from an$ other a""lications that refer to the a""lication in which the$+re declared. The$ can #e used onl$ at the module or class le%el) or within Structures.
1riend Varia#les declared with the 1riend 'e$word are accessi#le from an$where in the same module ?or classA in which the$+re declared) as well as from the names"ace containing that module.
Protected Varia#les declared with the Protected 'e$word are accessi#le onl$ within the class in which the$+re declared or within a class that inherits from that class. ?See 49sing 3nheritance5 later in this cha"ter.A The Protected 'e$word can #e com#ined with the 1riend 'e$word and can #e used onl$ to declare class mem#ers.
Pri%ate Varia#les declared with the Pri%ate 'e$word are accessi#le onl$ from the module) class) or structure in which the$+re declared. 3n classes or modules) declaring a %aria#le with ,im or
Pri%ate has the same effect on the %aria#le+s accessi#ilit$) #ut Pri%ate ma'es $our intentions more e1"licit. The Pri%ate 'e$word cannot #e used within a "rocedure. NOTE 3n ,J) all %aria#les must #e declared #efore the$ can #e used. Failure to declare a %aria#le will result in a com"iler error. 3n Visual Basic .NET and some other languages) it+s "ossi#le ?#ut not ad%isa#leA to use %aria#les without first declaring them. 9sing %aria#les that ha%e not #een e1"licitl$ declared is a ma;or source of #ugs in Visual Basic "rograms and should #e a%oided. The Visual Basic +ption E$plicit statement ?"laced at the to" of a module or classA re(uires that all %aria#les in that module #e e1"licitl$ declared.
'tu"ns 9*tion 9*tion x*licit on
x*licit 9##
To further "rotect $our code from inad%ertent #ugs) $ou can also use the new +ption Strict statement. &hen +ption Strict is on) con%ersions #etween data t$"es that would result in data loss ?also 'nown as narrowing con%ersions) such as con%erting a Single containing the %alue 2.2Q to an 3nteger) which would result in the 3nteger %aria#le ha%ing the %alue 2A are disallowed) as are con%ersions #etween strings and numeric t$"es.
'tu"ns 9*tion .t"ict on 9*tion .t"ict 9n 'tu"ns 9*tion .t"ict o## 9*tion .t"ict 9##
You can also set +ption E$plicit and +ption Strict in the "ro;ect "ro"erties for the "ro;ect) in which case the$ will a""l$ to all classes in the "ro;ect. Following these guidelines can hel" reduce the num#er of #ugs in $our code) and more im"ortantl$) the time $ou s"end trac'ing them down. The *"tion Strict statement includes all of the restrictions of *"tion E1"licit) so it is not necessar$ to use #oth.
,onstants
,onstants are similar to %aria#les) e1ce"t for one im"ortant detail= *nce a constant has #een declared and initialiGed) its %alue cannot #e modified. ,onstants are %er$ useful when $ou ha%e a literal %alue that $ou want to refer to #$ name. For e1am"le) in a "rogram that calculates
shi""ing weights in "ounds and ounces) $ou might want to create a constant to refer to the num#er of ounces in a "ound=
-onst 9unces(n0/oun! 0s (nte)e" = 1:
An$where within $our "rogram ?su#;ect to the same sco"e) lifetime) and accessi#ilit$ rules as %aria#lesA $ou can use the constant name +unces"n/Pound instead of the literal %alue >&. ,onstants are "articularl$ hand$ in "lace of literal %alues used as the arguments to methods of com"onents $ou might use. For e1am"le) in classic Microsoft Acti%e- 0ata *#;ects ?A0*A) the data t$"es of stored "rocedure "arameters were re"resented #$ numeric %alues. Tr$ing to remem#er all of those %alues would #e unrealistic) so the de%elo"ers of A0* also made it "ossi#le to use constants ?ad"nteger) adDar=har) and so onA in "lace of the literal %alues. 3n other words) constants let $ou su#stitute eas$/to/remem#er names for difficult/to/remem#er literal %alues. This can ma'e $our code easier to write and maintain) since $ou can u"date the %alue in a single location ?the constant initialiGationA) rather than ha%ing to search $our code for e%er$ instance of a literal %alue.
Enumerations
Man$ constants used with ASP.NET are actuall$ created using enumerations. 9sing enumerations allows $ou to define a set of related constants and access them in a t$"e/safe wa$. For instance) if $ou ha%e a "rocedure that acce"ts numeric %alues) from 2 to !) re"resenting a color) it might loo' li'e this=
.ub .et-olo"2B'Val -olo" 0s (nte)e"3 (# -olo" = 3 T+en '-o!e to a**l' colo" settin) 3. n! (# n! .ub
This method will) in fact) ha""il$ acce"t an$ integer %alue. To limit the "ossi#le %alues) $ou could declare an enumeration as follows=
nu& -olo"T'*e 0s (nte)e" 6e!=1 ;"een Blue n! nu&
B$ default the first element of an enumeration is e(ual to . 3n this e1am"le) since $ou want an enumeration that contains 2 through !) $ou set the first %alue in the enumeration to 2) and then the su#se(uent %alues are each incremented #$ one. So) -reen is 2 and 2lue is !. Now) rather than the "re%ious "rocedure declaration) $ou could use the following=
.ub .et-olo"2B'Val -olo" 0s -olo"T'*e3 (# -olo" = -olo"T'*e.Blue T+en '-o!e to a**l' t+e colo" settin) blue. n! (# n! .ub
This "rocedure will re(uire an instance of the =olorType enumeration to #e "assed as the "arameter) ensuring that the %alue is a %alid mem#er of the enumeration) and thus that the %alue re"resents a %alid color. The following is an e1am"le of calling Set=olor with a =olorType enumeration mem#er=
.et-olo"2-olo"T'*e.Blue3
Pr cedures
Procedures are an im"ortant tool in ASP.NET de%elo"ment #ecause the$ allow $ou to determine at the time that $ou write the code the order in which sections of code will run at run time. Procedures also allow $ou to #etter organiGe $our code into discrete units #ased on the functionalit$ "ro%ided #$ each one. For e1am"le) if $ou write code that multi"lies two num#ers and returns the result) that code is much more useful if it+s wra""ed in a "rocedure. 9sing a "rocedure allows the code to #e called from more than one "lace in $our a""lication as necessar$) which allows $ou to reuse the code rather than rewriting it each time $ou need to multi"l$ two num#ers. 3n Visual Basic .NET) $ou+ll use two main t$"es of "rocedures= Sub "rocedures and 1unction "rocedures. ?,J has functions onl$.A
Sub Procedures
A Sub "rocedure e1ecutes code #ut doesn+t return a %alue. ,ode contained in a Sub "rocedure is delimited #$ the Sub and End Sub statements) as follows=
'.ub *"oce!u"e t+at 1"ites out*ut to t+e b"o1se"
A Visual Basic .NET Sub "rocedure is e(ui%alent to a ,J function declared with the %oid modifier.
'B'6e# exa&*le .ub 7o!i#'(nt2B'6e# &'(nt 0s (nte)e"3 '0!! 4$ to &'(nt &'(nt = &'(nt + 4$ 'T+e o"i)inal ,alue o# &'(nt in t+e callin) '*"oce!u"e +as no1 been &o!i#ie!. n! .ub
'(&*licit B'Val exa&*le .ub 7o!i#'(nt2&'(nt 0s (nte)e"3 '0!! 4$ to &'(nt &'(nt = &'(nt + 4$ 'T+e o"i)inal ,alue o# &'(nt in t+e callin) '*"oce!u"e +as not been &o!i#ie!. n! .ub
Note that Visual Studio .NET will not allow the im"licit use of 2yDal. 3f $ou add the "receding code to a class in Visual Studio .NET) it will automaticall$ "refi1 arguments with 2yDal unless $ou e1"licitl$ "refi1 them with 2y.ef. You can "ass more than one "arameter to a "rocedure sim"l$ #$ se"arating each "arameter with a comma) as in the following e1am"le=
.ub 4"iteHello2B'Val Na&e1 0s .t"in), B'Val Na&e$ 0s .t"in)3 6es*onse.4"ite2"Hello to bot+ " & Na&e1 & " an! " & Na&e$3 n! .ub
Note that $ou e1"licitl$ declare the data t$"e of each "arameter as String. 3f an$ data t$"e other than String is "assed to the "rocedure) an e1ce"tion will #e thrown. ?An e1ce"tion) which $ou+ll learn more a#out later in the cha"ter) is similar to an error.A NOTE 3n Visual Basic 6) the default for a "arameter definition without the 2yDal or 2y.ef 'e$words is to "ass the "arameter #$ reference. Because this #eha%ior is the o""osite of that of the %ast ma;orit$ of languages) the Visual Basic de%elo"ment team has changed this #eha%ior in Visual Basic .NET. 3n Visual Basic .NET) "arameters defined without the 2yDal or 2y.ef 'e$words are "assed #$ %alue. &hether $ou+re writing Visual Basic 6 code that might need to #e u"graded to Visual Basic .NET or writing nati%e Visual Basic .NET code) it+s a good "rogramming "ractice to alwa$s use 2yDal and 2y.ef to e1"licitl$ declare how $our "arameters should #e "assed. You can ma'e one or more of the "arameters of $our "rocedure o"tional ?meaning the caller decides whether the "arameter will #e "assed or notA #$ "receding them with the +ptional 'e$word.
.ub 4"iteHello29*tional B'Val Na&e1 0s .t"in) = "Bob"3 6es*onse.4"ite2"Hello, " & Na&e1 & "!"3 n! .ub
&hen $ou use o"tional "arameters) $ou must su""l$ a default %alue for each one) as in the "receding e1am"le. Also) once $ou+%e declared an o"tional "arameter) all su#se(uent "arameters for that "rocedure must also #e o"tional. Finall$) $ou can change the accessi#ilit$ of Sub "rocedures using the Public) Pri%ate) 1riend) and Protected 'e$words. Sub "rocedures are "u#lic #$ default) which means the$ can #e called from an$where within $our a""lication.
1unction Procedures
1unction "rocedures in Visual Basic .NET are ;ust li'e Sub "rocedures) e1ce"t for one im"ortant detailBthe$ can return a %alue. &ith a 1unction "rocedure) $ou could
7eturn a numeric %alue re"resenting an error or success code 7eturn data in the form of an arra$ or an A0*.NET dataset 7eturn True or False to indicate the results of some conditional test
The following code e1am"le ta'es two string "arameters) concatenates them) and then returns the result to the caller as a string=
Function -oncat.t"in)s2B'Val .t"in)1 0s .t"in), < B'Val .t"in)$ 0s .t"in)3 0s .t"in) -oncat.t"in)s = .t"in)1 & .t"in)$ n! Function
NOTE The "receding e1am"le uses the underscore character ?OA to #rea' a line that is too long to #e dis"la$ed on a single line. This character is referred to in Visual Basic as the line continuation character) and $ou+ll see it in man$ e1am"les throughout the #oo'. 9sing the line continuation character can ma'e $our code easier to read) since $ou won+t need to scroll horiGontall$ to see all of the code. Notice that since the 1unction "rocedure itself is declared as a string) $ou don+t need to create a local %aria#le to hold the result of concatenating the two strings. 3nstead) sim"l$ assign the result to the function name to return it to the caller.
$l w ' ntr l
Another im"ortant "iece of an$ "rogram is flow control) which allows $ou to determine at run time which sections of $our code will run and in what order. Flow control statements are the
foundation of #usiness logic and consist of conditional logic ?including "f and =ase statementsA) loo"ing structures ?1orG and ,oG loo"sA) and error/handling statements.
"f Statements
"f statements are the decision structures that $ou will "ro#a#l$ use most in $our "rograms. The$ allow $ou to loo' for a defined logical condition in $our "rogram and e1ecute a s"ecific #loc' of code if that condition is true. The following code chec's a %aria#le stored in the Session o#;ect for the logged/in username ?set in the login "ageA to "re%ent a user who has not logged into $our ASP.NET a""lication from %iewing "ages that re(uire a login=
(# .ession2"Lo))e!(n=se"Na&e"3 = "" T+en 6es*onse.6e!i"ect2"Lo)in.as*x"3 n! (#
3n Visual Basic .NET) an "f statement #loc' alwa$s re(uires an accom"an$ing End "f statement to denote the close of the "f #loc'. You can also "ro%ide code that will e1ecute if the defined condition is false #$ adding the Else statement) and $ou can test for more than one condition #$ using one or more Else"f statements. These techni(ues are shown in the following e1am"le=
(# .ession2"Lo))e!(n=se"Na&e"3 = "" T+en 6es*onse.6e!i"ect2"Lo)in.as*x"3 lse(# .ession2"Lo))e!(n=se"Na&e"3 = ".u*e"=se"" T+en 6es*onse.4"ite2">ou a"e a su*e"use"! "3 lse 6es*onse.4"ite2"Hello, " & .ession2"Lo))e!(n=se"Na&e"3 & "!"3 n! (#
NOTE Visual Basic .NET also su""orts single/line "f statements) such as the following=
(# 1 ? $ T+en 6es*onse.4"ite2"1 is less t+an $"3
This s$nta1 should #e used onl$ for %er$ sim"le "f statements) since single/line "f statements are inherentl$ more difficult to read and de#ug.
code chec's to see which item of a list #o1 was chosen #$ a user) and then it ta'es a""ro"riate action.
%i& -olo".t"in) 0s .t"in) -olo".t"in) = 6e@uest.Fo"&2"-olo"s"3 .elect -ase -olo".t"in) -ase "6e!" 6es*onse.4"ite2"?#ont colo"='" & -olo".t"in) & "'A"3 6es*onse.4"ite2">ou c+ose 6e!"3 6es*onse.4"ite2"?B#ontA"3 -ase ";"een" 6es*onse.4"ite2"?#ont colo"='" & -olo".t"in) & "'A"3 6es*onse.4"ite2">ou c+ose ;"een"3 6es*onse.4"ite2"?B#ontA"3 -ase "Blue" 6es*onse.4"ite2"?#ont colo"='" & -olo".t"in) & "'A"3 6es*onse.4"ite2">ou c+ose Blue"3 6es*onse.4"ite2"?B#ontA"3 n! .elect
You can also add a =ase Else statement to e1ecute s"ecific code when the tested e1"ression doesn+t match an$ of $our listed %alues) as the following code demonstrates=
.elect -ase -olo".t"in) -ase "6e!" '... -ase ";"een" '... -ase "Blue" 6es*onse.4"ite2"?#ont colo"='" & -olo".t"in) & "'A"3 6es*onse.4"ite2">ou c+ose Blue"3 6es*onse.4"ite2"?B#ontA"3
-ase
lse
3t+s good "rogramming "ractice to alwa$s ha%e a =ase Else statement) ;ust in case there are une1"ected %alues for the e1"ression $ou+re testing ?such as =olorString in this e1am"leA.
Q. Mo%e the mouse "ointer o%er the Tool#o1 on the left side of the screen. The Tool#o1 will a""ear. Place a label) a dropCdown list) and another la#el on the form) as shown in the following illustration.
6. ,lic' the first <abel control) then use the Pro"erties window to change its Te$t "ro"ert$ to ' l r. K. ,lic' on the ,rop,own<ist and then use the Pro"erties window to change the ", "ro"ert$ to ' l r. ,hange the /utoPost2ack "ro"ert$ to True. D. Select the "tems "ro"ert$ of the ,rop,own<ist) clic' on the elli"sis ?XA) and enter items for the ,rop,own<ist #$ clic'ing Add four times and then setting the Te$t "ro"ert$ for the first list item to Select ' l r) the ne1t to Red) the ne1t to Green) and the fourth to Blue. *nce the screen loo's li'e the following illustration) clic' *>.
C. 9se the Pro"erties window to change the ", "ro"ert$ of the second la#el to Message. 2 . 0ou#le/clic' on the ,rop,own<ist. This will o"en the code/#ehind module for the "age) and will also create the =olor0Selected"nde$=hanged e%ent handler) as shown in the following illustration.
13. .elect -ase -olo"..electe!(te&.Text 14. 18. 1:. 1E. 1F. 1G. $H. $1. $$. $3. -ase "6e!" 7essa)e.Text &= "?#ont colo"='" & < -olo"..electe!(te&.Text & "'A" 7essa)e.Text &= ">ou -+ose 6e!!" 7essa)e.Text &= "?B#ontA" -ase ";"een" 7essa)e.Text &= "?#ont colo"='" & < -olo"..electe!(te&.Text & "'A" 7essa)e.Text &= ">ou -+ose ;"een!" 7essa)e.Text &= "?B#ontA"
-ase "Blue" 7essa)e.Text &= "?#ont colo"='" & < -olo"..electe!(te&.Text & "'A" 7essa)e.Text &= ">ou -+ose Blue!" 7essa)e.Text &= "?B#ontA" -ase lse
7essa)e.Text &= "?#ont colo"='BlacC'A" 7essa)e.Text &= ">ou !i! not c+oose!" 7essa)e.Text &= "?B#ontA" n! .elect
!!. From the File menu) select Sa%e &e#Form2.as"1.%# to sa%e the new code. !8. From the Build menu) select Build ,ha"terO ! to com"ile the "ro;ect. !Q. Browse the "age #$ right/clic'ing it in Solution E1"lorer) and then selecting View 3n Browser ?or Browse &ithA. !6. Select a color #$ clic'ing on the arrow on the right side of the dro"/down list. The result should #e similar to the following illustration.
This sim"le e1am"le shows se%eral features of ASP.NET and Visual Basic .NET within Visual Studio .NET) including=
7a"id A""lication 0e%elo"ment ?7A0A) which allows $ou to ;ust dro" controls on the form and then handle e%ents. The a#ilit$ to set man$ "ro"erties on controls without an$ coding. Automatic "ost#ac's #$ controls other than #uttons) which allows for a much richer user interface than classic ASPI for e1am"le) e%er$ time $ou select an item from the list) the form actuall$ "osts #ac' to the ser%er) allowing $ou to send an u"dated res"onse to the client.
.oo"ing Statements
.oo"ing statements are useful features that allow $ou to "erform actions re"eatedl$) #$ either s"ecif$ing e1"licitl$ at design time the num#er of times the code should loo") deciding at run time how man$ times to loo") loo"ing until a s"ecified condition is met) or loo"ing through a collection of o#;ects and ta'ing a s"ecific action on each item. There are se%eral different t$"es of loo"ing statements) each of which has its own "articular s$nta1 and is useful for a "articular situation=
1orG loo"s 1or EachG loo"s ?a s"ecial case of 1orG loo"sA ,oG loo"s ?which include ,o hileG End hile loo"s hileG and ,o !ntilG loo"sA
NOTE Visual Basic 6 su""orted the hileG end s$nta1 for hileG loo"s. 3n Visual Basic .NET) this s$nta1 is no longer su""orted. You should use the hileGEnd hile s$nta1 instead.
NOTE The "receding code e1am"le and se%eral others in this section use the ?I IA tags) which allow $ou to em#ed code directl$ into an .as"1 "age) which is also the wa$ that classic ASP "ages were t$"icall$ written. &hile this is still %alid in ASP.NET) it+s more common to "lace code in a ser%er/side ?sc"i*tA #loc' or in a code/#ehind class) which hel"s 'ee" <TM. and control tags se"arate from code) ma'ing #oth easier to maintain. You can also use the Step 'e$word to loo" #$ ste"s greater than 2) or e%en to loo" #ac'ward #$ s"ecif$ing a negati%e num#er) as follows=
?I %i& ( 0s (nte)e" Fo" ( = E To H .te* 51 IA ?#ont siDe="?I=(IA"A 4elco&e to 0./.N T ?B#ontA ?b"BA ?I Next IA
You can also use a 1orG loo" to loo" through the elements of an arra$ #$ s"ecif$ing the length of the arra$ as the loo" count e1"ression) as follows=
?I %i& s243 0s .t"in) s2H3 = "0" s213 = "B" s2$3 = "-" s233 = "%" s243 = " " Fo" ( = H To s.Len)t+ 5 1 IA ?#ont siDe="?I=(IA"A ?I=s2(3IA ?B#ontA ?b"BA ?I Next IA
NOTE 3n Visual Basic .NET) all arra$s are Gero/#ased. Therefore) to use the <ength "ro"ert$ of the arra$ for a loo"ing statement) $ou should use <ength J2. Note also that the arra$ declaration ,im sEBF /s String results in an arra$ of Q mem#ers ? to 8A.
NOTE Now is a Visual Basic .NET 'e$word that returns a ,ateTime structure containing the current date and time. This is useful for getting current date and time information) or future datesEtimes #ased on the current dateEtime) as shown in the "receding e1am"le. This code out"uts each date to the #rowser using .esponse. rite. Note that when declaring the ,ates arra$) $ou use the u""er #ound of ( to s"ecif$ ! elements ? to 2A.
The statements within the loo" will #e e1ecuted as long as the %aria#le " is less than or e(ual to Q. 3f) for whate%er reason) " is greater than Q the first time the ,o statement is e1ecuted) the statements within the loo" will not #e e1ecuted. 3f $ou want to ensure that the statements within the loo" will e1ecute at least once) $ou can mo%e the hile e1"ression to the end of the loo") as follows=
?I '%o...Loo* 4+ile s'ntaxJ %i& ( 0s (nte)e" = H %o ( = ( + 1 IA ?#ont siDe="?I=(IA"A 4elco&e to 0./.N T ?B#ontA ?b"BA ?I Loo* 4+ile ( ? 8 IA
You can also use the !ntil 'e$word in "lace of $ou the o""osite result of hile.
9ltimatel$) the onl$ real difference #etween hile or !ntil is that hile will loo" as long as its test condition e%aluates to True) whereas !ntil will loo" as long as its test condition e%aluates to 1alse.
9sing
hileGEnd
hile .oo"s
hileGEnd hile loo"s do essentiall$ the same thing as ,o hileG loo"s) letting $ou e1ecute a gi%en set of statements while a gi%en condition is true. hileG loo"s are not as fle1i#le as ,oG loo"s #ecause the$ don+t offer the !ntil 'e$word or allow the condition to #e "laced at the end of the loo" rather than the #eginning. An ad%antage of hileGEnd hile loo"s is that the sim"ler
s$nta1 might #e easier for #eginning "rogrammers to use more consistentl$. A hileG loo" that does the same thing as the "receding ,oG loo"s would loo' li'e the following=
?I '4+ile... n! 4+ile s'ntaxJ %i& ( 0s (nte)e" = 1 4+ile ( ?= 8 IA ?#ont siDe="?I=(IA"A 4elco&e to 0./.N T ?B#ontA ?b"BA ?I ( = ( + 1 n! 4+ile IA
Most "rograms will use a %ariet$ of loo" t$"es. No matter which loo" t$"e $ou choose) the im"ortant thing is that $ou use it correctl$ and consistentl$ for a gi%en tas'. This will ma'e $our code easier to read and maintain.
Err r 5andling
3n an$ a""lication) one challenge faced #$ de%elo"ers is dealing with the ine%ita#le errors that "o" u". A""lication errors come in three %arieties=
S$nta1 errors S$nta1 errors include miss"elled or missing 'e$words ?such as a missing End "f statementA) or other mista'es relating to the s$nta1 of the language $ou+re using. S$nta1 errors are t$"icall$ flagged #$ the 30E and can #e easil$ fi1ed at design time.
7un/time errors 7un/time errors a""ear once $our code is com"iled and running. 7un/time errors are caused #$ code that a""ears correct to the com"iler #ut cannot run with certain %alues. For e1am"le) code that di%ides one integer %aria#le #$ another will a""ear to #e correct to a com"iler) #ut it will cause a run/time error if the second %aria#le is Gero. 7un/time errors can also occur when a user gi%es an une1"ected res"onse to a "rogram or when the s$stem is not in a state consistent with what the "rogram e1"ects) such as not ha%ing a dis' in the flo""$ dis' dri%e when a "rogram is e1"ecting to read from it.
.ogic errors .ogic errors are errors in which a "rogram that wor's correctl$ under some ?or mostA circumstances gi%es une1"ected or unwanted results #ased on certain in"ut %alues. This
t$"e of error can #e e1tremel$ difficult to trac' down and fi1 #ecause it doesn+t sto" the e1ecution of the "rogram. *ne thing that all three t$"es of errors ha%e in common is that the$ must all #e handled in some fashion) lest the$ "ro%o'e gra%e dissatisfaction on the "art of $our users. An im"ortant first ste" is "re%ention. 3n Visual Basic .NET) $ou can use *"tion E1"licit and *"tion Strict in $our a""lications to "re%ent some run/time errors. ?The$+re #oth turned on #$ default in the Visual Studio .NET 30E.A 9sing *"tion E1"licit will raise a s$nta1 error if $ou attem"t to use a %aria#le #efore declaring it) which can hel" greatl$ if $ou ha%e a ha#it of miss"elling %aria#le names. 9sing *"tion Strict will raise a s$nta1 error if $ou attem"t an im"licit data t$"e con%ersion that would result in a loss of data. *"tion Strict also im"lies *"tion E1"licit) so *"tion Strict will also raise a s$nta1 error on an$ attem"t to use an undeclared %aria#le. The following e1am"le demonstrates the use of +ption Strict=
9*tion .t"ict 9n %i& 7'(nt 0s (nte)e" %i& 7'%ouble 0s %ouble 7'%ouble = 3.1418G 7'(nt = 7'%ouble 'T+is line 1ill cause an e""o" at co&*ile ti&e
Both +ption E$plicit and +ption Strict must come #efore an$ other code in the module in which the$ a""ear.
'-o!e t+at &i)+t cause an e""o" xit .ub ""o"Han!le"J ' ""o" +an!lin) co!e 6esu&e Next
n! .ub
The +n Error statement transfers e1ecution to the section of code indicated #$ the ErrorKandler la#el. *nce the error/handling code has e1ecuted) the .esume Ne$t statement causes e1ecution to return to the statement immediatel$ following the line that caused the error. The E$it Sub statement a""earing ;ust "rior to the ErrorKandler la#el "re%ents the error handler from running if no error occurs. The +n Error statement is an e1am"le of unstructured error handling. A""lications using unstructured error handling are generall$ more difficult to de#ug and maintain. Fortunatel$) Visual Basic .NET now also su""orts structured e1ce"tion handling using the TryG=atchG 1inally s$nta1. NOTE You might see the terms error and e$ception used interchangea#l$. 3n .NET) e1ce"tions are une1"ected e%ents that occur during the e1ecution of $our code. The$ differ from errors in that each e1ce"tion is re"resented #$ an instance of an e1ce"tion class ?there are man$ t$"es of e1ce"tion classes) each deri%ed from the #ase System.E$ception classA) which "ro%ides de%elo"ers with "ro"erties and methods that allow them to deal with the e1ce"tion.
'-o!e to +an!le exce*tion Finall' '-o!e t+at executes a#te" an' co!e in t+e -atc+ blocC2s3
n! T"'
You can define =atch #loc's for as man$ s"ecific errors as $ou want to handle. You can use the 1inally #loc' for an$ code $ou want to run after the e1ce"tion/handling code) including clean/u" code) such as code to close a file. The 1inally #loc' of code is alwa$s run) whether or not an e1ce"tion has occurred. 3n addition to catching e1ce"tions) $our code can actuall$ throw an e1ce"tion ?cause an errorA. To do so) $ou use the Throw 'e$word. For e1am"le) if $ou wanted to catch onl$ the di%ide #$ e1ce"tion and then rethrow an$ other e1ce"tion ?for e1am"le) to ha%e a higher/le%el e1ce"tion handler handle a "articular t$"e of e1ce"tionA) $ou could use the following code=
%i& a, b, c 0s (nte)e" T"' '.ta"t &onito"in) #o" exce*tions '-o!e t+at &a' cause an exce*tion a = 1 b = H c = a B b -atc+ 9 0s 9,e"#lo1 xce*tion
T+"o12e3 '6et+"o1 exce*tion e Finall' '-o!e t+at executes a#te" an' co!e in t+e -atc+ blocC2s3 n! T"'
3t is worth noting that the most s"ecific =atch #loc's should #e first) followed #$ an$ more general =atch #loc's. 3f the =atch for the most general e1ce"tion t$"e ?E$ception in this e1am"leA was first) all e1ce"tions would #e caught in that #loc') including the more s"ecific e1ce"tion) +%erflowE$ception. &hat ha""ens if an e1ce"tion is thrown and $our code does not catch itU 3f custom errors are not ena#led ?as 3+ll discuss in ,ha"ter QA) the e1ce"tion details are dis"la$ed to the user) which is "ro#a#l$ not what $ou want to ha""en. This ne1t e1am"le will wal' $ou through the "rocess of creating a "age that generates an unhandled e1ce"tion) and then adding e1ce"tion handling to "ro"erl$ handle the e1ce"tion.
<andle an e1ce"tion
2. *"en Visual Studio .NET. 2. From the File menu) select *"en) and then select *"en Pro;ect. Select the ,ha"terO ! "ro;ect $ou created earlier in this cha"ter. You can also select this "ro;ect #$ choosing File) then 7ecent Pro;ects. !. 7ight/clic' the ,ha"terO ! "ro;ect in the Solution E1"lorer. From the conte1t menu) select Add) then Add &e# Form. &hen "rom"ted) t$"e the name of the form as E0ce(ti ns.as(0) and then clic' *"en. 8. From the Tool#o1) on the right side of the screen) select a #utton and drag it to the form. Q. Select a la#el and drag it to the form ;ust #elow the #utton. 6. 9sing the Pro"erties window on the right/hand side of the screen) change the Te$t "ro"ert$ for the #utton from Button to 6i&ide B) 7er . The #utton con%enientl$ e1"ands to show all of the entered te1t. The screen should loo' similar to the following illustration.
K. ,hange the 30 of the la#el from .a#el2 to Message. D. 0ou#le/clic' the #utton in the designer.
The code/#ehind module for the "age will #e loaded for editing) and the 2utton>0=lick e%ent handler will #e added. C. Add the following code to the handler=
1H. %i& a, b, c 0s (nte)e" 11. a = 1 1$. b = H 13. c = a B b 7essa)e.Text = c.To.t"in)
28. *n the File menu) clic' Sa%e All to sa%e the "age) and then select Build ,ha"terO ! from the Build menu to com"ile the "ro;ect. 2Q. Test the "age #$ right/clic'ing E1ce"tions.as"1 in Solution E1"lorer) and then selecting View 3n Browser. &hen $ou see the screen with the 0i%ide B$ Pero #utton) clic' the #utton. You will see a screen similar to the following illustration) in which the *ut"ut window is closed to allow $ou to see more of the "age.
26. ,lose the em#edded #rowser window) locate the 2utton>0=lick handler in E1ce"tions.as"1.%#) and then change the code in the handler to the following=
1E. %i& a, b, c 0s (nte)e" 1F. T"' '.ta"t &onito"in) #o" exce*tions 1G. $H. $1. $$. '-o!e t+at &a' cause an exce*tion a = 1 b = H c = a B b 0s 9,e"#lo1 xce*tion
'-o!e to +an!le exce*tion 7essa)e.Text = "9,e"#lo1 #"o& !i,i!in) b' De"o." n! T"'
26. Select File) then Sa%e All to sa%e the "age) and then select Build ,ha"terO ! from the Build menu to com"ile the "ro;ect. 2K. Test the "age using the same "rocess as in ste" C. ,lic'ing the #utton should gi%e $ou a result similar to the following illustration.
the .NET de%elo"ment "latform. *#;ect/oriented "rogramming is a su#stantial to"ic) so 3 highl$ recommend that $ou do some additional reading to su""lement the material "ro%ided here. A good "lace to start is the Visual Studio .NET documentation for Visual Basic) which contains an entire section on o#;ect/oriented "rogramming. There are also man$ #oo's on #oth o#;ect/ oriented "rogramming and design patterns) a related su#;ect. 3n the sim"lest terms) an ob*ect is an instance of a class in o#;ect/oriented languages such as ,L L) ,J) and now Visual Basic .NET. ?,lasses are descri#ed in the section 49sing ,lasses as ,ontainers for ,ode5 later in this cha"ter.A *#;ects t$"icall$ mirror their real/world counter"arts= em"lo$ees) in%oices) and "urchase orders are all e1am"les of real/world entities that can #e modeled as o#;ects in $our "rograms. *#;ects t$"icall$ "ro%ide #oth properties) which descri#e some attri#ute of the o#;ect ?for e1am"le) an Employee o#;ect might ha%e an Employee", "ro"ert$A) and methods) which allow actions to #e ta'en #$ the o#;ect ?for e1am"le) an Employee o#;ect might e1"ose a Promote methodA. *#;ect/oriented "ro"erties and methods ma'e it easier for "rogrammers to use a gi%en o#;ect in wa$s that relate to the real/world o#;ects that the "rogram is modeling. 3n addition to "ro"erties and methods) o#;ect/oriented "rogramming offers three hel"ful features= inheritance) "ol$mor"hism) and enca"sulation.
"nheritance is the a#ilit$ to create new classes that are deri%ed from e1isting classes. A deri%ed class 4inherits5 all of the "ro"erties and methods of the class from which it is deri%ed ?referred to as the parent classA. Programmers can then add additional "ro"erties and methods to the deri%ed class) or in some cases o%erride the im"lementation of an e1isting method inherited from the "arent class. Polymorphism lets "rogrammers ha%e identicall$ named methods on different classes deri%ed from the same "arent) and it allows the correct method to #e e1ecuted #ased on the conte1t of the call. For e1am"le) a "rogrammer could define an "n%oice class with a Process method. The "rogrammer could then define se"arate Time"n%oice and 9aterials"n%oice classes that are deri%ed from the "n%oice class) #ut define different functionalit$ in their Process methods) hence o%eriding the functionalit$ e1"osed #$ the "arent class. &hen a "rocedure calls the Process method on one of these deri%ed o#;ects) the "ro"er "rocessing will #e e1ecuted. The calling "rocedure doesn+t ha%e to 'now which 'ind of "n%oice it is dealing with. Encapsulation allows o#;ects to #e treated as 4#lac' #o1es5 in that onl$ the "ro"erties and methods defined #$ the "rogrammer as "u#licl$ a%aila#le are %isi#le outside of the o#;ect. The internal o#;ect state and the im"lementation of the "u#licl$ a%aila#le methods are hidden #$ enca"sulation. This limited %isi#ilit$ lets de%elo"ers freel$ modif$ the internal state and im"lementation of their o#;ects) as long as the$ don+t change the "u#licl$ defined interface used to access the o#;ect. For instance) an Employee<ist class might e1"ose methods 1irstEmployee) Ne$tEmployee) and so on. 3nternall$) such a list could #e managed using a sim"le arra$) a lin'ed list ?in which each item "oints to the ne1t item in a listA) or a data#ase ta#le. To the consumer of the class) it should not matter e1actl$ how the list is maintained internall$) as long as the "u#lic methods such as 1irstEmployee return the correct information.
9sing 3nheritance
Now that $ou 'now a #it a#out o#;ect/oriented "rogramming) let+s ta'e a loo' at a sim"le e1am"le of how to "ut it to use. First) let+s define a class #ased on a real/world entit$Ban animal. The following class retrie%es a reference to the current Kttp=onte$t in order to #e a#le to write out"ut to the #rowser) and then defines Eat and Sleep methods) each of which writes a message to the #rowser.
/ublic -lass 0ni&al %i& -ontext 0s Htt*-ontext = Htt*-ontext.-u""ent /ublic 9,e""i!able .ub at23
Ne1t) we+ll create a more s"ecific animal class) ,at) which deri%es from the Animal class. Note the use of the 3nherits 'e$word on the second line. 3nheriting from another class is reall$ that sim"le. This class will o%erride the #eha%ior of the Eat method #ut not the Slee" method) as follows=
/ublic -lass -at (n+e"its 0ni&al %i& -ontext 0s Htt*-ontext = Htt*-ontext.-u""ent /ublic 9,e""i!es .ub at23
You+ll also create a 0og class that deri%es from Animal and that o%errides the Slee" method #ut not the Eat method) as follows=
/ublic -lass %o) (n+e"its 0ni&al %i& -ontext 0s Htt*-ontext = Htt*-ontext.-u""ent /ublic 9,e""i!es .ub .lee*23 -ontext.6es*onse.4"ite2"KDDDDD...1oo#1oo#1oo#1oo#... DDDDDD!?b"BA"3 n! .ub n! -lass
Finall$) we+ll use the =at and ,og classes in the following code. Note that $ou use the "mports statement to access the mem#ers of the /nimals names"ace without ha%ing to full$ (ualif$ names ?such as =at instead of /nimal.=atA. The sam"le code for this cha"ter shows the im"lementation of "mports.
/"i,ate .ub /a)e<Loa!2B'Val sen!e" 0s .'ste&.9bLect, < B'Val e 0s .'ste&. ,ent0")s3 Han!les 7'Base.Loa! %i& 7'-at 0s Ne1 -at23 %i& 7'%o) 0s Ne1 %o)23 7'-at. at23
This code) when added to a &e# Form) "ro%ides the out"ut shown in the following illustration.
E%en though $ou called the same two methods on #oth the =at and ,og classes) when $ou o%errode a method of the "arent /nimal class) $ou got the #eha%ior that $ou s"ecified for the "articular animal. &hen $ou didn+t o%erride) the out"ut shows that $ou got the #eha%ior inherited from the "arent /nimal class. You can find the full source code for this e1am"le in the "ractice files for this cha"ter.
Store and retrie%e a""lication state. Store and retrie%e session state. ,onfigure session state storage. 9se client/side coo'ies for state storage.
Most a""lications of an$ significance will use "ieces of data) or %aria#les) that need to #e maintained across a series of re(uests or shared #etween multi"le users of an a""lication. This data is referred to as state. 3n a rich client a""lication) it+s relati%el$ sim"le to maintain indi%idual user state sim"l$ #$ allocating s"ace in memor$ on the client machine. 3n &e# a""lications) managing user and a""lication state is more challenging. The "rimar$ reason for this is that the <$"erte1t Transfer Protocol ?<TTPABthe "rotocol used to send and recei%e re(uests through a &e# #rowserBis inherentl$ stateless. That is) <TTP doesn+t inherentl$ "ro%ide a wa$ for the &e# ser%er to identif$ a series of re(uests as coming from the same user) ma'ing it difficult for the &e# ser%er to maintain state and associate it with an indi%idual user. 3n classic ASP) this limitation was o%ercome through an in/memor$ collection of 'e$/%alue "airs associated with the intrinsic Session o#;ect. This collection) howe%er) had a num#er of im"ortant limitations of its own) which are discussed later in this cha"ter. 3n addition to indi%idual user state) man$ a""lications need to store and retrie%e applicationCle%el state information that is glo#al to all users of the &e# a""lication. To maintain a""lication state in classic ASP) the intrinsic /pplication o#;ect e1"osed a collection similar to that of the Session o#;ect+s collection.
A""lication state storage in ASP.NET is su""lied #$ the .NET Kttp/pplicationState class ?which resides in the System. eb names"aceA) an instance of which is e1"osed as the /pplication "ro"ert$ of the Page class. Because e%er$ ASP.NET "age inherits from the Page class) $ou can access the /pplication "ro"ert$ as if it were an inherent "ro"ert$ of the "age) as shown in the "receding code. For #ac'ward/com"ati#ilit$ with classic ASP) the ASP.NET /pplication o#;ect e1"oses a =ontents "ro"ert$ that can #e used to access indi%idual %alues) using the a""ro"riate 'e$.
0**lication.-ontents2"7'0**licationVa""3 = "7'Value" 7'LocalVa" = 0**lication.-ontents2"7'0**licationVa""3
New in ASP.NET is the a#ilit$ to add items to the Kttp/pplicationState collection using the /dd method e1"osed #$ the /pplication o#;ect. You can use the .emo%e method to remo%e items from the /pplication collection. ?3n classic ASP) the /dd and .emo%e methods are e1"osed #$ the /pplication.=ontents collection.A
0**lication.0!!2"7'0**licationVa"", "7'Value"3 0**lication.0!!2"7'9t+e"0**licationVa"", "7'9t+e"Value"3 0**lication.6e&o,e2"7'9t+e"0**licationVa""3
You can also clear the contents of the /pplication collection #$ using the =lear method e1"osed #$ the /pplication o#;ect ?or the .emo%e/ll method) which is "ro%ided for #ac'ward/ com"ati#ilit$ with classic ASPA.
' it+e" line belo1 1ill clea" t+e a**lication state
0**lication.-lea"23 0**lication.6e&o,e0ll23
The /pplication o#;ect e1"oses se%eral other wa$s to access and modif$ the %alues stored in the /pplication collection) as shown in Ta#le 8/2. Ta#le 834. /pplication +b*ect 9ethods and Properties Method or roperty /llLeys "ro"ert$ -et method Set method -etLey method ToString method !se 7eturns a collection of all of the 'e$s #$ which /pplication collection %alues can #e accessed. 7eturns an item from the /pplication collection #$ 'e$ or #$ inde1. 9"dates an item in the /pplication collection #$ 'e$ or #$ inde1. 7eturns the 'e$ for an item #ased on a su""lied inde1. 7eturns a string that re"resents an item in the /pplication collection. 9seful when a string %alue is re(uired) rather than an o#;ect reference.
=ount "ro"ert$ 7eturns the num#er of o#;ects stored in the /pplication collection.
3n addition to storing %alues in the /pplication collection) $ou can instantiate and store references to .NET com"onents) such as 0ataSets) in a""lication state using the :ob*ect runat5Mser%erM; tag s$nta1 in the @lo#al.asa1 file ?or its associated code/#ehind fileA. These o#;ects then #ecome "art of the /pplication o#;ect+s Static+b*ects collection and can #e referenced in $our ASP.NET &e# Form "ages #$ referring to the id attri#ute associated with the o#;ect.
' ;lobal.asax ?obLect "unat="se",e"" i!="7'-lass(nstance" class="7'-lassNa&e" sco*e="0**lication"A ?BobLectA ' 4eb Fo"&s *a)e 6es*onse.4"ite2"Value = " & 7'-lass(nstance.7'Value3
NOTE @lo#al.asa1 ?or its associated code/#ehind fileA is the onl$ mechanism for creating o#;ect instances with /pplication sco"e. TIP &hen $ou+re using either the /pplication or Session collections) it+s a good idea to initialiGe the %aria#les $ou+re using to a default %alue ?such as YY for a string or for a numericA in the
/pplication0Start or Session0Start e%ent handlers in @lo#al.asa1. You can then test for the default %alue as a wa$ of determining whether it has #een altered.
8. From the View menu) select ,ode) or "ress FK to o"en the code editor. Q. .ocate the Page0<oad method) and add the following code=
:. '(nitialiDe loo*in) ,a"iable E. %i& loo*-ount 0s (nte)e" = H F. G. 'LocC t+e a**lication obLect be#o"e 1e &ani*ulate it 1H. 0**lication.LocC23 11. 0**lication2"Test.t"in)"3 = "Hello"
1$. 0**lication.0!!2"TestNu&be"", 433 13. 14. 'No1 unlocC t+e 0**lication, since 1e 1ill no1 18. 'Lust "ea! #"o& t+e 0**lication obLect. 1:. 0**lication.=nLocC23 1E. 1F. 7essa)e.Text = "T+e"e a"e " & < 1G. $H. 0**lication.-ount.To.t"in)23 & < " ite&s in t+e 0**lication collection.?b"BA"
$1. %o 4+ile loo*-ount ? 0**lication.-ount $$. $3. $4. $8. Loo* loo*-ount += 1 7essa)e.Text &= "0**lication2" & < loo*-ount.To.t"in)23 & < "3 = " & 0**lication2loo*-ount3 & "?b"BA"
26. Sa%e the "age and its code/#ehind module #$ selecting File) then Sa%e All ?or #$ "ressing ,trlLShiftLSA. 2K. Select Build ,ha"terO 8 from the Build menu to #uild the a""lication. 2D. Test the "age #$ right/clic'ing &e#Form2.as"1 in Solution E1"lorer) and then selecting View 3n Browser. The resulting screen should loo' similar to the following illustration.
3nformation stored in a""lication state can #e easil$ shared among all users of an a""lication. This can ma'e it %er$ tem"ting to use a""lication state to store all manner of data) from a""lication settings such as data#ase connection strings to cached datasets containing fre(uentl$ used data. 3n man$ cases) there are more efficient means of storing this data than a""lication state. Ta#le 8/2 shows some e1am"les of when $ou might or might not want to store information in a""lication state) as well as alternati%es for storing such information. Ta#le 83*. /pplication State .ecommendations State I"for#atio" 0ata#ase connection strings or other a""lication configuration settings 0atasets containing fre(uentl$ read data Issues T$"icall$) these settings are accessed infre(uentl$. Storing this information in a""lication state is not %er$ efficient. ,aching fre(uentl$ used data at the a""lication le%el can #e efficient) #ut there+s little automatic control o%er when the data is refreshed. Shared %alues that can #e u"dated #$ multi"le users of an a""lication can "resent ma;or scala#ilit$ issues) as discussed in 4State and Scala#ilit$5 later in this cha"ter. $lter"ati%e 9se the &e#.config configuration file to store this information) and retrie%e with the /ppSettings "ro"ert$ of the =onfiguration Settings ,lass) as discussed in A""endi1 B. 9se the ASP.NET cache engine to cache e1"ensi%e or fre(uentl$ read data. The ASP.NET cache engine "ro%ides fine/ grained control o%er how and when data is refreshed or "urged from the cache. ?See ,ha"ter 22 for more information.A ,onsider storing shared a""lication flags in a data#ase) which will "ro%ide finer/ grained control o%er the reading and u"dating of indi%idual %alues.
Storing references to o#;ects with 3f it+s a#solutel$ necessar$ to store a the wrong threading model ?such reference to an o#;ect instance) ensure as legac$ ,*M com"onents that the class from which the o#;ect is created with Visual BasicA can created is thread safe. ha%e a se%ere im"act on the scala#ilit$ of an a""lication.
0ura#ilit$ A""lication state lasts onl$ as long as the &e# a""lication is running. 3f the &e# a""lication or &e# ser%er is shut down or crashes) an$ state information stored at the a""lication le%el will #e destro$ed. An$ information that needs to "ersist #etween a""lication restarts should #e stored in a data#ase or other "ersistent storage.
&e# farms A""lication state is not shared across multi"le ser%ers in a &e# farm ?nor across multi"le "rocessors in a &e# gardenA. 3f $ou need to store %alues that must #e a%aila#le to all users in these scenarios) a""lication state is not an a""ro"riate choice.
Memor$ An$ gi%en ser%er has onl$ a limited amount of "h$sical memor$ a%aila#le. *%eruse of a""lication state can result in information #eing swa""ed to %irtual memor$ ?a location on a hard dri%e used to "ro%ide su""lemental 4memor$5 storageA. This can reduce "erformance significantl$.
NOTE &e# farms are grou"s of identicall$ configured ser%ers that share the load of ser%ing user re(uests for a gi%en &e# a""lication. Each ser%er contains the same content and can fulfill an$ re(uest. 7e(uests are routed to indi%idual ser%ers #$ a hardware/ or software/#ased load/ #alancing algorithm that either determines which ser%er is least loaded or assigns re(uests to a gi%en ser%er randoml$. &e# gardens are a new conce"t in ASP.NET in which an a""lication can #e set to run on s"ecific "rocessors on a multi"rocessor ser%er.
!e# far%s 3n classic ASP) session state could not #e scaled across multi"le ser%ers in a &e# farm) limiting its usefulness in high/ scala#ilit$ situations.
6ura#ilit)
3n classic ASP) session state would #e destro$ed #$ a ser%er restart or crash. This made it a "oor choice for such uses as sho""ing carts) whose contents should sur%i%e such e%ents.
'
9ie reliance
,lassic ASP offered no inherent solution for su""orting session state with #rowsers that could not or would not acce"t coo'ies. Although aftermar'et solutions were a%aila#le) the$ often in%ol%ed unacce"ta#le "erformance trade/offs. ASP.NET sol%es each of these limitations) "ro%iding "er/user state storage that+s scala#le) relia#le) and a%aila#le on #rowsers that don+t su""ort coo'ies ?or for users who choose not to acce"t coo'iesA. For more information on the a%aila#le o"tions for ASP.NET session state and how the$ sol%e these limitations) see 4,onfiguring Session State Storage5 later in this cha"ter. As with the ASP.NET /pplication o#;ect) the ASP.NET Session o#;ect is e1"osed as a "ro"ert$ of the Page class) from which all ASP.NET "ages inherit. This allows direct access to the Session o#;ect.
.ession2"7'.essionVa""3 = "7'Value" 7'LocalVa" = .ession2"7'.essionVa""3
The Session o#;ect functionalit$ is "ro%ided #$ the KttpSessionState class) an instance of which is created for each user session that session state has #een ena#led for. .i'e the /pplication o#;ect) the Session o#;ect e1"oses a =ontents collection for #ac'ward/ com"ati#ilit$ with classic ASP. An$ %alues stored in the KttpSessionState collection can also #e accessed through the =ontents collection alias.
.ession.-ontents2"7'.essionVa""3 = "7'Value" 7'LocalVa" = .ession.-ontents2"7'.essionVa""3
The Session collection can also #e used to store references to o#;ect instances) using similar s$nta1 to that used to store o#;ect references at the a""lication le%el. These o#;ects then #ecome "art of the Session o#;ect+s Static+b*ects collection and can #e referenced in $our ASP.NET &e# Form "ages #$ referring to the id attri#ute associated with the o#;ect.
' ;lobal.asax ?obLect "unat="se",e"" i!="7'-lass(nstance" class="7'-lassNa&e" sco*e=".ession"A ?BobLectA
Ta#le 8/! lists some of the additional "ro"erties and methods "ro%ided #$ the Session o#;ect to retrie%e and mani"ulate Session collection %alues. Ta#le 832. Session +b*ect Properties and 9ethods Method or roperty Leys "ro"ert$ !se 7eturns a collection of all of the 'e$s #$ which Session collection %alues can #e accessed. 7eturns a string containing the session 30 for the current session. 7eturns an "nteger %alue re"resenting the current Session Timeout setting. 0estro$s the current user session. 7emo%es all items from the Session collection. 7emo%es a s"ecific item from the Session collection) #ased on its inde1 within the collection. 7eturns a string that re"resents an item in the Session collection. 9seful when a string %alue is re(uired rather than an o#;ect reference.
=ount "ro"ert$ 7eturns the num#er of o#;ects stored in the Session collection. Session", "ro"ert$ Timeout "ro"ert$ /bandon method =lear method .emo%e/t method ToString method
An$ attem"t to access the Session o#;ect from a "age on which enableSessionState has #een set to 1alse will result in an error. Note that once a session has #een created for a gi%en user) setting
the enableSessionState attri#ute to 1alse doesn+t result in the destruction of the e1isting session. 3t onl$ "re%ents access to the Session o#;ect from that "age. You can set the session state to read/onl$ for a gi%en "age #$ setting the enableSessionState attri#ute to .ead+nly. An$ attem"ts to u"date %alues stored in the Session collection from that "age will #e ignored.
To change its setting) select the enableSessionState entr$ in the Pro"erties window) clic' the dro"/down list containing the %alues) and select the desired %alue. This will u"date the @ Page directi%e that a""ears in the .as"1 "age currentl$ #eing edited. Fust as with a""lication state) using Visual Basic .NET to read and write session state is eas$. The out"ut for the following e1am"le will #e written into an ASP.NET .a#el ser%er control.
8. &ith the la#el control selected) change the ", of the la#el from .a#el2 to Message. Q. From the View menu) select ,ode or "ress FK to o"en the code editor. 6. .ocate the Page0<oad method) and add the following code=
E. '(nitialiDe loo*in) ,a"iable F. %i& loo*-ount 0s (nte)e" = H G. 1H. .ession2"Test.t"in)"3 = "Hello" 11. .ession.0!!2"TestNu&be"", 433 1$. 13. 7essa)e.Text="T+e"e a"e " & < 14. 18. 1:. 1E. %o 4+ile loo*-ount ? .ession.-ount 1F. 1G. $H. $1. Loo* loo*-ount += 1 7essa)e.Text &= ".ession2" & < loo*-ount.To.t"in)23 & < "3 = " & .ession2loo*-ount3 & "?b"BA" .ession.-ount.To.t"in)23 & < " ite&s in t+e .ession collection.?b"BA"
22. Sa%e the a""lication #$ using the File) Sa%e All menu o"tion ?or #$ "ressing ,trlLShiftLSA. 2!. From the Build menu) select Build ,ha"terO 8 to #uild the a""lication. 28. Test the "age #$ right/clic'ing SessionState.as"1 and selecting View 3n Browser. The resulting screen should loo' similar to the following illustration.
0e"ending on how fre(uentl$ these For infre(uentl$ accessed %alues) %alues are accessed) session state might consider storing user/s"ecific settings not #e the most efficient wa$ to store in a data#ase. these settings. ,aching fre(uentl$ used data at the session le%el can #e efficient) #ut there+s little automatic control o%er when the data is refreshed. 3t+s %er$ im"ortant to consider the cost of storing a dataset for each user session o%er the cost of retrie%ing the dataset from the data#ase. 9se the ASP.NET cache engine to cache e1"ensi%e or fre(uentl$ read data. The ASP.NET cache engine "ro%ides fine/grained control o%er how and when data is refreshed or "urged from the cache. See ,ha"ter 22 for more information on caching.
7eferences to Storing references to o#;ects with the 3f it+s a#solutel$ necessar$ to store a o#;ect instances wrong threading model ?such as legac$ reference to an o#;ect instance) ensure ,*M com"onents created with Visual that the class from which the o#;ect is BasicA can se%erel$ affect the scala#ilit$ created is thread safe. of an a""lication. 3t+s im"ortant to consider the cost of storing a reference to an o#;ect for each user session.
Failure to disa#le session state when not used 3f $ou+re not using session state within $our a""lication) disa#le it #$ changing the mode attri#ute of the sessionState configuration section of &e#.config to off. For a""lications that ma'e limited use of session state) ensure that an$ "ages that don+t use session state include the EnableSessionState5false attri#ute as a "art of the "age+s @ Page directi%e.
Misuse of $pplicatio".&oc'( ) The /pplication.<ockE F method "re%ents access to all a""lication %alues for an$ user other than the user whose re(uest resulted in the call to /pplication.<ockE F. This continues until the /pplication.!nlockE F method is called. You should minimiGe the time that these %alues are loc'ed #$ calling /pplication.<ockE F immediatel$ "rior to u"dating a %alue and calling /pplication.!n<ockE F immediatel$ afterward. 3f there is a %alue to #e added to a""lication state that might re(uire some time to calculate) calculate the %alue and sa%e the %alue into a %aria#le) and then loc' the a""lication) add the %alue from the %aria#le) and unloc' the a""lication.
Storing references to single ?or a"artmentA threaded o#;ects Storing references to non/free/threaded o#;ects at a""lication or session le%el can interfere with 33S thread management ca"a#ilities and can result in se%ere scala#ilit$ "ro#lems. A%oid storing non/free/threaded o#;ects at a""lication or session le%el.
In3(r cess sessi n state To scale a &e# a""lication #e$ond a certain "oint) it+s often necessar$ to use a &e# farm to allow multi"le ser%ers to handle re(uests. 3n/"rocess session state) the default) is not
a%aila#le to all ser%ers on a &e# farm. To use session state with a &e# farm) $ou should set $our a""lication+s Session mode to either StateSer%er or S#<Ser%er as descri#ed in the ne1t section.
O&eruse f sessi n r a((licati n st rage Storing numerous o#;ect references or large datasets at the a""lication le%el) and "articularl$ at the session le%el) can ra"idl$ e1haust the "h$sical memor$ on a &e# ser%er) causing it to su#stitute %irtual memor$ for storing additional information. This can ha%e a dramatic effect on the "erformance of an a""lication. You should alwa$s ensure that an$ use of a""lication state ?and more im"ortant) session stateA will not e1ceed the "h$sical memor$ resources a%aila#le on the &e# ser%er. Also remem#er that other a""lications will #e using some of these resources.
This is the default setting. 3ts #eha%ior is essentiall$ the same as in classic ASP. Out3 f3(r cess ;StateSer%er<
This setting s"ecifies that session state will #e stored #$ a ser%er running the ASP.NET state ser%ice. The state ser%er to connect to is s"ecified #$ an attri#ute) as descri#ed in the section 4Storing Session State *ut/of/Process5 later in this cha"ter. S=: Ser&er ;S*&Ser%er<
This setting s"ecifies that session state will #e stored in a Microsoft S:. Ser%er data#ase. The S:. Ser%er to connect to is s"ecified #$ an attri#ute) as descri#ed in the section 4Storing Session State in S:. Ser%er5 later in this cha"ter. ' 9ieless Sessi ns
This setting allows $ou to maintain session state e%en for users whose #rowsers cannot handle coo'ies. The following sections descri#e how to configure each of these settings.
8. Start the Ser%ices Microsoft Management ,onsole ?MM,A sna"/in #$ clic'ing Start) then selecting All Programs) then selecting Administrati%e Tools) and then selecting Ser%ices. Note that $ou must #e logged in as an administrator to see the Administrati%e Tools
folder ?if $ou are not logged in as an administrator) $ou can still access this folder from the ,ontrol Panel) #ut $ou will need to use the 7un As feature to run the Ser%ices MM, sna"/in using an administrati%e accountA. Q. Start the ASP.NET State Ser%ice on the desired ser%er from the Ser%ices MM, sna"/in. The &indows -P Professional Ser%ices sna"/in is shown in the following illustration.
ASP.NET will automaticall$ connect to the s"ecified state ser%er to store session state for $our a""lication. 3f the state ser%ice on the s"ecified ser%er is not running or the ser%er is not accessi#le) $ou will recei%e an error message. >ee" in mind that although storing session state in a dedicated ser%er "rocess can im"ro%e the o%erall scala#ilit$ of $our a""lication) mo%ing session state out/of/"rocess has inherent "erformance im"lications. 7etrie%ing state information from a different "rocess ?and es"eciall$ from a different machineA is significantl$ more costl$ than retrie%ing it from within the same "rocess. You should test the im"act on the t$"e and amount of session data $ou "lan to store #efore im"lementing this t$"e of session state storage in a "roduction a""lication.
2. *"en the &e#.config configuration file for $our a""lication and locate the sessionState configuration section. !. ,hange the mode attri#ute from 3nProc to S=:Ser&er. 8. Modif$ the s4l=onnectionString attri#ute so that it reflects the 3P address of the desired S:. Ser%er and the user 30 and "assword used to access the S:. Ser%er) and then sa%e &e#.config. The com"lete sessionState configuration section that uses a S:. Ser%er on the local machine would loo' li'e the following. ?Note that the state=onnectionString attri#ute and the cookieless and timeout attri#utes ha%e #een omitted.A
?session.tate &o!e=".NL.e",e"" s@l-onnection.t"in)="!ata sou"ce=1$E.H.H.1O use" i!=saO*ass1o"!="BA
IMPORTANT There are securit$ im"lications to "lacing the S:. Ser%er user 30 and "assword in the connection string in &e#.config. A #etter "ractice) where "ossi#le) is to use a trusted connection to S:. Ser%er. ,ha"ter C descri#es the ste"s necessar$ to use a trusted connection with S:. Ser%er) as well as other connection techni(ues. ,ha"ter 6 further e1"lores the to"ic of securit$ in ASP.NET) including good "ractices for storing connection string information.
&hen the cookieless attri#ute is set to true) ASP.NET will automaticall$ em#ed the Session", %alue in the 97. for all re(uests. For #est results) alwa$s use relati%e 97.s for internal lin's within $our a""lication. 7elati%e 97.s contain onl$ the "ath and file information for the re(uested resource) not the "rotocol and domain) which are assumed to #e the same as the current "age.
!. Add the coo'ie to the =ookies collection of the .esponse o#;ect ?e1"osed #$ the Page classA.
6es*onse.-ooCies.0!!27'-ooCie3
This sets a coo'ie called 49y =ookie5 that lasts until the user closes the #rowser.
,oo'ies ha%e a #ad re"utation #ecause of their misuse #$ some &e# com"anies to trac' the surfing ha#its of &e# users. 3t+s a good idea to e1"lain to $our users e1actl$ how and wh$ $ou+re using "ersistent coo'ies) and descri#e the #enefits of acce"ting those coo'ies. >ee" the e1"iration of "ersistent coo'ies within a reasona#le amount of time. For most sites) coo'ie e1"iration should #e measured in hours or da$s or) at most) months. Setting $our coo'ie e1"iration to $ears in the future is li'el$ to result in more users refusing $our coo'ie. Ne%er store user data in a coo'ie ?for e1am"le) credit card num#ers or other data that could #e at ris' if interce"ted or otherwise com"romisedA.
IMPORTANT Although it might seem o#%ious to a%oid storing information such as credit card num#ers in coo'ies) it+s e(uall$ im"ortant to consider the securit$ im"lications of storing such information on the ser%er side) whether in session state in memor$ or in a data#ase ser%er. Although there+s no single right answer to how to store sensiti%e data) here are some guidelines $ou should follow=
Store sensiti%e data onl$ if $ou must) and then onl$ for the minimum length of time necessar$. Encr$"t sensiti%e data to #etter "rotect it from #eing com"romised. &hen "ossi#le) archi%e sensiti%e data on s$stems that are not connected to the 3nternet ?and are thus less %ulnera#le to #eing com"romisedA.
Ma'e sure that $ou follow good securit$ "ractices on all of $our ser%ers) "articularl$ those e1"osed to the 3nternet. ?&e+ll co%er securit$ in greater detail in ,ha"ter 6.A
IMPORTANT Although following these guidelines won+t guarantee that $our &e# a""lications will ne%er #e com"romised #$ crac'ers) the$+ll hel" $ou limit the damage.
Do this
E+a#ple
&o!e=".tate.e",e""state-onnection.t"in)= sessionState configuration section "tc*i*=1$E.H.H.1J4$4$4"BA of $our a""lication+s &e#.config file) changing the mode attri#ute to StateSer%er and the state=onnectionString attri#ute to the a""ro"riate 3P address and T,P "ort for the state ser%er #eing used. ?session.tate Modif$ the &o!e=".NL.e",e""s@l-onnection.t"in)= sessionState configuration section "!ata sou"ce=1$E.H.H.1Ouse" of $our a""lication+s i!=saO*ass1o"!="BA &e#.config file) changing the mode attri#ute to S#<Ser%er and the s4l=onnectionString attri#ute to the a""ro"riate data source name) user 30) and "assword for the S:. Ser%er #eing used. ?session.tate cooCieless="t"ue"BA Modif$ the sessionState configuration section of $our a""lication+s &e#.config file) changing the cookieless attri#ute to true.
Edit ASP.NET configuration files. ,onfigure an ASP.NET a""lication. *%erride "arent configuration settings. .oc' down configuration settings.
*ne of the most im"ortant new features of ASP.NET) gi%en the ad%antages it "ro%ides de%elo"ers) is its new configuration s$stem. This configuration s$stem uses human/ and machine/reada#le -M./#ased files to store configuration information. This cha"ter will loo' at how these configuration files wor' and how $ou can use them in $our a""lications.
3n addition to machine.config) each ASP.NET &e# a""lication can ha%e one or more files called &e#.config ?one "er folderA in its folder hierarch$. Each &e#.config file o%errides an$ settings of the configuration files in "arent folders. Settings in &e#.config a""l$ onl$ to content within the folder in which the file resides) and an$ content in child folders. This allows $ou to set u" a hierarch$ of configuration files that lets $ou set a""lication/wide configuration o"tions at the highest le%els) while still allowing $ou to o%erride those settings at a lower le%el. For e1am"le) if $ou ha%e a grou" of files whose access must #e restricted) $ou can "lace those files in a se"arate folder within $our a""lication and then add a &e#.config file that im"lements tighter securit$ restrictions. You+ll see how to do this later in this cha"ter. NOTE 3f $ou decide to use multi"le le%els of configuration files within $our a""lication) $ou should consider using comments to ma'e it clear where $ou+re o%erriding settings from "arent &e#.config files or from machine.config. This wa$) those who need to maintain the a""lication can understand $our intent. ,omments in ASP.NET configuration files use the same s$nta1 as <TM. comments= RH// //S. >ee" in mind also that man$ of the settings configured in &e#.config and machine.config can also #e o%erridden at the "age le%el using attri#utes of the @ Page directi%e. Ta'e care to ensure that all de%elo"ers on a "ro;ect ?as well as those who will maintain the a""licationA understand this) to a%oid confusion. ,hanges to configuration file settings are detected automaticall$ #$ the ASP.NET runtime and integrated into the cached configuration settings for the a""lication. &hen a change is made) all new re(uests for resources within the sco"e of a gi%en configuration file use the new configuration settings automaticall$.
?s'ste&.1ebA ?ele&entNa&e1A ?c+il! le&entNa&e1 att"ibuteNa&e1=,alue att"ibuteNa&e$=,alue att"ibuteNa&eN=,alue BA ?Bele&entNa&e1A ?ele&entNa&e$ att"ibuteNa&e1=,alue att"ibuteNa&e$=,alue att"ibuteNa&eN=,alueA ?Bele&entNa&e$A ?ele&entNa&eN att"ibuteNa&e1=,alue att"ibuteNa&e$=,alue att"ibuteNa&eN=,alue BA ?Bs'ste&.1ebA ?Bcon#i)u"ationA
Each &e#.config file should #egin with the standard -M. declaration) though it will wor' without it. The file also contains o"ening and closing :configuration; tags. Nested within those tags are the o"ening and closing :system.web; tags) indicating that the content within is ASP.NET/s"ecific configuration information. This configuration information is su""lied in tags referred to as elements. Each element consists of an o"ening and closing tag. An$ attri#utes are defined within the o"ening tag and an$ child elements are defined #etween the o"ening and closing tags. 3f an element doesn+t ha%e child elements) $ou can omit the closing tag #$ adding the forward slash ?EA character at the end of the o"ening tag. ?This is standard -M. s$nta1.A You+ll see this format in action later in this cha"ter) as well as in A""endi1 B. NOTE Man$ de%elo"ers found it frustrating when Microsoft Visual 3nter0e% 6 reformatted code according to its "referred st$le. That feature was difficult) if not im"ossi#le) to turn off. 3n Microsoft Visual Studio .NET) not onl$ can $ou control how code is %alidated and formatted) #ut in most cases $ou can also turn off autoformatting entirel$.
To %iew or change the formatting settings for a gi%en language) from the Tools menu select *"tions) and then clic' the Te1t Editor folder. ,lic' the folder for the language of $our choice. Note that for some languages) the formatting settings a""ear on more than one o"tion "age. For e1am"le) <TM.E-M. formatting o"tions are set on the Format "age) the <TM. S"ecific "age) and the -M. S"ecific "age) all under the <TM.E-M. folder.
*"en &e#.config
2. Either o"en the ,ha"terO Q "ro;ect from the "ractice files) or create a new "ro;ect named ,ha"terO Q) using the ste"s $ou learned in ,ha"ter 2. 2. .ocate the &e#.config file in the Solution E1"lorer window and dou#le/clic' it. The &e#.config file will #e o"ened for editing using the Visual Studio .NET -M. editor) as shown in the following illustration. &e+ll loo' at e1am"les of editing this file later in the cha"ter) so $ou might want to lea%e it o"en.
3n addition to s$nta1 coloring and %alidation) Visual Studio .NET "ro%ides a default &e#.config file for each new &e# a""lication "ro;ect that $ou create. This default file contains the most commonl$ used elements) as well as comments that e1"lain the a%aila#le o"tions for each element) as shown in the "re%ious illustration. The default &e#.config file is useful as a tem"late for an$ additional &e#.config files $ou want to "lace in su#folders of $our &e# a""lication. >ee" in mind that when $ou+re using configuration files in su#folders of $our a""lication) it+s a good idea to include onl$ the elements for the configuration settings from the "arent file that $ou want to o%erride. This hel"s "re%ent the accidental o%erriding of a configuration setting) and it might hel" reduce "arsing o%erhead for the configuration of $our a""lication.
de%elo"ers using the machine. 9nless $ou en;o$ dealing with unha""$ colleagues) $ou should discuss an$ "ro"osed changes with them first.
8. 0ou#le/clic' the &e# Form in the 0esign %iew window. The code/#ehind module for fnf.as"1 will #e dis"la$ed in the code editor window) with the cursor automaticall$ mo%ed to the Page0<oad e%ent handler. Note that a local declaration has #een added to the code/#ehind for the <abel control to allow "rogrammatic access to the control #$ its name) <abel> ?$ou will need to e1"and the region mar'ed 4&e# Form 0esigner @enerated ,ode)5 as shown in the following illustration) to see the declarationA=
/"otecte! 4it+ ,ents Label1 0s .'ste&.4eb.=(.4eb-ont"ols.Label
Q. 7e"lace the "laceholder comment in the Page0<oad e%ent handler with the code in the illustration on the following "age. ?The ASP.NET runtime adds the asp$errorpath (uer$ string %aria#le automaticall$ and "o"ulates it with the "ath re(uested #$ the user when redirecting from an <TTP error.A
:. Label1.Text = "4e'"e so""'. T+e *a)e 'ou "e@ueste!J " & < E. 6e@uest.Nue"'.t"in)2"as*xe""o"*at+"3 & < " !oes not exist."
D. Sa%e fnf.as"1 and fnf.as"1.%#. C. 3f it is not alread$ o"en) o"en &e#.config #$ dou#le/clic'ing it in Solution E1"lorer. 2 . Modif$ the :customErrors; element to loo' li'e the code in the illustration on the following "age) and then sa%e the file. ?The :error; child element ma"s the <TTP 8 8 error code to redirect to the &e# Form created in a "re%ious ste".A
11. ?custo& ""o"s &o!e="9n"A 1$. ?e""o" status-o!e="4H4" "e!i"ect="#n#.as*x"BA ?Bcusto& ""o"sA
2!. From the Build menu) select Build ,ha"terO Q to #uild the "ro;ect. 28. 7ight/clic' &e#Form2.as"1 ?the default &e# Form added to the "ro;ect when it was createdA) select Browse &ith) select Microsoft 3nternet E1"lorer from the Browser .ist window) and then clic' Browse) as shown in the following illustration. ?This will o"en the "age in a se"arate #rowser window) rather than one em#edded in the 30E.A
2Q. 9sing the 3nternet E1"lorer address #ar) change the file "ortion of the 97. from &e#Form2.as"1 to &e#Form.as"1 ?a file that does not e1istA) and then clic' the @o #utton. The "age will redirect to fnf.as"1) and dis"la$ a message similar to the following. ?The "ath can %ar$ de"ending on how $ou set u" $our "ro;ect.A
You can use this techni(ue to "ro%ide useful error messages to $our users) as in this e1am"le) or $ou can e1"and on it #$ using the redirect "age to send a notification to an administrator of the error) using the Microsoft .NET Framewor'+s Smtp9ail class. ?You+ll learn how to use the Smtp9ail class in ,ha"ter D.A Kttp9odules are classes that "artici"ate in the "rocessing of e%er$ re(uest made to an a""lication. The #uilt/in Kttp9odules in ASP.NET include SessionState9odule and +utput=ache9odule) as well as modules for each of the #uilt/in authentication methods in ASP.NET. These modules are added #$ default in machine.config using the :http9odules; element. You can use the :http9odules; element in $our &e#.config file to remo%e an$ of
these modules that $ou+re not using) or to add additional http9odules ?including $our own custom http9odulesA.
7emo%e an Kttp9odule
2. *"en &e#.config ?if it isn+t alread$ o"enA #$ dou#le/clic'ing it in Solution E1"lorer. 2. Fust under the :system.web; tag) add an :http9odules; element to the file) as shown in the following illustration=
3. ?+tt*7o!ulesA 4. ?"e&o,e na&e=".ession"BA ?B+tt*7o!ulesA
Q. ,hange the mode attri#ute of the :customErrors; element to +ff. ?You+ll see wh$ in a few ste"s.A 6. 0ou#le/clic' the file &e#Form2.as"1 in Solution E1"lorer) and then dou#le/clic' the "age in the editor. The code/#ehind module for &e#Form2.as"1 will #e dis"la$ed for editing) as shown in the following illustration.
K. 7e"lace the comment in Page0<oad with the following code) shown in the following illustration=
.ession2"#oo"3 = "Ba""
D. Sa%e all o"en files and #uild the "ro;ect. C. 3n Solution E1"lorer) right/clic' &e#Form2.as"1) and then select Browse &ith to #rowse the "age in a se"arate #rowser window. ?Select 3nternet E1"lorer as $ou did in the "re%ious e1ercise.A The re(uest will result in an e1ce"tion) #ecause $ou+%e remo%ed the SessionState9odule from the a""lication. <ad $ou not modified the :customErrors; element in Ste" !) $ou would see a generic error message instead of the detailed message shown in the following illustration.
2. ,reate a new &e#.config file in the new folder. !. Add the configuration settings $ou want to o%erride to the new &e#.config file. 3nclude onl$ the configuration elements that $ou want to o%erride in the new &e#.config file. All other settings are inherited from the &e#.config file of the "arent folder or) if that file doesn+t e1ist ?or doesn+t contain settings for all a%aila#le configuration elementsA) from the machine.config file for $our &e# ser%er.
?BlocationA
The path attri#ute should #e the name of a su#director$. The elements that a""ear inside the system.web tags will #e treated as if the$ were in the &e#.config file in that su#director$. K. Add the desired configuration elements #etween the :system.web; and :/system.web; tags.
NOTE The "ath to as"netOregiis.e1e ma$ not #e registered in the Path en%ironment %aria#le on $our machine) in which case $ou will need to either include the full "ath to the e1ecuta#le
?$ou can locate it using the &indows search toolA or follow the instructions in A""endi1 , for adding the "ath to as"netOregiis.e1e to the Path en%ironment %aria#le. !. To %erif$ that the configuration was successful) o"en the 33S Manager) na%igate to the a""lication in (uestion) right/clic' the a""lication and select Pro"erties) and then clic' the ,onfiguration #utton. 3n the Ma""ings ta#) scroll down to the .as"1 e1tension) and ho%er the mouse o%er the E1ecuta#le Path column for that e1tension. The %ersion num#er in the toolti" that dis"la$s the "ath to the e1ecuta#le should loo' li'e the one in the following illustration.
IMPORTANT 3n &indows Ser%er 2 ! with 3nternet 3nformation Ser%ices 6. ) a new "rocess model is used in which a num#er of a""lications are run in one or more "rocesses using an a""lication "ool designation. A""lications using different a""lication "ool designations ne%er share the same "rocess. The reason this is im"ortant is that if $ou tr$ to configure an a""lication to run against a different %ersion of ASP.NET than other a""lications in the same a""lication "ool) $ou might get an error message similar to the following in the E%ent .og= "t is not possible to run different %ersions of /SP.NET in the same ""S process. Please use the ""S /dministration Tool to reconfigure your ser%er to run the application in a separate process.To resol%e this issue) $ou must create a new a""lication "ool and assign it to the a""lication that is to #e configured differentl$ from the others in the e1isting "ool.
Do this folder. &ra" the settings to #e loc'ed down with a :location; :/location; tag "air with the allow+%erride attri#ute set to 1alse.
7emo%e unused ser%ices to reduce securit$ e1"osure. ,reate and a""l$ securit$ "olicies to sim"lif$ the configuration of *S securit$ settings. Secure the s$stem administrator account for an MS0E data#ase instance. Validate and restrict user in"ut. Ena#le logging of &e# re(uests. Ena#le SS. encr$"tion of &e# re(uests. Ena#le &indows or Forms authentication for ASP.NET. 9se A,. or 97. authoriGation to control access to resources. 9se trusted connections with S:. Ser%er or MS0E data#ases.
3n da$s gone #$) there were "rimaril$ two t$"es of a""lications= single/user a""lications in which "resentation) #usiness logic) and an$ necessar$ data handling all occurred on the client machine of the userI and clientEser%er a""lications) which remo%ed much or all of the data handling to a se"arate data#ase ser%er. Bac' then) securit$ was largel$ a matter of ma'ing sure that in a clientEser%er situation) users made modifications onl$ to data that the$ were authoriGed to change. The t$"ical a""lication de%elo"er seldom had to face issues such as denial/of/ser%ice attac's) "ort sniffing) and so on. The 3nternet has changed all that fore%er. A""lications that are e1"osed to the 3nternet are inherentl$ %ulnera#le to a host of issues) ranging from attem"ts at stealing data to the defacing of &e# sites to denial/of/ser%ice attac's. No matter what o"erating s$stem or other software $ou run) that %ulnera#ilit$ will ne%er go awa$ entirel$. Software is an im"erfect science) and unfortunatel$) an o"erating s$stem in%ulnera#le to attac' has $et to #e created.
The good news is that most software) including Microsoft &indows 2 ) Microsoft &indows -P) 33S) and Microsoft &indows Ser%er 2 ! can #e made (uite secure if $ou follow #est "ractices ?a recogniGed set of recommended "rocedures and "oliciesA for securit$) such as 'ee"ing trac' of and installing securit$ "atches as soon as the$ are released. *ne of the remar'a#le things a#out securit$ "ractices in our industr$ is ;ust how man$ ser%ers ?#oth Microsoft/#ased and otherwiseA are sitting out there e1"osed to the 3nternet) without "atches installed that ha%e #een a%aila#le for months) or e%en $earsH
A denial/of/ser%ice attac' can "re%ent users from accessing $our site #$ flooding it with illegitimate re(uests) among other techni(ues. These attac's can #e difficult to "re%ent. ,onse(uences of not addressing this threat include com"romise of credit card or other sensiti%e data and illicit modification of ser%er data.
0ata loss or com"romise 0ata com"romised through "ac'et sniffing Ser%er data com"romised through user im"ersonation or data forger$
NOTE A more com"lete discussion of this to"ic is a%aila#le in ,ha"ter 28 of &illiam Stallings+) =ryptography and Network Security: Principles and PracticeP (d ed. ?Prentice <all) 2CCDA.
Securit) Basics
&ith so man$ "otential threats against 3nternet a""lications) it+s often difficult to 'now ;ust where to start in designing a secure a""lication. This section will discuss some of the strategies $ou can use to get started.
host a &e# a""lication is that these o"erating s$stems can use the NTFS file s$stemI the &indows C$ series cannot. NTFS allows $ou to "ro%ide ro#ust access control at #oth the file and folder le%el) and it also "ro%ides #uilt/in su""ort for file encr$"tion. The FAT and FAT!2 file s$stems ?a%aila#le in the C$ seriesA are "oor choices for &e# a""lications re(uiring ro#ust securit$. Ser%er o"erating s$stems offer the most ro#ust securit$ features) as well as #etter scala#ilit$) greater ease of configuration) and #etter features for de%elo"ers. Your e%aluation should include an anal$sis of features ?in this case) securit$ featuresA) cost) and the e1isting en%ironment) with the goal of determining which *S meets $our securit$ needs ?featuresA) while allowing $ou to wor' within the constraints of cost and e1isting en%ironment ?if an$A. IMPORTANT &indows 2 and &indows -P "ro%ide a num#er of ma;or securit$ im"ro%ements) including #uilt/in su""ort for file s$stem encr$"tion) securit$ "olicies and tem"lates ?discussed later in this sectionA) and a Securit$ ,onfiguration and Anal$sis tool. This tool can #e %er$ useful in determining whether $our s$stem will meet $our securit$ needs as configured) and can hel" $ou easil$ configure it if it doesn+t. For these reasons) &indows 2 ?or laterA should #e the default choice for secure &e# a""lications on the Microsoft "latform. Additionall$) the &e# Ser%er edition of &indows Ser%er 2 ! contains man$ securit$ im"ro%ements that should ma'e it the first choice for #uilding new ASP.NET &e# a""lications) whene%er "ossi#le.
,hoosing a Pur"ose
Another im"ortant "oint to consider when choosing $our o"erating s$stem is the "ur"ose of the ser%er. For smaller a""lications with low scala#ilit$ re(uirements) it can #e acce"ta#le to run $our &e# ser%er) data#ase ser%er) and com"onents all on the same machine. Because 33S and most data#ases ma'e significant demands on #oth 7AM and "rocessor "ower) this model does not scale "articularl$ well for larger a""lications. More im"ortant) howe%er) "lacing a data#ase on a &e# ser%er that is e1"osed to the 3nternet greatl$ increases the securit$ ris's to the data stored in that data#ase. This can also #e true for other ser%er and a""lication software) from mail/ ser%er software to "roducti%it$ a""lications such as Microsoft *ffice. The im"ortant "oint is that as $ou add more functionalit$ to a ser%er) $ou are also adding more securit$ e1"osure. >ee" all of this in mind as $ou configure $our ser%ers and decide the "ur"ose for each one.
'nown %ulnera#ilities. ?You can reduce the ris' of com"romise through diligent a""lication of "atches. See 4Patching5 for more information.A 3f $ou are not using a ser%ice) $ou should a%oid installing it) or use the Add *r 7emo%e Programs ,ontrol Panel a""let to remo%e it. The following ste"s) which are s"ecific to &indows Ser%er 2 !) show how to do so. ?The "rocedure for &indows 2 and &indows -P is similar.A TIP The Microsoft Baseline Securit$ Anal$Ger ?MBSAA tool) which is discussed later in this cha"ter ?see 4Patching5A) can assist $ou in identif$ing some of the more common unnecessar$ ser%ices that $ou might consider remo%ing.
Q. To remo%e a ser%ice or com"onent) unchec' ?deselectA the chec' #o1 ne1t to it) as done for the SMTP ser%ice shown in the following illustration. ,lic' *> to close the 0etails dialog #o1) and again to close the A""lication Ser%er dialog #o1 ?this is not necessar$ in &indows 2 and &indows -PA.
6. ,lic' Ne1t to a""l$ $our changes. K. ,lic' Finish to com"lete the "rocess) as shown in the following illustration.
3f $ou need to install ser%ices that are not used all the time) $ou should set them to #e started manuall$ rather than automaticall$. This wa$) $ou ha%e control o%er when these ser%ices are running. Be aware) howe%er) that in some cases) e%en ser%ices configured for manual startu" can #e started #ecause other ser%ices are de"endent on them. 3f $ou ha%e a ser%ice $ou reall$ do not want to e%er start) $ou can set the startu" t$"e to disa#led) and the ser%ice will not start) and cannot #e started as a de"endent ser%ice. IMPORTANT 7emo%ing unused ser%ices is one wa$ of reducing the so/called surface area that a "otential attac'er has to wor' with. This techni(ue a""lies not ;ust to ser%ices #ut to an$ software running on a gi%en machine. You should ne%er install unnecessar$ software) whether file sharing software) "roducti%it$ software) or third/"art$ utilities) on a ser%er unless $ou a#solutel$ must and $ou understand the securit$ im"act that installing them entails.
Be a Polic$ Ma'er
*ne unheralded feature of &indows 2 and later is a ro#ust set of tools for setting u" a machine+s securit$ settings (uic'l$ and relati%el$ "ainlessl$. A full discussion of these tools is #e$ond the sco"e of this #oo' ?and could ta'e u" a #oo' of its ownA) #ut let+s loo' at a cou"le of them.
The Securit$ Tem"lates tool and the Securit$ ,onfiguration and Anal$sis tool) when used together) let $ou create) edit) and a""l$ tem"lates for defining securit$ "olicies) from minimum "assword length to file s$stem auditing "olic$. Both tools) shown in the following illustration) are im"lemented as Microsoft Management ,onsole ?MM,A sna"/ins.
NOTE You can also define securit$ "olicies manuall$ #$ using the .ocal Securit$ Polic$ editor) which $ou can find #$ o"ening the ,ontrol Panel ?and switching to ,lassic View) if re(uiredA and then dou#le/clic'ing Administrati%e Tools and then the .ocal Securit$ Polic$ icon. This tool allows $ou to ad;ust indi%idual local securit$ "olic$ settings as well as a""l$ securit$ tem"lates to the local machine.
8. ,lic' the ,lose #utton to close the Add Standalone Sna"/in dialog #o1) and then clic' *> to close the AddE7emo%e Sna"/3n dialog #o1. Q. 3f desired) from the File ?or ,onsoleA menu clic' Sa%e ?,trlLSA or Sa%e As to sa%e $our new or modified MM, console. NOTE An infre(uentl$ used #ut hel"ful feature of the MM, is creating and sa%ing custom consoles that contain the MM, sna"/ins $ou use most fre(uentl$. You can use the "rocedure outlined in the "receding list to add the Securit$ ,onfiguration and Anal$sis sna"/in ?or an$ other sna"/inA to a console. The ad%antage of using the Securit$ Tem"lates tool to create and edit $our securit$ tem"lates is that it allows $ou to create securit$ "olic$ tem"lates se"aratel$ from a""l$ing the tem"late to the local machine.
2. 7ight/clic' the tem"late "ath folder where $ou want to store $our new tem"late) and then select New Tem"late. The following dialog #o1 will #e dis"la$ed.
!. T$"e the name TestTe%(late and the descri"tion This is a test te%(late for the new tem"late and clic' *>. The new tem"late will #e dis"la$ed under the "ath folder $ou
selected in Ste" 2) as shown in the following illustration. ?You might need to e1"and the node for the tem"late folder to %iew the new tem"late.A
8. E1"and the node for $our new tem"late #$ dou#le/clic'ing it) or clic' the L sign ne1t to it to dis"la$ the o"tions a%aila#le for configuration with the tem"late. Q. E1"and the "olic$ area $ou want to customiGe) such as the Password Polic$ ?which can #e found under the Account Policies nodeA. Select the "olic$ to %iew its a%aila#le Polic$ attri#utes in the right "ane of the console window. 6. 0ou#le/clic' Minimum Password .ength "olic$. K. ,hec' 0efine This Polic$ Setting 3n The Tem"late) as shown in the following illustration. Edit the %alue to $our desired setting.
D. ,lic' *> to close the Tem"late Securit$ Polic$ Setting dialog #o1 and a""l$ $our change to the tem"late. C. After ma'ing an$ additional changes to the tem"late) sa%e it #$ right/clic'ing the TestTem"late node and selecting Sa%e. *f course) once $ou+%e created $our custom tem"late) $ou might want to use it to configure securit$ for one or more machines. You can do this #$ using the Securit$ ,onfiguration and Anal$sis tool) which $ou can also use to determine which settings on the local machine are not in com"liance with the tem"late $ou+%e defined ?or one of the "redefined tem"latesA. IMPORTANT As with man$ securit$/related tas's) $ou must #e logged in as an administrator to successfull$ anal$Ge the current securit$ settings and a""l$ securit$ tem"lates. Non/administrators can start u" the Securit$ Tem"lates and Securit$ ,onfiguration and Anal$sis tools) #ut will recei%e errors if the$ attem"t to "erform actions for which the$ do not ha%e the necessar$ "ermissions. You can also use tem"lates to define securit$ settings for de%elo"ment) staging) and "roduction securit$ re(uirements. A de%elo"ment or staging ser%er+s securit$ re(uirements are usuall$ less restricti%e than those for a "roduction ser%er en%ironment) where the com"leted a""lication ultimatel$ will #e de"lo$ed. 9nfortunatel$) when an a""lication is mo%ed to the more restricti%e en%ironment of the "roduction ser%er) securit$ restrictions can "re%ent the a""lication from wor'ing. You can define securit$ tem"lates for de%elo"ment) staging) and "roduction en%ironments and then a""l$ those tem"lates to $our de%elo"ment andEor staging ser%ers to test whether the a""lication will wor' with the greater restrictions of those en%ironments. *nce testing is com"lete) $ou can restore the "re%ious tem"late to continue de%elo"ment wor'. IMPORTANT Because the Securit$ Tem"lates tool can affect a large num#er of securit$ settings on a machine) it is %er$ im"ortant that $ou configure and test $our tem"lates on de%elo"ment or staging
s$stems #efore a""l$ing them to "roduction s$stems. ,ertain securit$ restrictions can "re%ent &e# a""lications from functioning "ro"erl$ ?for e1am"le) #$ restricting access on accounts used #$ the a""licationA) so $ou should alwa$s ma'e sure $our a""lication wor's "ro"erl$ under the securit$ "olic$ defined #$ the tem"late #efore a""l$ing the tem"late to a "roduction s$stem.
Q. You can com"are the settings in the tem"late to those currentl$ configured on the local machine #$ right/clic'ing the Securit$ ,onfiguration and Anal$sis node) selecting Anal$Ge ,om"uter Now) and then clic'ing *> in the Perform Anal$sis dialog #o1. 6. E1"and the Account Policies node to dis"la$ the Password Polic$ node. Select the Password Polic$ node to %iew its settings) as shown in the following illustration. A green chec' mar' indicates where local settings match the tem"lateI a red - indicates where the settings do not match.
K. To configure the local machine with the settings s"ecified in the tem"late) right/clic' the Securit$ ,onfiguration and Anal$sis node) select ,onfigure ,om"uter Now) and then clic' *> in the ,onfigure S$stem dialog #o1. 3f $ou want to %iew the settings modified #$ the tem"late) $ou will need to reanal$Ge the com"uter as descri#ed in Ste" Q. >ee" in mind that onl$ settings for which a %alue has #een defined in the tem"late will #e a""lied. All other settings will remain as the$ were "re%iousl$ configured. Also note that when a ser%er that $ou+re configuring is "art of a &indows 2 or &indows Ser%er 2 ! domain) an$ settings configured in the domain/wide securit$ "olic$ will o%erride settings in the local securit$ "olic$.
Passwords) Please
*ne of the most commonl$ ?and dangerousl$A o%erloo'ed areas in &e# ser%er securit$ is "assword "rotection. Pro#lems in this area include wea' or none1istent "asswords for sensiti%e information or ser%ices) and "asswords "laced in "lain/te1t files such as ASP and ASP.NET "ages) @lo#al.asa or @lo#al.asa1 files) or configuration files in the &e# s"ace.
!. 3f the connection is successful) $ou+ll see the following "rom"t. ?3f the login fails) $ou+ll get a failure message.A
1A
8. 3f the login is successful) enter the following commands to modif$ the "assword for the sa account. Ma'e sure that $ou memoriGe the new "assword so $ou won+t forget it. ?A%oid writing it down if "ossi#le. But if $ou must) ma'e sure $ou "ut it somewhere secure so "r$ing e$es won+t find it.A 7e"lace :new password; with the new "assword $ou+%e chosen) and follow the go command #$ "ressing the Enter 'e$=
8. 1A s*<*ass1o"! N=LL, ' ?ne1 *ass1o"!A', 'sa' $A )o
6. 3f the result is successful) $ou should see the message shown in the following illustration. Also note that) in this e1am"le) a "assword containing letters) num#ers) and s$m#ols has #een chosen. IMPORTANT Although it might seem o#%ious) $ou should not use the "assword shown in this e1am"le as the sa "assword for $our S:. Ser%er or MS0E instance. 3nstead) choose a uni(ue %alue that will #e difficult to guess.
K. T$"e e0it) and then "ress the Enter 'e$ to e1it the os(l utilit$.
You can also use the S:. Ser%er Enter"rise Manager utilit$) if it is a%aila#le) to modif$ the login accounts and "asswords for an MS0E data#ase. Almost as #ad as #lan' "asswords are "asswords that are wea' ?easil$ guessa#leA) such as
Names or "laces 0ates) such as #irthda$s or anni%ersaries &ords found in a dictionar$ Short "asswords ?D characters or fewerA Passwords that are all letters) all lowercase) all u""ercase) or all numeric
&ea' "asswords ma'e it much easier for someone tr$ing to hac' a ser%er to guess the "assword for an account. So/called dictionary attacks use a dictionar$ of common terms or words to ra"idl$ attem"t to log in to an account. 2rute force attacks attem"t e%er$ "ossi#le %alue until the$ find the correct one. &hile a strong "assword won+t necessaril$ eliminate #rute force attac's) it can increase the time needed for such an attac' to succeed. 3n com#ination with a""ro"riate auditing and logging) this can gi%e $ou time to deal with the attac'. Strong "asswords meet minimum re(uirements for length and com"le1it$. You can re(uire secure "asswords using a securit$ tem"late) such as the hisecwe#.inf tem"late) or #$ using the Securit$ ,onfiguration and Anal$sis tool as descri#ed earlier in this cha"ter. The hisecwe#.inf tem"late sets minimum and ma1imum "assword age) enforces "assword histor$ ?"re%enting users from reusing old "asswordsA) sets minimum "assword length to eight characters) and re(uires "asswords to meet minimum com"le1it$ re(uirements) including re(uiring "asswords to include three of the following four categories of characters=
9""ercase characters .owercase characters Numeric characters Nonal"hanumeric s$m#ols ?such as "unctuation and s"ecial characters such as V) J) and [A
Note that these settings control "asswords onl$ for NT securit$ accounts. 3f $ou use $our own authentication credentials in $our a""lication) $ou will need to im"lement $our own solution for enforcing strong "asswords) such as using the 7egularE1"ressionValidator Ser%er ,ontrol to "erform "attern matching. ?See ,ha"ter D for more information on %alidation controls.A IMPORTANT *ne of the #est things an a""lication de%elo"er can do to encourage users to use strong "asswords is to hel" reduce the number of "asswords that users must remem#er. Too man$ times) we design a""lications without an$ consideration for the host of "asswords users must
remem#er for other a""lications or &e# sites. The more "asswords users ha%e to remem#er) the more li'el$ the$ are to choose sim"le ?and easil$ guessedA "asswords or to write "asswords down on stic'$ notes attached to their monitors. So what should $ou) as an a""lication de%elo"er) doU Find wa$s to reduce the num#er of "asswords $ou re(uire $our users to remem#er. A cou"le of ideas for this include=
,onsolidate authentication for multi"le a""lications under $our control whene%er "ossi#le. Allowing a single sign/on to multi"le a""lications can reduce the o%erhead of managing logins ?authenticationA) while a""lication rights can still #e assigned on a "er/ user #asis ?authoriGationA. 9se &indows Authentication whene%er "ossi#le. 9sing &indows authentication means that users do not need to remem#er a se"arate username and login for $our a""lication. *f course) if $ou+re going to use &indows authentication) $ou should encourage the use of strong "assword "olicies in $our organiGation so $our a""lication will #e less %ulnera#le to easil$ guessed "asswords.
*ther "ractices) such as limiting the length of "asswords or ma'ing certain characters in%alid in a "assword) can discourage users from reusing "asswords that the$ ha%e memoriGed for other a""lications. <ere) there+s a #alancing act #etween the desira#le "ractice of ha%ing uni(ue "asswords and the realit$ that more "asswords to remem#er often means shortcuts li'e writing down "asswords. 3n cases li'e these) as' $ourself which is worse= users reusing e1isting "asswords ?assuming these meet $our re(uirements for strong "asswordsA or users writing down new "asswords #ecause the$ aren+t going to #e a#le to remem#er them. Fust remem#er that while securit$ is a %er$ im"ortant goal) if $ou ma'e securit$ too hard for $our users to deal with) $ou might end u" encouraging "ractices that ma'e $our a""lication less secure in the end.
3f $ou+re using S:. Ser%er or MS0E) use a trusted connection to connect to $our data#ase. This method uses the Trusted0=onnection attri#ute of a connection string to tell S:. Ser%er to use the current user+s NT login information to log in. This is most useful in intranet scenarios where users log in to $our a""lication %ia NT.M with an NT username
and "assword. This method gi%es $ou the ad%antage of not needing to store a "assword at all. Store the connection string information in the machine.config file) which is not directl$ in the &e# s"ace of the a""lication) using the a""Settings configuration section ?descri#ed in A""endi1 BA. Although this method is still not ideal #ecause "assword information is still #eing stored in "lain te1t) the fact that the machine.config file is stored outside of the &e# s"ace ma'es it that much harder for a malicious user to get to this file. For #etter securit$ with this method) the director$ containing machine.config and the director$ containing $our &e# a""lication should reside on different dri%es. For "asswords used with Forms Authentication) $ou can use the a"tl$ ?if aw'wardl$A named KashPassword1orStoring"n=onfig1ile hel"er method of the 1orms/uthentication class to hash a "assword for storing in a configuration file or in a data#ase or -M. file. You can then use the same method to hash the "assword entered #$ the user at run time and com"are the two hashes to determine whether to allow the login to succeed. You+ll learn how to store hashed "asswords later in this cha"ter.
3n addition) $ou can use such techni(ues as encr$"tion ?using the classes in the S$stem.Securit$.,r$"togra"h$ names"aceA to ma'e a would/#e hac'er+s ;o# more difficult. The #ottom line is that there is reall$ no 2 /"ercent/secure "lace that $ou can store "asswords) #ut some methods are more secure than others. Balance $our need for securit$ against other factors when choosing how and where to store sensiti%e information. NOTE 9sing a trusted connection with S:. Ser%er re(uires either using &indows authentication and im"ersonation) as descri#ed in 49sing 3m"ersonation5 or setting u" the default ASPNET account ?the account used to run the ASP.NET wor'er "rocessesA as a login account in the S:. Ser%er data#ase #eing accessed. This "rocess is descri#ed in ,ha"ter C.
3n ASP.NET 2. under 33S Q. ) the default is the ASPNET account ?s"ecified #$ the 9/=K"NE %alue for the username attri#ute of the :process9odel; configuration element in machine.configA) which has %er$ few "ri%ileges on the s$stem. This change ma'es certain techni(ues more difficult to use) #ut it also reduces the li'elihood that a single com"romised a""lication can com"romise an entire s$stem or an entire networ'. NOTE &hen running 33S 6 on &indows Ser%er 2 ! in nati%e mode ?the defaultA) the 33S 6 "rocess model settings ?accessed through the Pro"erties dialog #o1 of the a""lication "ool containing $our a""licationA are used) and the settings contained in the :process9odel; element in machine.config are ignored. Since the default identit$ of an a""lication "ool "rocess in 33S 6 is the new Networ' Ser%ice #uilt/in account) rather than the ASPNET account) an$ a""lications that use 3m"ersonation and grant rights to the ASPNET account would need to #e modified to grant those same rights to the Networ' Ser%ice account to run on 33S 6 in nati%e mode. Another e1am"le of a ma;or %iolation of the "rinci"le of least "ri%ilege is running data#ase code using the S:. Ser%er sa account. Ne%er do this) e%erH 3f $ou run $our data#ase code ?whether raw S:. or stored "rocsA using the sa account) it ta'es onl$ one coding error on $our "art for $our entire data#ase ser%er to #e com"romised. And once an attac'er has control o%er one machine in $our networ') it is far easier for the same outlaw to #rea' into others. 0on+t let this ha""en to $ou. Alwa$s use accounts with the minimum necessar$ "ri%ileges to access and u"date data#ase data.
Additionall$) some sam"le a""lications demonstrate e1tremel$ "oor "ractices when it comes to securit$. Earl$ %ersions of the ASP.NET :uic'Start sam"les used the sa account with a #lan' "assword for data#ase connections. This is an e1tremel$ #ad "ractice. Not onl$ does it reinforce the #ad ha#it of lea%ing the sa account with no "assword) #ut it also uses an account for data access that has much wider "ermissions than are necessar$ for data access alone. The good news is that the current %ersions of the :uic'Start sam"les follow the #est "ractice of using an MS0E account created es"eciall$ for the sam"le a""lications. This account has "ermission onl$ to access the data#ases used #$ the sam"les) and onl$ the "ermissions on those data#ases necessar$ for the sam"les. Although the changes in the .NET Framewor' :uic'Start sam"les indicate that Microsoft is committed to demonstrating #etter securit$ "ractices in sam"le a""lications) $ou should ne%er install them on a "roduction ser%er ?or an$ other ser%er that is e1"osed to the 3nternet) for that matterA without a %er$ clear understanding of the ris's entailed) and without underta'ing efforts necessar$ to mitigate those ris's. TIP The MBSA tool ?mentioned earlier in 4Too Much Ser%ice5 and discussed later in 4Patching5A can assist $ou in identif$ing sam"les commonl$ installed #$ default in some %ersions of 33S. 3t does not) howe%er) identif$ the .NET Framewor' :uic'Start sam"les as a securit$ ris'. Nonetheless) to reduce the a%aila#le attac' surface $ou "resent to "otential attac'ers) $ou generall$ should a%oid installing the :uic'Start sam"les on a "roduction ser%er e1"osed to the 3nternet.
and an associated .egularE$pressionDalidator control that limits in"ut to a small su#set of <TM. tags and "unctuation characters. The regular e1"ression used in the code e1am"le is ta'en from ,ha"ter 2! of Michael <oward and 0a%id .eBlanc+s riting Secure =ode) 2d ed. ?Microsoft Press) 2 2A. IMPORTANT You should alwa$s chec' for %alid in"ut rather than chec'ing for in%alid in"ut. The inherent "ro#lem with chec'ing for in%alid in"ut or data is that it is far too eas$ to miss a "articular t$"e of in%alid in"ut. ,hec'ing for %alid in"ut according to rules $ou define and re;ecting an$ other in"ut is more li'el$ to ensure that $ou don+t acce"t malicious in"ut #$ accident.
?#o"& i!="Fo"&1" &et+o!="*ost" "unat="se",e""A ?!55 <O an! &)tO "e*"esent ? an! A 55A ?as*JLabel i!="Label1" "unat="se",e""A nte" text to !is*la' 2<Ob&)tO, <Oi&)tO, <O+"&)tO acce*table3J?Bas*JLabelA ?as*JButton i!="Button1" "unat="se",e"" Text="%is*la'"BA ?as*JTextBox i!="TextBox1" "unat="se",e"" Text7o!e="7ultiLine" Hei)+t="11$*x" 4i!t+="43$*x"A?Bas*JTextBoxA ?as*J6e)ula" x*"essionVali!ato" i!="6e)ula" x*"essionVali!ato"1" "unat="se",e"" ""o"7essa)e="(n,ali! (n*ut Foun!!" ?!55 T+is ,ali!ation ex*"ession 1ill allo1 onl' ?iA, ?bA, an! ?+"A ta)s, s*aces, an' text 05Ka5DH5G, an! t+e #ollo1in) *unctuationJ P!,.'". 0ll ot+e" in*ut 1ill cause t+e ,ali!ation to #ail. Note t+at t+is ex*"ession !oes not ,ali!ate #o" 1ell5#o"&e! HT7L 55A Vali!ation x*"ession="R2SQsQ1QPQ!Q,Q.Q'Q&@uotOTUV2?BP2iV(VbVBV+"VH63A33UW" -ont"olToVali!ate="TextBox1"A?Bas*J6e)ula" x*"essionVali!ato"A ?as*JLabel i!="Label$" "unat="se",e""A?Bas*JLabelA ?B#o"&A
You+ll learn more a#out using the ASP.NET %alidation controls in ,ha"ter D. You can learn more a#out using regular e1"ressions for %alidating user in"ut in ,ha"ter 22 and ,ha"ter 2! of riting Secure =ode) 2d ed.) #$ Michael <oward and 0a%id .eBlanc ?Microsoft Press) 2 2A. A good source for regular e1"ressions for a %ariet$ of "ur"oses is http://www.rege$lib.com/) a site run #$ Ste%en A. Smith) a noted leader in the ASP.NET communit$.
or at the "age le%el using the %alidate.e4uest attri#ute of the @ Page directi%e=
?I M /a)e Vali!ate6e@uest="#alse" IA
IMPORTANT 3t is highl$ recommended that $ou do not disa#le 7e(uest Validation unless $ou ha%e first ensured that all in"ut to the "age or a""lication is #eing a""ro"riatel$ %alidated andEor filtered for "otentiall$ dangerous data. Failure to heed this recommendation can result in data loss or other serious securit$ "ro#lems.
?among othersA are left o"en #$ default. This gi%es hac'ers an engra%ed in%itation to "ro#e these "orts and see if the software #ehind them is %ulnera#le to attac'. @i%en the man$ %ulnera#ilities disco%ered in FTP) SMTP) and other 3nternet/#ased ser%ices) it is essential to close all "orts that are not in use #$ $our a""lication. ,losing "orts can #e accom"lished in a num#er of wa$s) the most common #eing through the use of firewall software or a hardware router with firewall functionalit$) or using the 3P Securit$ Polic$ Management MM, sna"/in in &indows 2 or &indows -P. For man$ a""lications) the "referred solution is to set u" a hardware firewall #etween the &e# ser%er and the 3nternet that allows traffic onl$ on "ort D ?<TTPA) and o"tionall$ "ort 88! ?<TTPSA if secure soc'ets &e# traffic is re(uired. ?See 49sing SS. to Protect ,ommunications5 for more information on Secure Soc'ets .a$er communication.A Then a second firewall is added #etween the &e# ser%er and the internal networ' that allows traffic onl$ on "orts necessar$ for the &e# ser%er to reach other ser%ers ?such as the data#ase ser%erA) and also #loc's "orts D and 88! ?and an$ other "orts o"en in the other firewallA. This method "laces the &e# ser%er in what is referred to as a 0MP ?demilitariGed GoneA) which is designed to "re%ent direct communication #etween the 3nternet and an internal networ'. This "rotects ser%ers on the internal networ' from attac'. IMPORTANT &hiche%er method $ou use to close unused "orts on $our &e# ser%er) it is im"erati%e that $ou #loc' traffic to an$ "orts that $our a""lications do not use. 7emem#er) howe%er) that the "orts that remain o"en are still a securit$ ris'. Effecti%e logging of ser%er acti%it$) fre(uent monitoring of logs) and "rom"t "atching of %ulnera#ilities in software o"erating on the o"en "orts are all im"ortant means of defending $our ser%er?sA from attac's. A full discussion of "ac'et filtering) routing) and 3PSec management is #e$ond the sco"e of this cha"ter. ,onsult the manual for $our firewall or router) or the &indows 2 E-P <el" files) for more information on im"lementing these solutions.
Patching
*nce $our ser%er is set u" correctl$ and securel$) and $ou+%e considered how the design of $our a""lication affects securit$) $ou might thin' $ou+re home free. Not soH E%en the most securel$ configured ser%er and securel$ designed a""lication can #e com"romised #$ a la1 attitude toward ongoing maintenance. *ne of the most im"ortant as"ects of ongoing maintenance of ser%ers and a""lications is sta$ing on to" of "atches released #$ %endors of an$ software $ou+re using. 3n an ideal world) the software we use would #e "erfect from the start. <owe%er) the realit$ is that there are few) if an$) "rograms that do not contain %ulnera#ilities. &hen these %ulnera#ilities are disco%ered) t$"icall$ the %endor of the "rogram will issue a "atch designed to correct the "ro#lem. 9nfortunatel$) man$ ser%er administrators do not a""l$ these "atches consistentl$) lea%ing their ser%ers %ulnera#le to attac'.
This is ine1cusa#le. Most "atches can #e a""lied easil$) and there are man$ wa$s that $ou can #e notified automaticall$ a#out new ones for Microsoft software) including the following sources of information a#out "atches=
The &indows 9"date site ?http://windowsupdate.microsoft.comEA lets $ou anal$Ge the u"dates a%aila#le for a gi%en s$stem and determine which of them are currentl$ installed. Microsoft &indows CD and later and &indows 2 and later install a lin' to &indows 9"date in the Start menu #$ default. The Microsoft Product Securit$ Notification ser%ice lets $ou sign u" for e/mail notification of %ulnera#ilities and a%aila#le "atches. This method is useful for administrators who need to 'ee" trac' of "atches without %isiting multi"le machines. You can sign u" for this ser%ice at http://www.microsoft.com/technet/tree%iew/default.aspS url5/technet/security/bulletin/notify.asp. The Microsoft Baseline Securit$ Anal$Ger ?MBSAA is a utilit$ that will scan the local machine) or machines on the local networ') for uninstalled "atches for Microsoft &indows NT 8. ) &indows 2 ) 33S 8. and 33S Q. ) Microsoft S:. Ser%er K. and Microsoft S:. Ser%er 2 ?and MS0EA) and Microsoft 3nternet E1"lorer Q. 2 and later) as well as chec'ing for numerous other "otential securit$ "ro#lems) such as wea' "asswords) installed sam"les for 33S) and securit$ issues related to 3nternet E1"lorer and Microsoft *ffice "roducts. MBSA 2.2 is downloada#le from http://www.microsoft.com/technet/security/tools/tools/mbsahome.asp.
2. ,lic' Scan A ,om"uter. The resulting interface) shown in the following illustration) allows $ou to select a com"uter to scan) as well as to s"ecif$ the t$"es of %ulnera#ilities to scan for.
!. .ea%e the settings as the$ are) and clic' Start Scan. &hen the scan is com"lete) MBSA will dis"la$ a re"ort of the %ulnera#ilities it has found) as shown in the following illustration. A green chec' mar' ne1t to an entr$ indicates that no "ro#lems were found for that issue. A $ellow - indicates a noncritical securit$ warning. These are issues that warrant further in%estigation #ut do not necessaril$ indicate a %ulnera#ilit$. A red - indicates a critical securit$ issue re(uiring action to correct an identified %ulnera#ilit$. The other two icons $ou might see are a #lue asteris') indicating recommended #est "ractices) and an i icon) indicating that additional information is a%aila#le for a gi%en issue. Also) each issue includes lin's indicating what was scanned) an$ additional details on the results) and) most im"ortant) instructions for how to correct a %ulnera#ilit$ found #$ the tool.
8. .ocate an entr$ with a $ellow or red - icon. Q. ,lic' <ow To ,orrect This and follow the instructions "ro%ided to correct the issue) including lin's to re(uired "atches) and so on. 6. 7e"eat Ste" Q for all warnings or critical issues. K. *nce $ou ha%e finished correcting issues ?re#ooting when necessar$A) start MBSA again) and rescan the machine to confirm that the issues ha%e #een corrected. NOTE Starting with MBSA 2.2) there is an issue with nonsecurit$/related "atches installed #$ the &indows 9"date functionalit$ #uilt into &indows -P) or from the &indows 9"date &e# site. Because the -M. file used #$ MBSA to identif$ the file %ersions to scan for does not include nonsecurit$/related "atches) $ou might run into a situation in which MBSA highlights a file whose %ersion is higher than e1"ected as a securit$ warning #ecause that file has #een u"dated #$ &indows 9"date. For this reason) 'ee" trac' of the "atches that are installed from &indows 9"date so that $ou 'now when the warning gi%en #$ MBSA is indicati%e of a "otential "ro#lem rather than of a nonsecurit$/related "atch.
Access ,ontrol
Access control is the "rocess of determining who can access resources on $our ser%er. This includes #oth authentication ?determining the identit$ of a user ma'ing a re(uestA and authoriGation ?determining whether that user has "ermission to ta'e the action re(uestedA. For an ASP.NET a""lication) there are se%eral different authentication and authoriGation methods. You+ll learn how to im"lement authentication and authoriGation in ASP.NET later in this cha"ter. 3t is im"ortant not to forget that access control also includes "h$sical access to the machine #eing secured. The #est authentication) authoriGation) and "assword "ractices won+t hel" $ou a #it if someone can gain "h$sical access to a machine and circum%ent $our securit$ #arriers) or sim"l$ damage the machine #e$ond re"air. An$ machine that has %alue to $ou should #e secured "h$sicall$) as well as %ia software) from unauthoriGed use.
2. Select the ser%er $ou want to manage) and e1"and the tree to find the site $ou want to manage. 7ight/clic' the desired site and select Pro"erties. The following dialog #o1 will #e dis"la$ed ?the illustration is from 33S 6. on &indows Ser%er 2 !A.
!. 3n the the &e# Site ta# of the :sitename; Pro"erties dialog #o1) ensure that the Ena#le .ogging chec' #o1 is chec'ed. 8. Modif$ the format of the logs #$ using the Acti%e log format dro"/down list You can clic' the Pro"erties #utton to modif$ where logs are 'e"t) how fre(uentl$ a new log file is created) and the s"ecific information that is logged. NOTE 3t is considered a good "ractice to modif$ the location of the &e# ser%er logs from their default of Z&in0irZNS$stem!2N.ogFiles #ecause that ma'es it more difficult for hac'ers who gain access to $our s$stem to co%er their trac's. 3f the log files are in their default location) hac'ers can more easil$ alter them or delete them to hide their acti%it$. Ma'e sure to set a""ro"riate A,.s on the log file location since it might still #e "ossi#le for an attac'er to locate these files.
recreate them) including an$ data "assed from form fields on a su#mitted "age. 3f such a form contained sensiti%e data) such as "asswords or credit card num#ers) this data could #e stolen. Encr$"tion is an im"ortant tool for 'ee"ing this 'ind of information secure. The most commonl$ used form of encr$"tion in &e# a""lications is the Secure Soc'ets .a$er ?SS.A "rotocol. Sites re(uiring secure communications #etween the &e# ser%er and the #rowser use SS. to create and e1change a 'e$ used to encr$"t communications #etween the client and ser%er) there#$ hel"ing to "rotect this information from "r$ing e$es. This is t$"icall$ done #$ e/commerce sites to "rotect credit card information) for e1am"le. SS. can also #e useful for "rotecting other information) including Session30 coo'ies and login information when using #asic authentication) or ASP.NET Forms/#ased authentication. ?See 4Ena#ling Authentication5 for more information on #asic authentication.A B$ default) SS. communications occur on "ort 88! ?as o""osed to non/SS. &e# communications) which are on "ort D #$ defaultA) using the https:// "refi1 for 97.s that use SS.. Ena#ling SS. for $our &e# ser%er re(uires o#taining a ser%er certificate and #inding that certificate to the &e# sites on which $ou want to use SS.. ,ertificates are issued #$ se%eral com"anies) including VeriSign ?http://www.%erisign.com/products/site/inde$.htmlA) that are "resumed to #e trustworth$.
8. 9se the &e# Ser%er ,ertificate &iGard to create a new certificate re(uest. This method is useful if $ou want to create a certificate re(uest to send to a third/"art$ certificate authorit$) such as VeriSign or Thawte) who will %erif$ the information in the re(uest and send $ou a ser%er certificate. Alternati%el$) if $ou ha%e ,ertificate Ser%ices installed on a machine on $our networ') $ou can use that ser%ice to create a certificate. ?Note that $our clients must ha%e $our ,ertificate Ser%ices ,A listed in their #rowser as a trusted certificate authorit$ in order to use this method.A See the ,ertificate Ser%ices documentation for more information on creating and installing $our own certificates. NOTE No matter which method $ou use to generate a certificate re(uest) the common name of the certificate ?identified #$ the ,ertificate Ser%ices &e# re(uest "ages as NameA must match the full$ (ualified domain name of the site the certificate will #e installed on. *therwise) users will get a warning that the ser%er+s certificate is %alid #ut the name on the certificate doesn+t match the re(uested 97.. *nce $ou+%e recei%ed the res"onse from the certificate authorit$ containing $our certificate) follow these ste"s to install the certificate for use in 33S.
2. .ocate the certificate file $ou recei%ed from the certificate authorit$. 7ight/clic' the file and select 3nstall ,ertificate. 2. *"en 3nternet 3nformation Ser%ices ?or 3nternet Ser%ices Manager on &indows 2 A. ?3f $ou are not logged in as an administrator) $ou will need to use the 7un As feature of &indows 2 or &indows -P to run the 3nternet Ser%ices Manager using an administrati%e account.A !. 7ight/clic' the site $ou want to "rotect %ia SS. and select Pro"erties. 8. *n the 0irector$ Securit$ ta#) clic' the Ser%er ,ertificate #utton. This will again start the &e# Ser%er ,ertificate &iGard. Q. ,lic' Ne1t to ad%ance to the second "age of the wiGard. 6. *n the Ser%er ,ertificate "age of the wiGard) shown in the following illustration ?33S 6. %ersion shownA) select Assign An E1isting ,ertificate and then clic' Ne1t.
K. The A%aila#le ,ertificates "age should list all of the certificates on the current machine) including the certificate $ou ;ust installed. Select the desired certificate and then clic' Ne1t. D. 7e%iew the ,ertificate Summar$ information to ensure $ou are assigning the correct certificate. Then clic' Ne1t. C. ,lic' Finish to com"lete the wiGard.
*nce $ou+%e installed the certificate for a gi%en site) $ou can use SS. to encr$"t communications on an$ of the %irtual directories under that site #$ ha%ing users re(uest "ages with https:// rather than http://. To ensure that "ages cannot #e %iewed without SS.) howe%er) $ou must re(uire SS. for the "age or director$ $ou want to "rotect.
7e(uire SS.
2. *"en 3nternet 3nformation Ser%ices ?or 3nternet Ser%ices Manager if $ou are using &indows 2 A. ?3f $ou are not logged in as an administrator) $ou will need to use the 7un As feature of &indows 2 or &indows -P to run the 3nternet Ser%ices Manager using an administrati%e account.A 2. 7ight/clic' the site) %irtual director$) or file $ou want to "rotect and then select Pro"erties. !. *n the 0irector$ Securit$ or File Securit$ ta#) in the Secure ,ommunications section) clic' the Edit #utton) which should now #e a%aila#le. This will o"en the Secure ,ommunications dialog #o1) shown in the following illustration.
8. 3n the Secure ,ommunications dialog #o1) chec' the 7e(uire Secure ,hannel ?SS.A chec' #o1. You could chec' the 7e(uire 22D/#it Encr$"tion chec' #o1 for greater securit$) #ut this re(uires that the client #rowser su""ort 22D/#it encr$"tion. Q. ,lic' *> to close the Secure ,ommunications dialog #o1) and then clic' *> again to close the Pro"erties dialog #o1 for the site) director$) or file $ou are "rotecting. The resource should now #e accessi#le onl$ #$ using https://.
IMPORTANT 9sing SS. encr$"tion is an im"ortant tool for "rotecting information sent from the #rowser to the ser%er) #ut it is onl$ one of man$ tools $ou need to use to secure $our a""lication. SS. alone is not enough. 3f the onl$ securit$ tool $ou use is SS.) $our site is almost guaranteed to #e %ulnera#le in some other area.
Ena#ling Authenticati n
As discussed earlier in this cha"ter) authentication is the "rocess of %alidating the identit$ of the user ma'ing the current re(uest. ASP.NET a""lications wor' with 33S to carr$ out authentication #ased on one of se%eral authentication t$"es) which are discussed in the following section. Authentication and authoriGation in ASP.NET wor' hand/in/hand and o"erate on two distinct le%els= the o"erating s$stemE33S le%el and the ASP.NET le%el. <ere+s an o%er%iew of how 33S and ASP.NET interact= 2. A re(uest comes in to 33S for a resource associated with ASP.NET ?such as a &e# FormA. 2. 3f one of the 33S authentication methods is ena#led) 33S "erforms authentication) and adds the authentication information to the re(uest. !. 33S "asses the re(uest to the ASP.NET run time. From this "oint on) 33S "la$s no further role in the re(uest. 2. 8a. 3f &indows authentication is ena#led) authoriGation is "erformed on the re(uest using the authenticated identit$ "assed #$ 33S) and if the authoriGation ?t$"icall$ A,. authoriGationA succeeds) the re(uest is "rocessed. 8#. 3f Forms authentication is ena#led) ASP.NET chec's for the forms authentication coo'ie. 3f no coo'ie e1ists) the user is redirected to the configured login "age. *nce the user successfull$ logs in) an authentication coo'ie is set) and if the authoriGation ?t$"icall$ 97. authoriGationA succeeds) the user is redirected to the re(uested resource. 8c. 3f Pass"ort authentication is ena#led) ASP.NET chec's for a Pass"ort coo'ie) and if it does not e1ist) redirects the user to the Pass"ort login "age for the site. *nce the user successfull$ logs in) the Pass"ort coo'ie is set) and the user is redirected to the re(uested resource.
2.
!.
methods) how the$+re im"lemented) and wh$ $ou might choose one "articular method o%er another. NOTE The interaction #etween 33S and ASP.NET in terms of authentication and authoriGation might #e somewhat confusing if $ou+re ine1"erienced with these features. 9ntil $ou understand how the %arious o"tions wor') $ou should "ractice the techni(ues and "rocedures discussed in this section on a machine that is not e1"osed to the 3nternet or other "otential sources of com"romise. 7e(uests for resources in an ASP.NET a""lication go through two distinct le%els of authentication= the 33S le%el and the ASP.NET a""lication le%el. The t$"e of authentication $ou choose determines which of these le%els is used to determine whether the re(uest is "ro"erl$ authenticated. As mentioned earlier) authoriGation also occurs on two le%els) so it is im"ortant to choose the a""ro"riate authoriGation method for the authentication t$"e $ou+re using. The authentication t$"e is determined #$ the :authentication; element in the &e#.config file for an a""lication. You+ll see e1am"les of this element later in this section. The full s$nta1 of the :authentication; element is e1"lained in A""endi1 B.
Basic authentication This method is com"ati#le with most #rowsers) #ut the "assword is sent in clear te1t. 9se this onl$ if $ou can "rotect the communication with SS. encr$"tion.
0igest authentication This authentication method was introduced as a feature of <TTP 2.2) so it might not #e su""orted #$ all #rowsers. 3t sends a hashed %alue instead of a clear/te1t "assword) ma'ing it more secure than #asic authentication. This method re(uires a &indows 2 0omain ,ontroller. You ha%e to store a clear/te1t %ersion of the "assword on the 0omain ,ontroller used to %alidate the "assword) so the 0omain ,ontroller must #e secured from "h$sical and networ' intrusions. 3f no &indows 2 0omain ,ontroller is a%aila#le) this o"tion will #e una%aila#le) as seen in the Authentication Methods dialog #o1 shown later in this cha"ter.
3ntegrated &indows ?NT.MA authentication This method is a%aila#le onl$ with 3nternet E1"lorer. 3t+s the most secure method #ecause it ne%er sends the username or "assword o%er the networ'. 9se this method if $ou re(uire $our clients to use 3nternet E1"lorer to access $our a""lication. Note also that 3ntegrated &indows authentication will not wor' o%er an <TTP "ro1$ connection) which can ma'e it
im"ossi#le for clients on a cor"orate networ' using a "ro1$ to log in to an a""lication o%er the 3nternet. 3t also re(uires each "erson that logs in to $our site to ha%e an NT account either on the &e# ser%er or on a domain controller trusted #$ the &e# ser%er. 3f more than one authentication t$"e chec' #o1 is chec'ed) 0igest and 3ntegrated &indows authentication will alwa$s ta'e "recedence o%er #asic authentication. *nce 33S has authenticated the user) it "asses the authenticated identit$ to ASP.NET) which can then use that information to allow or den$ access to resources within the a""lication. See 4AuthoriGing 9sers and 7oles5 for more information on this t$"e of authoriGation.
Q. ,lic' *> to close the Authentication Methods dialog #o1) and then clic' *> to close the Pro"erties dialog #o1 for the resource $ou selected in Ste" 2.
8. 3f desired) $ou can ha%e ASP.NET im"ersonate the logged/in user ?so that resource re(uests are made in the securit$ conte1t of the logged/in userA #$ adding the :identity; element as follows. ?See 49sing 3m"ersonation5 for more on im"ersonation.A
?i!entit' i&*e"sonate="t"ue"A
Q. Sa%e the &e#.config file. *nce $ou ha%e set the authentication mode to &indows) $ou need to set the authoriGation method to "rotect the desired resources.
!. 3f desired) $ou can set u" an internal redirect 97. for Pass"ort authentication #$ adding a :passport; child element as follows. This will redirect users who ha%e not authenticated to the s"ecified internal 97. rather than the default Pass"ort login site.
4. ?aut+entication &o!e="/ass*o"t"A 8. ?*ass*o"t "e!i"ect="l="<URL>"A ?Baut+enticationA
6. Sa%e the &e#.config file. NOTE To download and install the Pass"ort S0> and use Pass"ort authentication on $our site) $ou will need to register on http://msdn.microsoft.com/library/default.aspS url5/downloads/list/websr%pass.asp and "a$ a license fee. TIP 3n 33S 6. ) $ou can configure an a""lication to use .NET Pass"ort authentication using the 33S Manager a""let) as descri#ed earlier in this cha"ter in the ste"s showing how to change the authentication method used #$ 33S. See the 4.NET Pass"ort Authentication5 to"ic in the 33S 6. documentation for more information on configuring .NET Pass"ort authentication for 33S 6. .
"age to loo' for an authentication coo'ie) and then redirect to a login "age if the coo'ie didn+t e1ist. ASP.NET Forms/#ased authentication ta'es care of all this for $ou. All $ou need to do is create the login "age) tell ASP.NET where to find it ?%ia settings in &e#.configA) and set the desired authoriGation restrictions. 3n $our login "age) $ou can %erif$ the username and "assword credentials entered #$ the user against a data#ase) &indows 2 Acti%e 0irector$) or another credential store of $our choice) such as an -M. file. *nce $ou+%e %erified the user+s credentials) $ou can use the methods e1"osed #$ the 1orms/uthentication class to set or remo%e an authentication coo'ie) redirect the user to the original "age the$ re(uested) or renew the authentication coo'ie. IMPORTANT 3n Forms/#ased authentication) the username and "assword are sent as clear te1t. To ensure the securit$ of this information) $ou should alwa$s use an SS./ena#led connection for $our login "age. .et+s ta'e a loo' at an e1am"le. &e+ll create two "agesBa login "age and a "age to dis"la$ the username of the currentl$ logged/in userBand we+ll add the necessar$ elements and attri#utes to &e#.config) including authentication credentials against which we+ll authenticate re(uests.
8. Ma'e the following changes to the "ro"erties of the s"ecified controls= Co"trol roperty Value <abel> <abel( <abelA 2utton> Te1t Te1t Te1t Te1t Userna%e, Passw rd, Persist ' 9ie@ : gin
Te$t2o$( Te1tMode Passw rd <abelB Te1t R#lan'S Q. The result should loo' similar to the following illustration.
6.
K. 0ou#le/clic' the Button control in the designer. This will o"en u" the code/#ehind module for the "age and add the 2utton0=lick e%ent handler. D. Add the 3m"orts line to the to" of the code/#ehind module) #efore the class declaration for the .ogin class) as shown here.
G. (&*o"ts .'ste&.4eb..ecu"it' 1H. /ublic -lass Lo)in 'class co!e
This will allow $ou to use the methods of the 1orms/uthentication class without e1"licitl$ naming the System. eb.Security names"ace each time. 22. Add the following code to the 2utton0=lick e%ent handler. ?The com"leted code/#ehind module should loo' similar to the illustration that follows the code.A
1$. (# Fo"&s0ut+entication.0ut+enticate2TextBox1.Text, TextBox$.Text3 T+en 13. Fo"&s0ut+entication.6e!i"ectF"o&Lo)in/a)e2TextBox1.Text, <
4. 8. :. E. F. G.
?#o"&s na&e="#o"&saut+" lo)in="l="lo)in.as*x" *"otection="0ll" ti&eout=":H"A ?c"e!entialsA ?use" na&e="<username>" *ass1o"!="<password>"BA ?Bc"e!entialsA ?B#o"&sA
NOTE 3n addition to the attri#utes shown in the "receding e1am"le) the :forms; configuration element e1"oses se%eral other attri#utes) including two new attri#utes introduced in ASP.NET %ersion 2.2) re4uireSS< and slidingE$piration. The re4uireSS< attri#ute s"ecifies whether a secure connection is re(uired to "rotect data stored in the authentication coo'ie. 3f set to true) com"liant #rowsers will return the coo'ie onl$ if the re(uest is made o%er an SS. connection. The slidingE$piration attri#ute s"ecifies whether the timeout %alue for the authentication coo'ie is reset with each re(uest in a gi%en #rowser session. The default is false) which s"ecifies that the coo'ie will e1"ire after the inter%al s"ecified #$ the timeout attri#ute. You can find out more a#out the attri#utes a%aila#le in the :forms; element in A""endi1 B. B$ default) $ou will need to 'now the "assword in order to use an$ "age on the site #ecause of the wa$ it is secured. To a%oid this and allow $ou to use the hash"wd.as"1 "age) add the following section to the &e#.,onfig file ;ust #elow the closing :system.web; tag=
?location *at+="+as+*1!.as*x"A ?s'ste&.1ebA ?aut+o"iDationA ?allo1 use"s="P" BA ?Baut+o"iDationA ?Bs'ste&.1ebA ?BlocationA
This section allows the hash"wd.as"1 file to #e accessed #$ e%en unauthenticated users. The :location; tag is descri#ed more full$ in 4AuthoriGing 9sers and 7oles5.
2!. Sa%e &e#.config. The a""lication is now configured to use Forms authentication and to refuse all re(uests from anon$mous users.
!. ,hange the Te1t "ro"ert$ of the Button control to : g ut. 8. 0ou#le/clic' the Button control in the designer. This will o"en u" the code/#ehind module for the "age and add the 2utton0=lick e%ent handler. Q. Add the 3m"orts line to the to" of the code/#ehind module) #efore the class declaration for the .ogin class. This will allow $ou to use the methods of the 1orms/uthentication class without e1"licitl$ naming the System. eb.Security names"ace each time.
:. (&*o"ts .'ste&.4eb..ecu"it'
D. Add the following code to the 2utton0=lick handler. The call to the Signout method of the 1orms/uthentication hel"er class remo%es the forms authentication coo'ie) while the .esponse..edirect call ensures that the user is redirected to the login "age.
G. Fo"&s0ut+entication..i)nout23 6es*onse.6e!i"ect2".+o1=se"na&e.as*x"3
2 . 7e"lace the comment in the Page0<oad e%ent handler with the following code=
Label1.Text = "=se"na&e isJ " & =se".(!entit'.Na&e
22. Sa%e the "age and code/#ehind module. The com"leted code/#ehind module should loo' similar to the following illustration.
!. Enter the username and "assword ?unhashedA that $ou configured in &e#.config and then clic' .ogin. 3f $ou choose to chec' the Persist ,oo'ieU chec' #o1) the forms authentication coo'ie will #e a "ersistent) rather than session) coo'ie. Persistent coo'ies are coo'ies that will remain on the machine and will #e there e%en after the #rowser session closes out. B$ "ersisting the authentication coo'ie) the user won+t need to login the ne1t time the$ access the "age ?su#;ect to the timeout limitations set in &e#.configA. Assuming the credentials $ou enter match those in &e#.config) $ou will #e redirected to Show9sername.as"1) as shown in the following illustration. *therwise) an error message will #e dis"la$ed.
8. ,lic' the .ogout #utton. You will #e redirected to the login "age.
TIP For the sa'e of sim"licit$) we left the 30 "ro"erties of the controls in the "receding e1am"le at their defaults ?.a#el2) Button2) and so onA. 3n a real a""lication) it+s #est to gi%e controls more meaningful names) such as PasswordBo1) .oginButton and so on. The MS0N documentation "ro%ides hel"ful guidelines for structuring $our code and naming o#;ects and %aria#les. You can find these guidelines #$ entering the words c ding c n&enti ns in the 3nde1 "ane of the MS0N documentation window. NOTE 3n this e1am"le &e#.config file) the 97. for the login "age is s"ecified with the login!rl attri#ute of the :forms; element. ?For more information on all of the attri#utes of the :forms; element) see A""endi1 B.A <owe%er) if $ou lea%e this attri#ute out) ASP.NET su""lies the name login.asp$ ?which ha""ens to #e the same as in the e1am"leA as the default. ASP.NET also su""lies a default %alue of default.as"1 for the redirect "age when FormsAuthentication.7edirectFrom.oginPage is called with no 7edirect9rl (uer$ string argument. So in the "receding e1am"le) if $ou call the login "age directl$ and authenticate successfull$) ASP.NET will attem"t to redirect $ou to default.as"1. 3f there+s no such "age) $ou+ll get a 4file not found5 error.
!. 9sing &indows E1"lorer) right/clic' a file or folder in $our a""lication+s "h$sical director$ that $ou want to restrict access to) and then select Pro"erties. ?You must #e logged in as either an administrator or an account with ownershi" rights on the resource to #e configured.A 8. ,lic' the Securit$ ta# and add or remo%e users or grou"s as desired. Note that $ou should remo%e the E%er$one grou" if it is "resent. 3f $ou want ASP.NET to #e a#le to access a resource when not im"ersonating) the ASPNET account should #e gi%en access to the resource. &hen $ou+re finished a""l$ing "ermissions) clic' *> to close the dialog #o1. Q. Browse to the "rotected resource. You should #e "rom"ted to log in using $our &indows username and "assword. 3f $ou enter credentials for one of the accounts $ou configured in Ste" !) $ou should #e a#le to access the resource.
?Bcon#i)u"ationA
&hen the :authori3ation; element shown here is added to the &e#.config for an a""lication) it allows Andrew to access resources in the a""lication+s root director$ and in an$ su#directories that do not ha%e conflicting :authori3ation; "ermissions set) as well as den$ing access to all other users. The users attri#ute of the :allow; and :deny; elements allows $ou to s"ecif$ comma/se"arated lists of users to #e allowed or denied access to the 97. #eing "rotected. ?Note that if no "ath is s"ecified) ASP.NET will a""l$ the settings to the director$ in which the &e#.config containing the settings resides) as well as its children.A ASP.NET "ro%ides the following two wildcards for allowing and den$ing access=
V This wildcard lets $ou allow or den$ all users. U This wildcard lets $ou allow or den$ anon$mous users.
You can also s"ecif$ a comma/se"arated list of roles ?e(ui%alent to NT grou"sA to allow or den$ #$ adding the roles attri#ute to an :allow; or :deny; element=
?allo1 "oles="0!&inist"ato"s, =se"s"A
Note that authoriGation settings for child directories o%erride those of the "arent) unless the "arent settings are loc'ed down using the o"tional allow+%erride attri#ute of the :location; element. To "re%ent the "receding authentication settings from #eing o%erridden) $ou would modif$ the &e#.config file as follows=
?con#i)u"ationA ?location allo19,e""i!e="#alse"A ?s'ste&.1ebA ?aut+o"iDationA ?allo1 use"s="0n!"e1" BA ?!en' use"s="U" BA ?Baut+o"iDationA ?Bs'ste&.1ebA ?BlocationA ?Bcon#i)u"ationA
Note that the :location; element also has a path attri#ute that allows $ou to s"ecif$ the "ath to which the settings contained #etween the :location; tags a""l$. This can #e a %er$ con%enient wa$ to s"ecif$ the authoriGation settings for multi"le files or directories in an a""lication from a single &e#.config file) allowing the de%elo"er or administrator to decide which settings can or cannot #e o%erridden #$ child &e#.config files. This is an es"eciall$ useful feature in shared
ser%er or shared hosting situations. A ser%er administrator can "lace master "ermissions in the Machine.config file for the ser%er and use the :location; element to "re%ent o%erriding of these "ermissions.
.imiting the re(uest t$"es to those necessar$ for a "age or "ages in $our a""lication can #e an im"ortant wa$ to "re%ent hac'ers from com"romising $our site. 3f a hac'er is una#le to ma'e a P+ST re(uest) it is that much more difficult for him to ta'e ad%antage of a %ulnera#ilit$ that re(uires sending data in an <TTP P+ST re(uest. You can restrict or allow <TTP %er# access for a "age or set of "ages #$ adding the path attri#ute to the :location; element) as descri#ed in the "re%ious section. The Forms authentication e1am"le demonstrates the use of the path attri#ute of the :location; element.
conte1t of the 39S7OMA,<3NENAME #uilt/in account. 3n ASP.NET) im"ersonation must #e turned on e1"licitl$ #$ using the impersonation attri#ute of the :identity; element. &ithout im"ersonation) ASP.NET runs as the #uilt/in ASPNET account. ?You can use the :process9odel; configuration section to configure ASP.NET to run as a different account that has more "ri%ileges) such as the SYSTEM #uilt/in account) #ut this carries some increased securit$ ris's #ecause of the higher "ri%ilege le%el of the SYSTEM account.A NOTE As mentioned earlier in this cha"ter) 33S 6. ) when running in nati%e mode) ignores the :process9odel; configuration element in fa%or of its own "rocess model settings. The default identit$ for ASP.NET a""lications running under 33S 6. is Networ' Ser%ice. For e1am"le) $ou might want to ta'e ad%antage of im"ersonation to use trusted connections with S:. Ser%er. Trusted connections use &indows securit$ to connect to a S:. Ser%er data#ase without the need for a S:. Ser%er username and "assword. As discussed earlier in this cha"ter) one of the challenges facing ASP.NET de%elo"ers is where to store data#ase login information to reduce the ris' of it #eing com"romised. &ith trusted connections) this is not a "ro#lem #ecause the login information is ne%er stored #$ the a""lication.
!. Add the desired &indows accounts to the S:. Ser%er securit$ data#ase. 8. 3n the connection string used to connect to the data#ase) s"ecif$ Trusted0=onnection5yes. The full connection string would loo' similar to the following=
"se",e"=2local3QV.!otN TO!atabase=*ubsOT"uste!<-onnection='es"
Q. 9sing one of the accounts that $ou added to the S:. Ser%er securit$ data#ase) log in to the ASP.NET a""lication. You should #e a#le to access the data on the S:. Ser%er data#ase. NOTE 3f $ou cannot use &indows authentication in $our ASP.NET a""lication) $ou might still #e a#le to ta'e ad%antage of trusted connections #$ configuring the default ASPNET ?or Networ' Ser%ice) in 33S 6. A account ?used to run the ASP.NET wor'er "rocessesA as a S:. Ser%er login account. >ee" in mind) though) that this will allow an$one who can access an$ ASP.NET a""lication to access the data#ase according to the S:. Ser%er "ermissions $ou ha%e set u" for the ASPNET account. The "rocess of setting u" the ASPNET account as a S:. Ser%er login is descri#ed in ,ha"ter C.
http://www.microsoft.com/technet/security This is the starting "oint for finding securit$/related information for &indows) 33S) and other Microsoft "roducts. You+ll find a host of good information on im"ro%ing the securit$ of $our ser%ers and a""lications here.
http://www.microsoft.com/technet/security/iis)chk.asp This is the Secure 3nternet 3nformation Ser%ices Q ,hec'list. Pre"ared #$ Michael <oward of the &indows 2 and 33S securit$ teams) this document "ro%ides recommendations and #est "ractices for securing 33S Q. .
http://www.microsoft.com/technet/itsolutions/security/tools/tools.asp This is a list of securit$ tools a%aila#le through the Microsoft Technet &e# site.
http://nsa(.www.con$ion.com/win(k/download.htm
This is the download site for the &indows 2 Securit$ 7ecommendation @uides "re"ared #$ the National Securit$ Agenc$ ?NSAA.
http://www.microsoft.com/technet/columns/security/>Qimlaws.asp This is the 2 3mmuta#le .aws of Securit$) a list of the man$ wa$s to lose control of $our com"uter.
http://www.microsoft.com/technet/columns/security/>Qsalaws.asp This is the 2 3mmuta#le .aws of Securit$ Administration) a list of sage ad%ice for those who ha%e the du#ious "leasure of #eing res"onsi#le for securing their s$stems.
http://www.cert.org/ad%isories/=/C(QQQCQ(.html This ad%isor$ "ro%ides a detailed descri"tion of cross/site scri"ting ?-SSA and the "ro#lems it can cause.
,hange the #lan' sa "assword of a default install of MS0E Ena#le logging for a &e# site
Ena#le SS.
Do this follow the "rocedures recommended #$ the certification authorit$ of $our choiceA. *nce $ou ha%e recei%ed and installed $our certificate) o"en the 3nternet Ser%ices Manager) na%igate to the site to #e configured for SS.) and access the Pro"erties dialog #o1 for the site. *n the 0irector$ Securit$ ta#) clic' the Ser%er ,ertificate #utton and use the Assign An E1isting ,ertificate o"tion in the &e# Ser%er ,ertificate &iGard to assign the newl$ installed certificate to the site. You can re(uire SS. communications #$ using the Edit #utton on the 0irector$ Securit$ ta#.
Ena#le ASP.NET to use Set the mode attri#ute of the :authentication; element in &e#.config to &indows authentication indows. Ena#le ASP.NET to use Set the mode attri#ute of the :authentication; element in &e#.config to Pass"ort authentication Passport. 3nstall the Pass"ort S0> and follow the instructions to configure. You must also ac(uire a license to use Pass"ort authentication. Ena#le ASP.NET to use Set the mode attri#ute of the :authentication; element in &e#.config to Forms authentication 1orms. Add the :forms; element with the desired attri#utes) such as login!.< and timeout. .oc' down authoriGation settings &ra" the :authentication; tags in a :location; element "air with the allow+%erride attri#ute set to false.
,reate &e# Forms "ages. ,reate and use user controls. <andle "age and control e%ents.
3n "re%ious cha"ters) $ou+%e seen e1am"les of #oth %er$ sim"le and more com"licated ASP.NET "ages. The sim"lest ASP.NET "age consists of "lain <TM. and is named with the .as"1 e1tension. &hile that+s "erfectl$ %alid) it+s also missing a lot of the elements that ma'e &e# Forms so useful. &e# Forms go #e$ond what classic ASP "ages offered) adding new directi%es) new reusa#ilit$ o"tions in the form of user controls and ser%er controls) and a new ser%er/side data/#inding s$nta1. This section will e1"lore how a "age is "ut together and how $ou can use these new features in $our &e# Forms.
Hello.i&*le.as*x
?I55 xa&*le o# t+e M /a)e !i"ecti,e 55IA ?IM /a)e Lan)ua)e=",b" -lassNa&e="Hello" IA ?+t&lA ?+ea!A ?sc"i*t "unat="se",e""A 't+is is a sc"i*t co!e !ecla"ation blocC
/"i,ate <na&e 0s .t"in) = "0n!"e1" /ublic /"o*e"t' Na&e 0s .t"in) ;et 6etu"n <na&e n! ;et .et <na&e = Value n! .et n! /"o*e"t' .ub .a'Hello23 Label1.Text = "Hello, " & <na&e & "!" n! .ub .ub /a)e<Loa!2.en!e" 0s 9bLect, (# (s/ostBacC T+en (# Na&eTextBox.Text ?A "" T+en Na&e = Na&eTextBox.Text n! (# .a'Hello n! (# n! .ub ?Bsc"i*tA ?B+ea!A ?bo!'A ?!55 t+is is a se",e" si!e #o"& 55A ?#o"& "unat="se",e""A ?!55 a .e",e" -ont"ol 55A ?as*JLabel i!="Na&eLabel" "unat="se",e""ANa&eJ ?Bas*JLabelA ?!55 a .e",e" -ont"ol 55A ?as*Jtextbox i!="Na&eTextBox" "unat="se",e""BA 0s ,ent0")s3
?!55 a .e",e" -ont"ol 55A ?as*Jbutton i!="Na&eButton" text=".ub&it" "unat="se",e""BA ?B#o"&A ?!55 a .e",e" -ont"ol 55A ?as*JLabel i!=Label1 "unat="se",e""BA ?Bbo!'A ?B+t&lA
The following sections descri#e the elements used in <elloSim"le.as"1) as well as other elements that $ou can use in a &e# Form "age.
Ser%er/side code
E%ent handlers E%ent handlers are "rocedures in :script; code declaration #loc's that handle "age or ser%er control e%ents) such as Page0<oad or control =lick e%ents. Most ASP.NET code should #e written in or called from e%ent handlers) rather than #eing written in render #loc's. :script; code These #loc's are used to contain "age/le%el "rocedures and to declare %aria#les
Ta#le B34. /SP.NET Page Elements Ele#e"t declaration #loc's Descriptio" that are glo#al to the "age. E1ecuta#le code) other than glo#al %aria#le declarations in code declaration #loc's) must #e contained within a "rocedure declaration. Ser%er/side code declaration #loc's must ha%e the runat56ser%er7 attri#ute) as shown in <elloSim"le.as"1.
:8 8; render These #loc's are used to contain e1ecuta#le code not contained within #loc's "rocedures. *%eruse of render #loc's can result in code that is difficult to read and maintain. ,lient/side :script; #loc's Ser%er/side comments 9ser controls These #loc's are used to contain scri"t code to #e e1ecuted on the client) usuall$ in res"onse to a client/side e%ent. ,hoice of language ?set #$ the language attri#uteA is dictated #$ the languages su""orted #$ the target #rowser. Fa%aScri"t is the most common choice for cross/#rowser com"ati#ilit$ in client scri"ts. S$nta1= :8CC CC8;. Ser%er/side comments allow descri"ti%e te1t to #e added to a "age. 9nli'e <TM. comments) this te1t is not sent to the client. These are custom controls that are defined declarati%el$ in files with the .asc1 e1tension. The$ "ro%ide a sim"le and straightforward mechanism for reuse of 93 and 93/related code) and can contain most of the same elements as &e# Forms "ages.
ASP.NET This set of #uilt/in controls "ro%ides ASP.NET de%elo"ers with a "rogramming ser%er controls model that mimics that of Microsoft Visual Basic. ,ontrols are added to a "age) and "rogrammers write code to handle e%ents raised #$ users\ interaction with the controls at runtime. ASP.NET "ro%ides two sets of #uilt/in controls= the <TM. controls) which "ro%ide a 2/to/2 ma""ing of ser%er/side controls for most <TM. elementsI and the &e# controls) which "ro%ide a set of controls that are %er$ similar to the Visual Basic 93 controls. Note that some ser%er controls) such as the Te$t2o$ and 2utton controls) must #e "laced within a ser%er/side :form;) or an e1ce"tion will #e raised. ,ustom ser%er ,ustom ser%er controls are another mechanism for reuse in ASP.NET. The$\re controls defined in class files ?.cs or .%# filesA and are "recom"iled into managed assem#lies #efore use.
and then the .as"1 file inherits from the code/#ehind class %ia the "nherits attri#ute of the @ Page directi%eA. The following illustration shows the relationshi" #etween the "age) its code/ #ehind class ?if an$A) and the com"iled assem#l$. *nce com"iled) the class is e1ecuted) the resulting <TM. is rendered to the #rowser) and the class is remo%ed from memor$.
Each ASP.NET &e# Forms "age contains a ser%er/side :form; tag that directs the "age to "ost #ac' to itself when the form is su#mitted #$ the user. Man$ ASP.NET ser%er controls also render Fa%aScri"t to the client) allowing actions such as selecting an item in a dro"/down list to cause a "ost#ac'. The ASP.NET runtime also renders a hidden form field to the "age that allows the "age to maintain its state #etween re(uests. The "ost#ac' and the hidden field are 'e$) #ecause when the client is interacting with the "age) no code is running on the ser%er at all. The "ost#ac' and the hidden field allow the "age to #e reconstituted on the ser%er. Also) the$ allow code to #e e1ecuted in res"onse to the e%ent raised #$ the user action) and #ased on an$ changes to the form fields. *nce the "age has #een "rocessed and the out"ut rendered to the #rowser) the "age and its controls are again discarded. The ste"s in this "rocess are as follows= 2. The user re(uests the "age from the #rowser. 2. The "age and controls are loaded and initialiGed at the ser%er. !. 3f the "age re(uest is the result of a "ost#ac') the control state is loaded from the %iewstate ?hidden form fieldA) and an$ changes su#mitted #$ the user are a""lied. ?Note that #oth the original %alues in the %iewstate and the u"dated %alues are a%aila#le to ser%er/side code.A 8. Page e%ent handlers and e%ent handlers for e%ents triggered #$ user actions are e1ecuted. Q. ,ontrol state is sa%ed to %iewstate ?hidden form fieldA.
6. <TM. out"ut from the "age is rendered to the #rowser. K. The "age and controls are unloaded on the ser%er. 3t\s im"ortant to note that while most ser%er controls sa%e their state to %iewstate automaticall$) the same is not true for "ro"erties that $ou define in $our "ages) or in user controls or custom ser%er controls. You\ll learn how to use %iewstate for storing custom control state in ,ha"ter 2 .
9sing 0irecti%es
3f $ou\%e de%elo"ed a classic ASP "age) $ou\%e wor'ed with directi%es. There were few directi%es in classic ASP) #ut the$ were im"ortant. Most "rominent were the @ <anguage directi%e and the U"nclude directi%e. The @ <anguage directi%e) which a""eared at the to" of e%er$ classic ASP "age) told the ASP runtime which language engine to use in inter"reting scri"t found in :8 8; render #loc's in the "age. The U"nclude directi%e told the ASP inter"reter to include a "articular file inline with the current ASP "age. 0irecti%es are sim"l$ wa$s for de%elo"ers to declarati%el$ determine how certain as"ects of a "rogram will o"erate. 3n classic ASP) this was somewhat limited. 3n fact) classic ASP had onl$ four ] directi%es) in addition to the @ <anguage directi%e=
@ =odepage 9sed in glo#aliGation to set the code "age for an ASP "age
@ Transaction 9sed to s"ecif$ whether and how the "age "artici"ates in ,*ML transactions
ASP.NET greatl$ e1"ands the use of directi%es) adding a num#er of useful directi%es for e%er$thing from controlling "age #eha%ior and configuration to caching "age out"ut. 3n addition) ] directi%es in ASP.NET ha%e attri#utes) there#$ increasing their "ower and fle1i#ilit$. The four classic ASP directi%es listed "re%iousl$ are re"resented in ASP.NET as attri#utes of the @ Page directi%e) which is descri#ed in the ne1t section.
@ Page
The @ Page directi%e) which is allowed in .as"1 files onl$) defines "age/s"ecific attri#utes used #$ ASP.NET language com"ilers and the runtime to determine how the "age will #eha%e. The default %alues for a few of these attri#utes are set in the Pages configuration section in machine.config. Some of the attri#utes) including /utoE%ent ireup) are set or o%erridden in "ages created #$ Microsoft Visual Studio .NET. The attri#utes a%aila#le for the @ Page directi%e are listed in Ta#le K/2. Ta#le B3*. @ Page /ttributes $ttri2ute /sp=ompat Value True/1alse urpose Pro%ides com"ati#ilit$ with ,*M com"onents created with Visual Basic 6. ?or earlierA #$ forcing the "age to #e run in an STA ?Single Threaded A"artmentA. Also "ro%ides the com"onent with access to unmanaged instances of the ASP intrinsics ?Session) /pplication) .e4uest) and so onA. This setting will li'el$ degrade "erformance) so use it onl$ when necessar$. 0efault is 1alse. 0etermines whether handlers for e%ents such as Page0<oad are set u" automaticall$. See 4E%ent <andling5 for more information. 0efault is True.
/utoE%ent ireup
2uffer
True/1alse 0efault is set 0etermines whether rendered out"ut is #uffered in the :pages; section of #efore #eing sent to the client or is sent as it is machine.config or rendered. 0efault is True. &e#.config. An$ %alid class name. 0etermines the name of the "age generated #$ d$namicall$ com"iling the "age. This attri#ute wor's with or without =odebehind) and with either the Src or =odebehind attri#utes. The default #eha%ior if this attri#ute is omitted is for the "age name to #e in the form filenameOas"1. 0etermines the target #rowser for which ser%er controls should render out"ut. The !ser /gent string should #e one recogniGed #$ the ser%er controls #eing used.
=lassName
=lientTarget
An$ %alid !ser/gent string. A%aila#le %alues are set in the :clientTarget; section of machine.config or &e#.config.
=odebehind
Filename of code/#ehind This attri#ute is used in Visual Studio .NET to class. locate codeCbehind classes to #e com"iled during a #uild o"eration. 3t is not used #$ the ASP.NET runtime.
Ta#le B3*. @ Page /ttributes $ttri2ute =odePage =ompiler+ptions Value An$ %alid code "age %alue. String containing %alid com"iler o"tions. urpose 9sed in glo#aliGation to set the code "age for a &e# Forms "age. Allows de%elo"ers to "ass com"iler o"tions for the "age to the com"iler. For Visual Basic .NET and ,J) this can #e an$ %alid se(uence of command/line switches for the com"iler. Sets the M3ME t$"e for the "age out"ut. This attri#ute is useful when returning #inar$ content ?such as imagesA to the client. 0etermines the culture setting for the "age.
=ontentType
An$ %alid M3ME t$"e ?such as 4te$t/html5 or 4application/%nd.msC e$cel5A. An$ %alid culture string ?such as enC!S for 9S EnglishA. True/1alse 0efault is set #$ the debug attri#ute of the :compilation; section of machine.config or &e#.config. An$ string.
=ulture
,ebug
0etermines whether "ages are com"iled with de#ug s$m#ols or without. This setting affects "erformance) so "roduction a""lications should ha%e this set to 1alse. The default is 1alse. Pro%ides a te1t descri"tion of the "age. This attri#ute is ignored #$ the ASP.NET runtime. 0etermines whether a re(uest to the "age will initiate a new session) and whether the "age can access or modif$ data stored in an e1isting session. 0efault is True. 0etermines whether %iewstate is ena#led for the "age. DiewState allows ser%er controls to sa%e their current state from re(uest to re(uest. 0efault is True. 0etermines whether ASP.NET runs a Machine Authentication ,hec' ?MA,A on the content of the hidden form field that is used to store %iewstate) to ensure that it has not #een altered on the client. 0efault is 1alse. S"ecifies a "age to which the client is redirected if there is an unhandled e1ce"tion in the "age.
,escription
EnableSessionState
True/1alse/.eadonly 0efault is set in the :pages; section of machine.config or &e#.config. True/1alse 0efault is set in the :pages; section of machine.config or &e#.config.
EnableDiewState
EnableDiewState9ac True/1alse 0efault is set in the :pages; section of machine.config or &e#.config. ErrorPage An$ %alid 97..
Ta#le B3*. @ Page /ttributes $ttri2ute E$plicit Value urpose True/1alse 0efault is set 0etermines whether code written in Visual in the :compilation; Basic is su#;ect to the +ption E$plicit rule when section of machine.config com"iled. 0efault is True. or &e#.config. An$ class deri%ed from the S"ecifies a codeCbehind class for the "age. An$ Page class. Format is code contained in the "age is com#ined with the 4namespacename. code in the codeCbehind class into a single classname5 or class. 4classname5. An$ %alid string for an S"ecifies the language com"iler to #e used to installed .NET language com"ile the "age. 0efault is %b. ?such as 4%b5E 4%isualbasic5) 4cU5E 4cs5E 4csharp5) and so onA 0efault is set in the :compilation; section of machine.config or &e#.config. An$ %alid locale identifier. 9sed to set the locale identifier for a "age. An$ %alid encoding string. 9sed in glo#aliGation to set the character 0efault is set in the encoding for the <TTP res"onse. 0efault is utfC :globali3ation; section of V. machine.config or &e#.config. True/1alse 0etermines whether SmartNa%igation) which uses 3Frame elements for clients running Microsoft 3nternet E1"lorer Q. or a#o%e to reduce the flash of na%igation when re"eatedl$ "osting #ac' to the same "age) among other enhancements) is ena#led or disa#led. 0efault is 1alse.
"nherits
<anguage
<=", .esponseEncoding
SmartNa%igation
Src Strict
Filename of codeCbehind S"ecifies the name of a codeCbehind class file to class #e com"iled d$namicall$ at runtime. True/1alse 0etermines whether code written in Visual Basic is su#;ect to the +ption Strict rule when com"iled. 0efault is 1alse.
Trace
True/1alse 0efault is set 0etermines whether the "age includes in the :trace; section of trace out"ut. 0efault is 1alse.
Ta#le B3*. @ Page /ttributes $ttri2ute Value machine.config or &e#.config. urpose Note= .ea%ing tracing ena#led on "roduction s$stems can cause #oth "erformance and securit$ issues. Ensure that tracing is disa#led #efore de"lo$ing an a""lication.
Trace9ode
Sort2yTime/ 0etermines how the trace out"ut is sorted when Sort2y=ategory 0efault is tracing is ena#led. 0efault is Sort2yTime. set in the :trace; section of machine.config or &e#.config. *ne of the following= ,isabled NotSupported Supported .e4uired .e4uiresNew An$ %alid 93 culture %alue. True/1alse 0etermines whether and how the "age will "artici"ate in ,*ML transactions. 0efault is ,isabled. S"ecifies the 93 culture setting for a &e# Forms "age. S"ecifies whether re(uest %alidation will #e "erformed on in"ut data such as (uer$string %alues) form fields) and so on. 3f True) and if an$ "otentiall$ dangerous content such as <TM. tags or scri"t is found) an e1ce"tion of t$"e Kttp.e4uestDalidationE$ception will #e thrown. The default is True. 3m"ortant= You should not disa#le this feature unless $ou are certain that $ou ha%e ade(uatel$ "ro%ided for filtering or %alidating that an$ in"ut that the "age acce"ts is safe for "rocessing or dis"la$. S"ecifies the warning le%el at which the com"iler should a#ort "age com"ilation. .ower num#ers allow com"ilation to continue through warnings of greater se%erit$. .e%els 2T8 a""l$ to ,J onl$.
Transaction
!"=ulture Dalidate.e4uest
arning<e%el
T8
@ Page E1am"les
3n this section) we\ll ta'e a loo' at a cou"le of e1am"les of using the @ Page directi%e. The first e1am"le will show how to ena#le de#ugging of ASP.NET "ages) and the second will show how to ena#le "age/le%el tracing.
B$ default) ASP.NET "ages created as a "art of a Visual Studio .NET &e# a""lication "ro;ect are com"iled with de#ug s$m#ols. This is good for de%elo"ment) since it offers much richer error information than was a%aila#le in classic ASP) as shown in the following illustration.
This functionalit$) howe%er) e1acts a "erformance "enalt$) so $ou should usuall$ turn this o"tion off when $ou de"lo$ $our a""lication. 0e#ug s$m#ols are ena#led in two s"ecific "laces in Visual Studio .NET= in &e#.config ?which ena#les de#ug s$m#ols for .as"1 "agesA and in the ,onfiguration Manager "ro"erties for the "ro;ectEsolution ?which ena#les de#ug s$m#ols for code/#ehind classes and other com"iled classes in the "ro;ectA. The following "rocedures descri#e how to turn off de#ug s$m#ols in #oth "laces.
Now if $ou encounter an unhandled error in code contained within the .as"1 "age) ASP.NET will "ro%ide $ou with an error "age without the s"ecific error information made "ossi#le #$ the use of de#ug s$m#ols) as shown in the following illustration.
IMPORTANT 0e#ugging carries some "erformance "enalt$) #ut) more im"ortant) if $ou do not configure the :customErrors; configuration element "ro"erl$) ena#ling de#ugging can result in information #eing dis"la$ed to the user that could "resent a securit$ ris'. You should alwa$s disa#le de#ugging in "roduction a""lications to minimiGe the amount of e1"loita#le information $our a""lication "ro%ides when an e1ce"tion occurs) as well as to im"ro%e "erformance.
2. To disa#le de#ug s$m#ols for a single "ro;ect) select that "ro;ect in the dialog #o1 and change the %alue in the ,onfiguration dro"/down list from 0e#ug to 7elease) as shown in the following illustration.
!. To disa#le de#ug s$m#ols for all "ro;ects) change the Acti%e Solution ,onfiguration from 0e#ug to 7elease) as shown in the following illustration.
8. ,lic' ,lose.
Ena#ling Tracing
B$ default) the trace functionalit$ is not ena#led for ASP.NET "ages. As with the debug attri#ute) disa#ling tracing in "roduction a""lications is good for "erformance) since there is o%erhead associated with tracing. 0isa#ling tracing in "roduction a""lications is also im"ortant for securit$ #ecause tracing "ro%ides a large amount of information a#out each re(uest) information that could "otentiall$ assist a malicious user in attac'ing $our site if tracing isn\t configured "ro"erl$. Tracing ena#les $ou to %iew information a#out the current re(uest) including the collections ?coo'ies) forms) headers) (uer$strings) and ser%er %aria#lesA associated with the re(uest.
Ena#le tracing
2. *"en the desired "age in Visual Studio .NET and switch to <TM. %iew. 2. Add the trace attri#ute to the @ Page directi%e) with a %alue of True.
?IM /a)e t"ace="t"ue" IA
!. Sa%e the file. &hen $ou re(uest the file from a #rowser) $ou\ll #e a#le to see the trace information a""ended to the "age out"ut) as shown in the illustration on the following "age.
For more information on tracing and its uses in de#ugging ASP.NET a""lications) see ,ha"ter 28. TIP 3n addition to manuall$ adding ?or modif$ingA the attri#utes of the @ Page directi%e) $ou can ena#le or disa#le these features on a "er/"age #asis #$ using the Pro"erties window in Visual Studio .NET to set the ,ebug or Trace "ro"erties of the ,+=!9ENT o#;ect.
@ =ontrol
The @ =ontrol directi%e) which is allowed in .asc1 files onl$) "erforms the same function as the @ Page directi%e. <owe%er) instead of setting attri#utes for "ages) it sets the attri#utes for user controls) which are reusa#le sni""ets of code named with the .asc1 file e1tension. The attri#utes e1"osed #$ the @ =ontrol directi%e are a su#set of the attri#utes e1"osed #$ the @ Page directi%e) and their "ur"ose and %alues are the same as in the ta#le of @ Page attri#utes ta#le #eginning. The following attri#utes are a%aila#le for the @ =ontrol directi%e=
=ompiler+ptions ,ebug ,escription EnableDiewState E$plicit "nherits <anguage Strict Src arning<e%el
@ "mport
The @ "mport directi%e is used to im"ort either a Microsoft .NET Framewor' names"ace or a custom names"ace into a "age. 3m"orting a names"ace allows $ou to write code against the mem#ers of that names"ace without e1"licitl$ s"ecif$ing the names"ace each time. The @ "mport directi%e has onl$ one attri#ute) Namespace) which s"ecifies the names"ace to im"ort. Each @ "mport directi%e can ha%e onl$ one Namespace attri#ute) so $ou must use a se"arate @ "mport directi%e for each names"ace $ou want to im"ort. For e1am"le) to use the .NET Framewor' Smtp9ail and 9ail9essage classes to send e/mail from an ASP.NET "age) $ou need to add the System. eb.9ail names"ace to $our "age) as follows=
?IM (&*o"t na&es*ace=".'ste&.4eb.7ail" IA
Then) to create an instance of the 9ail9essage class) $ou use the following=
%i& &'7ail 0s Ne1 7ail7essa)e
@ "mplements
The @ "mplements directi%e is used to im"lement a defined interface from within an ASP.NET "age. An interface "ro%ides an a#stract definition of a set of methods and "ro"erties. &hen $ou im"lement an interface) $ou commit to su""orting the methods and "ro"erties defined #$ the
interface) and $ou must create matching method and "ro"ert$ definitions in $our .as"1 file) using :script; #loc's. The @ "mplements directi%e can\t #e used to im"lement interfaces in a code/ #ehind file. 3t has one attri#ute) interface) which s"ecifies the interface #eing im"lemented.
@ .egister
The @ .egister directi%e is used with #oth user controls and custom ser%er controls to register them for use within a "age. The @ .egister directi%e\s attri#utes are listed in Ta#le K/!. Ta#le B32. @ .egister /ttributes $ttri2ute /ssembly Value An$ %alid assem#l$ name. The assem#l$ name should not contain a file e1tension. urpose S"ecifies the "recom"iled assem#l$ for a custom ser%er control. 9sed with the Namespace and TagPrefi$ attri#utes. The assem#l$ named needs to #e a%aila#le to the a""lication) either #$ #eing "laced in the #in su#director$ of the a""lication or #$ #eing installed into the glo#al assem#l$ cache. S"ecifies the names"ace to #e associated with the tag "refi1 s"ecified #$ the TagPrefi$ attri#ute.
An$ %alid "ath to a user S"ecifies the location of a user control associated with a control ?.asc1A file Acce"ts TagName/TagPrefi$ "air. either relati%e or a#solute 97.s. An$ string ?must #e %alid S"ecifies an alias for a user control to #e used in for -M.A. im"lementing the user control within the "age. Must #e used with the TagPrefi$ attri#ute. An$ string ?must #e %alid S"ecifies an alias for a tag "refi1 for a user control or for -M.A. custom ser%er control to #e used in im"lementing the control within the "age. 3f used without the TagName attri#ute) as with a custom ser%er control) the tag name is the same as the class name defined in the ser%er control assem#l$ s"ecified #$ the /ssembly and Namespace attri#utes.
TagName
TagPrefi$
For e1am"les of the use of the @ .egister directi%e) see 4,reating and 9sing 9ser ,ontrols5 and 49sing Ser%er ,ontrols5 in ,ha"ter D.
@ /ssembly
The @ /ssembly directi%e is used to lin' an assem#l$ into a "age at com"ilation time. This allows de%elo"ers to use all of the classes) methods) and so forth e1"osed #$ the assem#l$ as if
the$ were "art of the "age. The @ /ssembly directi%e\s attri#utes are listed in Ta#le K/8. *nl$ one of the Name and Src attri#utes of the @ /ssembly directi%e can #e used at a time. Ta#le B38. @ /ssembly /ttributes $ttri2ute Value Name Src An$ %alid assem#l$ name. An$ %alid "ath to a class source file ?.%#) .cs) and so onA. urpose S"ecifies the name of a com"iled assem#l$ to #e lin'ed to when the "age is com"iled. S"ecifies the "ath to a source file to #e d$namicall$ com"iled and lin'ed to the current "age.
Note that it is not necessar$ to use the @ /ssembly directi%e to lin' in assem#lies residing in the #in su#director$ of $our a""lication. These assem#lies are automaticall$ lin'ed in #$ default) #ased on the :assemblies; su#section of the :compilation; section of the machine.config configuration file) which contains the following tag=
?a!! asse&bl'="U"BA
This s"ecifies that ASP.NET should lin' in an$ assem#lies in the #in su#director$. Note also that an$ other assem#lies s"ecified #$ an :add; tag in the :assemblies; su#section do not re(uire lin'ing with the @ /ssembly directi%e.
@ +utput=ache
The @ +utput=ache directi%e is used to s"ecif$ that the rendered out"ut of the "age or user control in which it a""ears should #e cached. This directi%e also s"ecifies the attri#utes that determine the duration of caching) the location of the cached out"ut) and the attri#utes that determine when a client will recei%e freshl$ rendered content rather than the cached content. *ut"ut caching in user controls can #e es"eciall$ useful when some of the content in a "age is relati%el$ static) #ut other content is fre(uentl$ u"dated) ma'ing it a "oor candidate for caching. 3n a case li'e this) $ou could mo%e the static content into a user control and use the @ +utput=ache directi%e to cache its content) while lea%ing the rest of the "age to #e d$namicall$ generated with each re(uest. The @ +utput=ache directi%e\s attri#utes are listed in Ta#le K/Q. Ta#le B3>. @ +utput=ache /ttributes $ttri2ute ,uration <ocation Value Num#er of seconds. ?7e(uired.A urpose S"ecifies the time) in seconds) for the "age or control to #e cached.
*ne of the following= S"ecifies the location where cached out"ut should /ny =lient ,ownstream #e stored. ?This attri#ute is not su""orted for user None Ser%er controls.A
Ta#le B3>. @ +utput=ache /ttributes $ttri2ute Shared Value True/1alse urpose New in ASP.NET 2.2) this attri#ute s"ecifies whether a cached user control can #e shared across multi"le "ages. 3f set to True) a single cached co"$ of the user control is shared among multi"le "ages within the a""lication. 3f set to 1alse) a se"arate co"$ of the user control will #e cached for each "age that uses the control. The default is 1alse. This attri#ute is %alid for user controls onl$. S"ecifies a custom string #$ which to %ar$ the out"ut cache. 3f browser is used) out"ut caching will %ar$ #ased on the #rowser name and ma;or %ersion. 3f $ou want to %ar$ #$ <TTP re(uest data other than the re(uesting #rowser) $ou will need to o%erride the -etDary2y=ustomString method of the Kttp/pplication class in @lo#al.asa1 in order to im"lement $our custom string. S"ecifies one or more <TTP headers to #e used to %ar$ the out"ut cache. &hen a re(uest is recei%ed with a %alue for the s"ecified <TTP header?sA that does not match that of an$ of the cached "ages) a new %ersion of the "age will #e rendered and cached. This attri#ute cannot #e used with user controls.
Dary2yParam .ist of (uer$string 'e$s S"ecifies one or more names of either (uer$string 'e$s or form field names) "assed with a -ET re(uest) or form field names "assed se"arated #$ semicolons) with a P+ST re(uest to #e used to %ar$ the out"ut or one of the following= cache. &hen a re(uest is recei%ed with a %alue for one None of the s"ecified "arameters that does not match that of ? an$ of the cached "ages) a new %ersion of the "age will ?7e(uired in ASP.NET #e rendered and cached. 3f the %alue of this attri#ute is "ages and in user set to none) the out"ut cache will not %ar$ #ased on controls that don\t ha%e a -ET and P+ST "arameters. 3f the %alue is set to ?) the Dary2y=ontrol attri#ute out"ut cache will %ar$ #$ all -ET and P+ST s"ecified.A "arameters. ?7e(uired in a user control if $ou don\t s"ecif$ a Var$B$Param attri#ute.A Dary2y=ontrol .ist of "ro"erties e1"osed #$ a user control) se"arated #$ semicolons. S"ecifies one or more "ro"erties e1"osed #$ a user control to #e used to %ar$ the out"ut cache. &hen a re(uest is recei%ed with a %alue that does not match the s"ecified "ro"ert$ of an$ of the cached "ages) a new %ersion of the "age will #e rendered and cached. This attri#ute can #e used onl$ for out"ut caching with user controls) not with ASP.NET "ages.
!. Sa%e the file. &ith these %alues for the attri#utes) the out"ut of the "age will #e cached for 6 seconds. An$ -ET/P+ST re(uests with "arameters that do not match an e1isting cached %ersion of the "age will #e ser%ed a freshl$ rendered %ersion of the "age) which will then #e cached. For more information on out"ut caching and using the ASP.NET cache engine to store ar#itrar$ data) see ,ha"ter 22.
@ .eference
The @ .eference directi%e allows $ou to d$namicall$ load user controls #$ referencing the filename of the desired control and then using the Page.<oad=ontrol method to load the control at runtime. The @ .eference directi%e directs the ASP.NET runtime to com"ile and lin' the s"ecified control to the "age in which it is declared. You\ll see an e1am"le of using the @ .eference directi%e in the section on user controls later in this cha"ter.
ASP "ntrinsic o#;ects These o#;ects ?/pplication) Session) .e4uest) .esponse) Ser%er) and =onte$tA are im"lemented in ASP.NET as class instances) which are e1"osed as "ro"erties of the page o#;ect. For e1am"le) the Ser%er functionalit$ is "ro%ided #$ a class called KttpSer%er!tility. Because the instance of KttpSer%er!tility is e1"osed as the Ser%er
"ro"ert$ of the Page class) $ou can call its methods ?Ser%er.Transfer) for e1am"leA ;ust as $ou could in classic ASP.
=ontrols collection Pro%ides access to the collection of controls defined for the "age. As $ou\ll see later in this cha"ter) $ou can use this collection to add or modif$ controls on a "age.
"sPost2ack "ro"ert$ Allows $ou to determine whether the current re(uest is a -ET re(uest or a P+ST re(uest resulting from the current "age #eing "osted #ac' to itself. This "ro"ert$ is %er$ useful in deciding what to do when loading a &e# Forms "age) as $ou\ll see later in this cha"ter.
!ser "ro"ert$ Pro%ides access to information a#out the currentl$ logged/in user.
=ache "ro"ert$ Pro%ides access to the ASP.NET cache engine) allowing data to #e cached for later retrie%al.
1ind=ontrol method Allows $ou to locate a control contained in the "age\s =ontrols collection #$ s"ecif$ing its ", "ro"ert$.
DiewState "ro"ert$ Pro%ides access to a state dictionar$ ?#ased on the State2ag classA that allows $ou to store information in Ley/Dalue "airs. This information is "assed with each re(uest as a hidden <TM. form field.
=lear=hildDiewState method Allows $ou to delete all %iewstate information for an$ child controls on the "age. This is useful if $ou want these controls to maintain their state most of the time) #ut $ou want to clear the state "rogrammaticall$ under s"ecific circumstances.
Man$ other "ro"erties and methods are e1"osed #$ the Page class. A su#stantial num#er of these are inherited from the =ontrol class) from which the Page class is deri%ed) or the +b*ect class) from which the =ontrol class ?and ultimatel$) e%er$ other classA is deri%ed. This is an e1am"le of how inheritance allows $ou to #uild a %er$ rich o#;ect model.
There are two wa$s to indicate that an ASP.NET "age is inherited from the Page class. The first is adding the @ Page directi%e to an .as"1 file) which automaticall$ ma'es all of the "ro"erties and methods of the Page class a%aila#le to an$ code written in the "age. The second) which is discussed in more detail later in this cha"ter) is inheriting from the Page class in a code/#ehind class that is associated with the "age #$ either the Src or "nherits attri#ute. This not onl$ ma'es all of the mem#ers of the Page class a%aila#le to the code/#ehind class) #ut also allows ASP.NET to com#ine the code in the &e# Form\s .as"1 file with the code in the code/#ehind class file into a single com"iled class at com"ile time. This single com"iled class contains all of the methods and "ro"erties e1"osed #$ the Page class) as well as an$ methods and "ro"erties im"lemented #$ $our code. An$ of the mem#ers of the Page class can #e called within code in a "age without e1"licitl$ using the "age name. For e1am"le) to write te1t to the #rowser using the rite method of the .esponse o#;ect) $ou would use the following code=
?I 6es*onse.4"ite2"Hello, 4o"l!!"3 IA
<owe%er) it is not necessar$ to add the Page "ro"ert$ #ecause the .esponse "ro"ert$ and the other Page mem#ers are e1"osed directl$ when inheriting from the Page class.
ASP.NET sol%es these "ro#lems #$ im"osing limitations on what t$"es of code $ou can write and where $ou can write it. &hile man$ of the e1am"les in this #oo' use the default techni(ue of writing 93/s"ecific code in a code/#ehind module ?rather than in the &e# Forms "age itselfA) it\s worth loo'ing at these limitations for those times when $ou want to wor' without code/#ehind. As with classic ASP) there are still two wa$s to write code within a &e# Forms "age= :script; #loc's and :8 8; render #loc's.
The following code will cause a com"iler error) since the com"iler e1"ects to see either a %aria#le or method declaration=
?sc"i*t lan)ua)e=",b" "unat="se",e""A 6es*onse.4"ite2"Hello, 4o"l!!"3 ?Bsc"i*tA
.i'ewise) $ou can declare a local mem#er %aria#le in a declaration #loc') #ut $ou cannot assign to it outside of a defined method. So the following code will wor'=
?sc"i*t lan)ua)e=",b" "unat="se",e""A %i& Na&e 0s .t"in) .ub .etNa&e Na&e = "0n!"e1" n! .ub
?Bsc"i*tA
There is one e1ce"tion to the %aria#le assignment rule. You can initialiGe the %alue of a %aria#le #$ assigning a %alue as "art of the %aria#le declaration) as follows=
?sc"i*t lan)ua)e=",b" "unat="se",e""A %i& Na&e 0s .t"in) = "0n!"e1" ?Bsc"i*tA
The language attri#ute of the :script; #loc' is o"tional. 3f it is omitted) the %alue will default to the language s"ecified #$ the @ Page directi%e\s language attri#ute. 3f no language attri#ute has #een s"ecified for the @ Page directi%e) the %alue will default to D2 ?this %alue is set in the :compiler; element of the machine.config configuration fileA.
IA
Adding the =lassName attri#ute allows the user control to #e strongl$ t$"ed when added to a "age "rogrammaticall$ ?as o""osed to declarati%el$A. ,reating a user control is fairl$ straightforward. 3n the following e1am"le) $ou\ll create a user control that calculates com"ounding interest. ?0on\t worr$ a#out the mathBit\s "ro%ided as "art of the e1am"le.A
!. Add si1 <abel controls) three Te$t2o$ controls) a ,rop,own<ist control) and a 2utton control to the user control design surface. &hen $ou\re finished) the control should loo' li'e the following illustration.
Since user controls start out in Flow.a$out mode #$ default) $ou\ll need to use the Enter 'e$ to mo%e a control to a new line. 3t\s im"ortant to name or num#er the controls in the order in which the$ a""ear on the "age. ?For e1am"le) the first la#el is <abel>) the second) <abel() and so on.A This guarantees that the code in later ste"s will wor'. 8. Set the "ro"erties of the controls as follows= Co"trol roperty Value <abel> Te$t <abel> 1ontCSi3e <abel( Te$t <abelA Te$t ' %( und Interest 'alculat r :arge Princi(al ;C<, Rate ;D<, <abel> 1ontC2old True
Co"trol
roperty
<abel& Te$t ?#lan'A Q. ,lic' the ,rop,own<ist> control to select it) and then select the "tems "ro"ert$ and clic' the elli"sis ?XA #utton to o"en the ,ollection Editor. Add four items) set the following te1t and %alues) and then clic' *>= Ite# Te+t Annuall) 2 2 M nthl) Value 4 4*
=uarterl) 8
! 6ail) 2?> 6. &hen $ou ha%e finished modif$ing the "ro"erties) the design %iew of ,om"ound.asc1 should loo' li'e the following illustration.
K.
D. 0ou#le/clic' the ,alculate #utton. This will switch to the code/#ehind for the user control and add the 2utton>0=lick e%ent handler. Add the following code) which calls the function to calculate the com"ounded interest) to the e%ent handler. ?Note that the following code is a single line) #ut uses the Visual Basic line continuation character for reada#ilit$.A
G. Label:.Text = "Final BalanceJ W" & < 1H. 11. 1$. -alcBalance2-on,e"t.To(nt3$2TextBox1.Text3, < 2-on,e"t.To(nt3$2TextBox$.Text3 B 1HH3, < -on,e"t.To(nt3$2TextBox3.Text3, < -on,e"t.To(nt1:2%"o*%o1nList1..electe!(te&.Value33.To.t"in)
2!. 3mmediatel$ following the End Sub of the 2utton>0=lick e%ent handler) add the following code) which defines the function for calculating the com"ound interest=
14. /"i,ate Function -alcBalance2B'Val /"nc*l 0s (nte)e", < 18. B'Val 6ate 0s %ouble, <
1:.
B'Val >ea"s 0s (nte)e", < B'Val /e"io! 0s (nte)e"3 0s .t"in) %i& BaseNu& 0s %ouble = 21 + 6ate B /e"io!3 -alcBalance = Fo"&at2/"nc*l U .'ste&.7at+./o12BaseNu&, < 2>ea"s U /e"io!33, "X,XXX,XXH.HH"3.To.t"in) n! Function
2K. Sa%e the control and code/#ehind module) and then #uild the ,ha"terO K "ro;ect. This control ta'es a dollar amount re"resenting the "rinci"al to #e in%ested ?or #orrowedA) an interest rate) a "eriod in $ears) and a com"ounding fre(uenc$) and uses these %alues to calculate the ending #alance. This control enca"sulates all of the controls and methods necessar$ for doing the calculation) so the onl$ wa$ to access them is through the user interface defined #$ the control. 3t is also "ossi#le) if desired) to e1"ose the controls andEor their %alues "u#licl$) so that the$ can #e mani"ulated at runtime from the containing "age. To use this control) $ou need to add it to a &e# Forms "age. You can do this two wa$s= declarati%el$ and "rogrammaticall$. The declarati%e techni(ue is sim"ler) #ut the "rogrammatic techni(ue gi%es $ou #etter runtime control.
8. Sa%e ,om"ound,ontainer.as"1) and then #rowse it using 3nternet E1"lorer #$ right/ clic'ing the file in Solution E1"lorer and selecting Browse &ith. Enter amounts for the "rinci"al) rate) and $ears) then choose a com"ounding fre(uenc$) and then clic' ,alculate. The result should loo' similar to the following illustration. Note that if $ou enter an$ non/integer %alue in the te1t#o1es) an e1ce"tion will occur when $ou clic' ,alculate. You could "re%ent this #$ adding %alidator controls to ensure that onl$ integer %alues are entered.
3f $ou ta'e a loo' at the <TM. %iew for ,om"ound,ontainer.as"1) $ou\ll see that Visual Studio .NET ta'es care of adding #oth the @ .egister directi%e that ma'es the user control a%aila#le to the "age) and the tag that re"resents the user control. This greatl$ sim"lifies the "rocess of adding a user control to the "age) and should "ro#a#l$ #e $our "referred method for adding user controls in Visual Studio .NET. You can) howe%er) also add a user control to the "age "rogrammaticall$) as $ou\ll see in the ne1t section.
!. Sa%e the file) #ut don\t close it. The @ .eference directi%e tells ASP.NET to com"ile and lin' the user control ,om"ound.asc1 with the "age when it is com"iled. This ma'es the control a%aila#le for $ou to add to the "age. Since $ou\re not going to #e adding a tag within the <TM. mar'u" for the control\s out"ut) ta'e ad%antage of a s"ecial ser%er control called the Placeholder control. As the name suggests) this allows $ou to "ut a "laceholder in the <TM. mar'u" to which $ou can add controls later. 3n this wa$) $ou can decide "recisel$ where $ou want the out"ut from the control to a""ear.
Finall$) we need to add the control to the "age) and to the =ontrols collection of the Placeholder control) which will "lace the out"ut of the control where we want it. Then the control will ta'e care of the rest) ;ust as in the "re%ious e1am"le.
!. Sa%e the "age and code/#ehind module) and then #uild the ,ha"terO K "ro;ect. 8. Browse ,om"oundProgrammatic.as"1) using the Browse &ith dialog #o1. The out"ut of the "age should #e the same as in the "re%ious illustration. ' %(aring User ' ntr ls t Include $iles 9ser controls "erform a similar function to ser%er/side includes in classic ASP) #ut the$\re considera#l$ more "owerful #ecause of the le%el of integration with the "age model. A user control can ha%e its own controls) and it can sa%e the %iewstate of its controls or its own %iewstate. This allows the user control to maintain its state across multi"le calls without an$ effort on the "art of the "age containing the user control. 9ser controls can e1"ose #oth "ro"erties and methods) ma'ing them eas$ to understand for de%elo"ers who are used to com"onents. 3nclude files are still a%aila#le in ASP.NET) mainl$ for #ac'ward com"ati#ilit$ with classic ASP. @i%en the ad%antages of user controls) it ma'es sense to use them for new a""lications.
E&ent 5andling
*ne of the #iggest differences #etween classic ASP and ASP.NET is the e1ecution model. 3n classic ASP) "ages were e1ecuted in a to"/to/#ottom fashion. 3n other words) with the e1ce"tion of detours to e1ecute functions defined in the "age) classic ASP "ages were "rocedural rather than e%ent/dri%en) li'e Visual Basic "rograms. ASP.NET changes that #$ #ringing e%ent/dri%en "rogramming to &e# de%elo"ment through ser%er controls and "ost#ac's. At runtime) the code in a &e# Form) as well as in an$ code/ #ehind class associated with that &e# Form) is com"iled into an assem#l$. &hen e1ecuted) the code in that assem#l$ fires e%ents that $ou can handleB#oth those e1"osed #$ the Page class and those that are fired #$ ser%er controls that ha%e #een added to the "age. Page Processing Stages A &e# Forms "age goes through the following "rocessing stages= "nit Page and control settings are initialiGed as necessar$ for the re(uest. <oadDiewState Ser%er control state that was sa%ed to %iewstate in an earlier re(uest is restored. <oadPost,ata An$ data returned in ser%er control form fields is "rocessed) and the rele%ant control "ro"erties are u"dated. <oad ,ontrols are created and loaded) and control state matches the data entered #$ the client. .aisePost,ata=hangedE%ent E%ents are raised in res"onse to changes in control data from the "re%ious re(uest to the current re(uest. .aisePost2ackE%ent The e%ent that caused the "ost#ac' is handled) and the a""ro"riate ser%er/side e%ents are raised. Pre.ender An$ changes that need to #e made "rior to rendering the "age are "rocessed. An$ "rocessing after this "oint will not #e rendered to the "age. Sa%eDiewState
Ser%er control state is sa%ed #ac' to the "age+s %iewstate "rior to tearing down the controls. .ender ,ontrol and "age out"ut is rendered to the client. !n<oad The "age and its constituent controls are remo%ed from memor$ on the ser%er.
*f these stages) $ou can add "age/le%el e%ent handlers for the "nit) <oad) Pre.ender) and !n<oad e%ents. These handlers are t$"icall$ named Page0"nit) Page0<oad) Page0Pre.ender) and Page0!n<oad. For other stages) such as the <oadDiewState) Sa%eDiewState) and .ender stages) $ou can o%erride the a""ro"riate method to customiGe the "rocessing of these stages. *%erriding these methods is discussed in ,ha"ter 2 . Some e%ents) such as those fired #$ the "age) are fired automaticall$ as certain stages of "age "rocessing occur. *thers) such as those associated with ser%er controls) are actuall$ triggered on the client ?such as a user clic'ing a #utton ser%er controlA #ut are fired and handled on the ser%er when the "age is "osted #ac' to the ser%er. Because the "age is reloaded and the control state is restored with each "ost#ac') to the client it a""ears as though the "age is there throughout the client+s interaction with it) and the a""lication a""ears to o"erate much li'e a Visual Basic formT #ased a""lication.
You can handle other "age e%ents) such as the Page0!nload e%ent) #$ adding the a""ro"riate handler code to the code/#ehind module. 3n a code/#ehind module) $ou also need to add the Kandles 'e$word) with the a""ro"riate reference) in this case 9y2ase.!nload. ?9y2ase is the Visual Basic .NET 'e$word for referring to the class that the current class deri%es from) in this case the Page class.A
/"i,ate .ub /a)e<=nLoa!2B'Val sen!e" 0s 9bLect, < B'Val e 0s ,ent0")s3 Han!les 7'Base.=nloa!
*f course) $ou can also handle e%ents if $ou+re not using code/#ehind #$ adding the a""ro"riate e%ent handler to a ser%er/side scri"t #loc' within the .as"1 "age=
?sc"i*t "unat="se",e""A .ub /a)e<Loa!2B'Val sen!e" 0s 9bLect, B'Val e 0s ' ,ent +an!lin) co!e n! .ub ,ent0")s3
?Bsc"i*tA
IMPORTANT The "receding code assumes that the /utoE%ent ireup attri#ute of the "age has #een set to True. For "ages created outside of Visual Studio .NET) $ou won+t need to set this attri#ute manuall$) since true is the default setting inherited from the :pages; configuration section in Machine.config. <owe%er) "ages created in Visual Studio .NET ha%e the /utoE%ent ireup attri#ute in their @ Page directi%e set to 1alse. This means that all e%ent handlers in these "ages must #e manuall$ wired to the e%ents that the$ are to handle. You+ll learn more a#out manuall$ wiring e%ents in ,ha"ter D.
Han!les %"o*%o1nList1..electe!(n!ex-+an)e!
n! .ub
You can add handlers for other e%ents associated with a control #$ using similar s$nta1. &hen writing the e%ent handler in code/#ehind) it doesn+t matter what $ou name the e%ent/handling "rocedure) as long as the Kandles 'e$word correctl$ references the desired e%ent. Still) it+s a good idea to stic' with the naming con%ention of =ontrolName0E%entName) as this ma'es it eas$ to tell at a glance which control and e%ent a gi%en "rocedure is handling. TIP &hen adding e%ent handlers in a code/#ehind module) an eas$ wa$ to ma'e sure that $our code is correct is to use the dro"/down list #o1es at the to" of the code editor window. Sim"l$ select the control whose e%ent $ou want to handle in the left/hand dro"/down list) and then select the e%ent $ou want to handle from the right/hand dro"/down list ?e%ents are denoted #$ a lightning/ #olt iconA. Visual Studio .NET will automaticall$ insert the code for the e%ent handler into $our code/#ehind module.
<andling control e%ents in "ages that do not use code/#ehind is fairl$ straightforward. There are two ste"s= First) add an e%ent handler "rocedure to a ser%er/side scri"t #loc' in the "age) onl$ without the Kandles 'e$word. Then) ma" the e%ent raised #$ the control to the e%ent handler using an attri#ute on the control tag. For e1am"le) if $ou wanted to handle the =lick e%ent of a 2utton control named 2utton>) $ou would add the following code to the :script; #loc' in Ser%er,ontrols.as"1=
.ub Button1<-licC2B'Val .en!e" 0s 9bLect, B'Val ' ,ent +an!le" co!e n! .ub 0s ,ent0")s3
And then $ou would add the following attri#ute to the 2utton> ser%er control tag=
?as*JButton i!="Button1" on-licC="Button1<-licC" "unat="se",e""BA
Again) $ou are not re(uired to name the e%ent handler "rocedure with the =ontrolName0E%entName naming con%ention) #ut using this con%ention will ma'e $our code easier to read.
!. Sa%e the file and #rowse the "age. The control tree section of the ,om"ound,ontainer.as"1 trace out"ut is shown in the illustration on the following "age. Notice that where a control has #een gi%en an e1"licit 30 through its id tag attri#ute) that 30 is used in the control tree.
3f $ou want to "lace the new control at a "articular "osition in the control tree) $ou can use the /dd/t method instead=
%i& 7'TextBox 0s Ne1 TextBox /a)e.-ont"ols.0!!0t2$, 7'TextBox3
/a)e.-ont"ols.6e&o,e0t2$3
To locate a "articular control #$ 30) $ou can use the 1ind=ontrol method of the "age or control containing the control $ou+re loo'ing for=
7'-ont"ol = /a)e.Fin!-ont"ol2"7'TextBox"3
Note that #ecause 1ind=ontrol returns an o#;ect of t$"e =ontrol ?rather than of the s"ecific t$"e of control foundA) $ou will need to cast to the a""ro"riate control t$"e #efore using "ro"erties or methods that are s"ecific to that control t$"e.
9se classes #$ name 3n a &e# Form) add the @ "mport directi%e) with the names"ace without e1"licitl$ attri#ute s"ecif$ing the names"ace to im"ort. s"ecif$ing their names"ace 3n a Visual Basic .NET code/#ehind file) add the "mports statement with the desired names"ace. Ma'e a user control or custom ser%er control a%aila#le for use on a &e# Form Ena#le out"ut caching ,reate a user control 0rag and dro" the user control from the Solution E1"lorer window onto the design surface of a &e# Form.
Add the @ +utput=ache directi%e to the "age) and set the desired attri#utes. 7ight/clic' the "ro;ect in Solution E1"lorer) select Add) and then select Add &e# 9ser ,ontrol. Add the desired controls to the user control) and write an$ code necessar$) and then sa%e the files and #uild the "ro;ect.
&rite ser%er/side functions ,reate a :script; #loc' with the runat56ser%er7 attri#ute and "lace in a &e# Forms "age the functions within it. <andle "age/le%el e%ents Add an e%ent handler with the a""ro"riate signature ?such as Page0e%entnameA to the code/#ehind module for the "age ?or the ser%er :script; #loc' for "ages that do not use code/#ehindA.
9se the two main t$"es of ser%er controls= <TM. controls and &e# controls. 9se s"ecialiGed &e# controls) such as the =alendar control and the Dalidation ser%er controls. Mani"ulate ser%er controls "rogrammaticall$ at runtime. <andle ser%er control e%ents.
,ha"ter K loo'ed at how &e# Forms "ages are constructed) including some sim"le uses of ser%er controls. This cha"ter will ta'e an in/de"th loo' at using ser%er controls in $our a""lication.
<TM. ,ontrols
The <TM. controls ma" 2/to/2 with the standard <TM. elements. <owe%er) some <TM. elements don+t ma" directl$ to a s"ecific <TM. control. &h$ would $ou want to use an <TM. control instead of ;ust coding <TM.U Because $ou can easil$ mani"ulate the loo' and functionalit$ of the "age at runtime #$ changing the control+s attri#utes "rogrammaticall$. The <TM. controls reside in the System. eb.!".Ktml=ontrols names"ace) which is a%aila#le to &e# Forms "ages automaticall$. Ta#le D/2 descri#es how <TM. elements ma" to <TM. controls. Ta#le G34. 9apping of KT9< Elements to KT9< =ontrols 5TM& Ele#e"t Co"trol Type urpose Pro%ides "rogrammatic access to an <TM. anchor element. E1"oses a Ser%er=lick e%ent. :a; 0efines a h$"erte1t Ktml/nchor lin'.
Ta#le G34. 9apping of KT9< Elements to KT9< =ontrols 5TM& Ele#e"t :button; 7enders an <TM. #utton. Co"trol Type Ktml2utton urpose Pro%ides "rogrammatic access to an <TM. #utton element. This element is defined in the <TM. 8. s"ec and is su""orted onl$ #$ Microsoft 3nternet E1"lorer 8. and higher. E1"oses a Ser%er=lick e%ent. Pro%ides "rogrammatic access to an <TM. form element. Acts as a container for other ser%er controls. An$ controls that need to "artici"ate in "ost#ac's should #e contained within an Ktml1orm control. Pro%ides "rogrammatic access to an <TM. image element. Pro%ides "rogrammatic access to an <TM. in"ut element for the button) submit) and reset in"ut t$"es. E1"oses a Ser%er=lick e%ent.
Ktml1orm
:img; Em#eds an image Ktml"mage or %ideo cli". :input type56button7; Ktml"nput2utton :input type56submit7; :input type56reset7; S"ecifies a form in"ut control. :input type5 Ktml"nput=heck2o$ 6checkbo$7; S"ecifies a form in"ut control. :input type56file7; S"ecifies a form in"ut control. Ktml"nput1ile
Pro%ides "rogrammatic access to an <TM. in"ut element for the checkbo$ in"ut t$"e. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an <TM. in"ut element for the file in"ut t$"e. Pro%ides "rogrammatic access to an <TM. in"ut element for the hidden in"ut t$"e. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an <TM. in"ut element for the image in"ut t$"e. E1"oses a Ser%er=lick e%ent.
:input type56hidden7; Ktml"nputKidden S"ecifies a form in"ut control. :input type56image7; S"ecifies a form in"ut control. :input type56radio7; S"ecifies a form in"ut t$"e. Ktml"nput"mage
Ktml"nput.adio2utton Pro%ides "rogrammatic access to an <TM. in"ut element in"ut control for the radio in"ut t$"e. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an <TM. in"ut element for the te$t and password in"ut t$"es. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an <TM.
:input type56te$t7; Ktml"nputTe$t :input type5 6password7; S"ecifies a form in"ut control. :select; 0efines a list KtmlSelect
Ta#le G34. 9apping of KT9< Elements to KT9< =ontrols 5TM& Ele#e"t #o1 or dro" down list. :table; 0enotes a KtmlTable section of tags organiGed into rows and columns. Co"trol Type urpose select element. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an <TM. ta#le element. Note that some ta#le su#elements ?such as :col;) :tbody;) :thead;) and :tfoot;A are not su""orted #$ the KtmlTable control. Pro%ides "rogrammatic access to <TM. ta#le cell elements. Pro%ides "rogrammatic access to <TM. ta#le row elements. Pro%ides "rogrammatic access to an <TM. te1t area element. E1"oses a Ser%er=hange e%ent. Pro%ides "rogrammatic access to an$ <TM. element not s"ecificall$ re"resented #$ its own <TM. control class.
:td; and :th; 0enote ta#le cells and header rows. :tr; 0enotes a ta#le row. :te$tarea; S"ecifies a multi/line te1t in"ut control.
KtmlTable=ell
KtmlTable.ow KtmlTe$t/rea
Each <TM. control class is deri%ed from the generic Ktml=ontrol class. This class "ro%ides methods and "ro"erties common to all <TM. controls) such as the /ttributes collection) which "ro%ides a collection of nameE%alue "airs for an$ attri#utes contained in the tag definition for the control ?such as id56my=ontrol7 or border56>7A. The indi%idual control classes then e1"ose additional methods and "ro"erties that are s"ecific to the <TM. element that the$ re"resent. For e1am"le) the Ktml/nchor control e1"oses an Kref "ro"ert$ that allows $ou to "rogrammaticall$ modif$ the 97. to which the anchor tag is lin'ed) as well as a Target "ro"ert$) which allows $ou to modif$ the target of the anchor tag. NOTE Because the <TM. controls do not e1"ose a strongl$ t$"ed control e(ui%alent for e%er$ <TM. element) $ou can use the /ttributes collection to "rogrammaticall$ add tag attri#utes to an$ <TM. control. This allows $ou to "rogrammaticall$ set tag attri#utes that are not e1"osed as "ro"erties #$ the <TM. control classes=
%i& &'TB 0s Ne1 Ht&l(n*utText23 &'TB.0tt"ibutes2"onBlu""3 = "La,asc"i*tJale"t2'Lost #ocus!'3O "
Man$ of the <TM. controls also e1"ose e%ents to which $ou can res"ond ?a#o%e and #e$ond the standard e%ents inherited from Ktml=ontrolA. Some <TM. controls e1"ose a Ser%er=lick e%ent and some e1"ose a Ser%er=hange e%ent. The ta#le D/2 lists which controls su""ort which e%ent.
NOTE 9nli'e the ser%er controls in the &e# control names"ace) which handle onl$ ser%er/side e%ents) <TM. controls can handle #oth ser%er/side e%ents and an$ client/side e%ents that e1ist for the <TM. element to which the$ ma". For e1am"le) the Ktml"nput2utton control su""orts #oth the ser%er/side Ser%er=lick e%ent and the client/side =lick e%ent. To handle #oth e%ents) $ou+d use the following tag declaration=
?in*ut t'*e="sub&it" onclicC="client<+an!le"" onse",e"clicC="se",e"<+an!le"" "unat="se",e""BA
This allows $ou to "erform actions on the client #efore the "age is "osted #ac' to the ser%er) if desired. Because of their close ma""ing to indi%idual <TM. elements) <TM. controls "ro%ide the fastest and easiest "ath for mo%ing from static <TM. to the "ower of ASP.NET ser%er controls. 3n &e# Forms "ages) there are three #asic rules of the game when it comes to case sensiti%it$.
Names"aces and class names are case sensiti%e. For e1am"le) names"aces im"orted using the @ "mport directi%e will cause an error if the correct case is not used. This is a common cause of errors for those ;ust getting started with ASP.NET. Tag names and attri#utes are not case sensiti%e. This also a""lies to ser%er control "ro"erties e1"ressed as tag attri#utes. ,ontrol names used in RscriptS #loc's or in code/#ehind classes might or might not #e case sensiti%e) de"ending on whether the language $ou+re using is case sensiti%e. ,J is case sensiti%e) for e1am"le) so using the incorrect case for a control name or "ro"ert$ in ,J code can lead to errors. Though Visual Basic .NET is not case/sensiti%e) $ou should still use case consistentl$) to ensure that $our code is eas$ to read and maintain. NOTE &hen $ou+re wor'ing with a case/sensiti%e language) or when $ou recei%e errors such as 4The Names"ace or t$"e :namespace; for the 3m"ort ^S$stem.:namespace;+ cannot #e found)5 it+s usuall$ a good idea to chec' for incorrect case in control) class) or names"ace names.
B$ sim"l$ adding the runat56ser%er7 attri#ute and an id attri#ute to the :body; and :p; elements) $ou can turn these elements into Ktml-eneric=ontrols=
?+t&lA ?bo!' i!="Bo!'" "unat="se",e""A ?* i!="Text/a"a" "unat="se",e""AT+is is so&e si&*le HT7L text.?B*A ?Bbo!'A ?B+t&lA
*nce $ou+%e con%erted the elements to <TM. controls) it is fairl$ sim"le to mani"ulate them in ser%er/side code=
?+t&lA ?+ea!A ?sc"i*t lan)ua)e=",b" "unat="se",e""A .ub /a)e<Loa!2.en!e" 0s 9bLect, 0s ,ent0")s3
Bo!'.0tt"ibutes2"b)colo""3 = ";"a'" Text/a"a.0tt"ibutes2"st'le"3 = "colo"J6e!O#ont5siDeJla")eO" n! .ub ?Bsc"i*tA ?B+ea!A ?bo!' i!="Bo!'" "unat="se",e""A ?* i!="Text/a"a" "unat="se",e""AT+is is so&e si&*le HT7L text.?B*A ?Bbo!'A ?B+t&lA
3f $ou sa%e this code in a file with the .as"1 e1tension to a director$ set u" as a %irtual director$ in 33S and #rowse the "age) the out"ut should loo' li'e the following illustration.
<TM. controls are useful for d$namicall$ adding and remo%ing <TM. ta#le rows or :select; items. 3n the following e1am"le) $ou+ll see how to d$namicall$ add and remo%e items in a dro"/ down list created #$ an KtmlSelect control.
G. ?BselectA 1H. ?in*ut i!=" nte"" t'*e="button" ,alue=" nte""A ?+3A?s*an i!="Fa,e"A?Bs*anA?B+3A
22. Switch #ac' to design %iew. The "age should loo' similar to the following illustration.
22. 7ight/clic' the dro"/down list re"resenting the :select; element) and select 7un As Ser%er ,ontrol. 7e"eat for the button element. Note the gl$"hs that Visual Studio .NET adds to these elements) indicating that the$ are now ser%er controls. The gl$"hs are shown in the following illustration.
Because the :span; element has no re"resentation in design %iew) $ou+ll need to add the runat56ser%er7 attri#ute to this element manuall$. 2!. Switch to <TM. %iew) and then add the runat56ser%er7 attri#ute to the :span; element to transform it into a ser%er control. 28. Switch #ac' to design %iew and dou#le/clic' in an o"en area of the "age. This will o"en the code/#ehind module for the "age) and "lace the cursor in the Page0<oad e%ent handler. Add the following codeBwhich adds two items to the KtmlSelect control and remo%es one from itBto the Page0<oad e%ent handler=
18. (# Not (s/ostBacC T+en 1:. 1E. 1F. 1G. (ce-"ea&.(te&s.0!!2"/istac+io"3 (ce-"ea&.(te&s.0!!2"6ocC' 6oa!"3 '4e !on't liCe .t"a1be""' (ce-"ea&.(te&s.6e&o,e2".t"a1be""'"3 n! (#
2 . 9sing the ta#s at the to" of the editor window) switch #ac' to <tmlSelect.as"1. 0ou#le/ clic' the #utton. This will add the Enter0Ser%er=lick e%ent handler to the code/#ehind module) and switch $ou #ac' to the code/#ehind module. Add the following code to the Enter0Ser%er=lick e%ent handler=
Fa,e.(nne"Ht&l = ">ou" #a,o"ite is " & (ce-"ea&.Value & "!"
22. Sa%e the "age and code/#ehind module) #uild the "ro;ect) and then #rowse the "age. The out"ut should loo' similar to the following illustration.
22. Select 7oc'$ 7oad from the dro"/down list) and then "ress the Enter #utton. The out"ut should loo' similar to the following illustration.
You would declare an ASP.NET 2utton ser%er control with the following s$nta1=
?as*Jbutton i!=" nte"" Text=" nte"" 9n-licC=" nte"<-licC" "unat="se",e"" BA
Notice that in the second e1am"le) a forward slash character ?EA is added #efore the closing angle #rac'et ?SA. This is re(uired when $ou do not use a com"lete closing tag. <ere+s an e1am"le of when $ou+d use a closing tag=
?as*Jlabel i!="&'Label" "unat="se",e""AHi t+e"e!?Bas*JlabelA
You enclose the literal te1t Ki thereT #etween o"ening and closing tags. The literal te1t #ecomes the Te$t "ro"ert$ of the <abel control. The <abel control) which renders as a :span; on the client side) is one of a num#er of controls that allow $ou to enclose literal te1t for the Te$t "ro"ert$ ?or some other "ro"ert$ of the controlA #etween the o"ening and closing tags. *ther controls include the <iteral) Panel) PlaceKolder) and Te$t2o$ controls. You could also accom"lish the same result #$ using a single/tag s$nta1=
?as*Jlabel i!="&'Label" text="Hi t+e"e! " "unat="se",e""BA
,hoosing the 7ight ,ontrol Because there are two distinct sets of ser%er controls to choose from) $ou might wonder how to choose the right control for a gi%en a""lication. 3n general) if $ou are interested in handling client/side e%ents or are con%erting <TM. elements to ser%er controls) $ou should loo' at the <TM. controls. 3f $ou+re familiar with the Visual Basic "rogramming model) the &e# controls ma" %er$ closel$ to that model. The &e# controls also "ro%ide additional functionalit$) such as %alidation) and "ro%ide a strong #asis for customiGation. &hen $ou add a control to the "age declarati%el$) $ou are doing two things= gi%ing the control enough information to #e created and initialiGed "ro"erl$) and setting the "ro"erties for the control. The first "art is accom"lished #$ the asp: "refi1 and the tag name) "lus the id and runat attri#utes. *nl$ the "refi1Etag name and the runat attri#ute are re(uired to create a ser%er control) #ut the id attri#ute is re(uired if $ou want to refer to the control in ser%er/side code. *nce $ou+%e "ro%ided this minimum information) $ou can set additional "ro"erties #$ adding attri#utes to the tag declaration corres"onding to the "ro"ert$ $ou want to set. For e1am"le) if $ou wanted to set the Disible "ro"ert$ of a <abel control to 1alse ?to set u" a message declarati%el$ and show it #$ ma'ing it %isi#le later in ser%er/side codeA) $ou would modif$ the declaration as follows=
?as*Jlabel i!="&'Label" text="Hi t+e"e! " ,isible="#alse" "unat="se",e""BA
Some of the more feature/filled controls) such as the ,ata-rid control) use a com#ination of attri#utes in the main tag definition and su#tags that declare additional controls or set "ro"erties ?such as the "temStyle and /lternating"temStyle tags that can #e used with the ,ata-rid or ,ata<ist controlsA to define the "ro"erties for the control. You+ll see e1am"les of these controls later in this cha"ter.
The "receding code creates the <abel control and sets its te1t "ro"ert$ to Ki thereT. There+s ;ust one "ro#lem. As written) the code adds the control to the end of the "age+s ,ontrols collection) which is actuall$ after the closing :body; and :html; tags) which ASP.NET treats as <iteral controls on the ser%er. The code that is sent to the #rowser is shown here=
?+t&lA ?+ea!A ?B+ea!A ?bo!'A ?Bbo!'A ?B+t&lA ?s*anAHi t+e"e!?Bs*anA
&hile this out"ut will still #e rendered in most #rowsers) the incorrect <TM. s$nta1 ma'es it less than ideal. This "resents e%en more of a "ro#lem when $ou are dealing with #oth declarati%e and "rogrammaticall$ created controls. ,reating controls out of order can "roduce unintended results. So what do $ou doU
*ne o"tion is to call the /dd/t method of the =ontrols collection) instead of /dd. /dd/t ta'es two arguments= an integer re"resenting the location in the collection where the control should #e added) and the name of the control to add.
/a)e.-ont"ols.0!!0t23, &'Label3
The onl$ "ro#lem is that in order to render the control where $ou want it in the "age) $ou ha%e to 'now e1actl$ where the control should a""ear in the collection. This is not alwa$s "ractical. An easier wa$ to ensure that "rogrammaticall$ created controls a""ear where $ou want them to is to use a PlaceKolder control to locate the control in the "age. The PlaceKolder control has no 93 of its own. All of the content within a PlaceKolder control is rendered #ased on the controls in its =ontrols collection. So) to ma'e sure that the control in the "re%ious e1am"le is dis"la$ed within the #od$ of the <TM. document sent to the #rowser) $ou can use the following code=
?IM /a)e Lan)ua)e=",b" IA ?+t&lA ?+ea!A ?sc"i*t "unat="se",e""A .ub /a)e<Loa!23 %i& &'Label 0s Ne1 Label &'/H.-ont"ols.0!!2&'Label3 &'Label.Text = "Hi t+e"e!" n! .ub ?Bsc"i*tA ?B+ea!A ?bo!'A ?as*J*lace+ol!e" i!="&'/H" "unat="se",e"" BA ?Bbo!'A ?B+t&lA
You can add multi"le controls to the same "laceholder) and $ou can use multi"le "laceholders in the same "age.
To add a control to the "age) $ou can sim"l$ dou#le/clic' the desired ser%er control. The control will #e inserted into the "age at the location of the cursor if the "age is in Flow.a$out mode) or at the to"/left corner of the "age if the "age is in @rid.a$out mode. 3n @rid.a$out mode) $ou can also select a control from the Tool#o1 and draw it on the form as $ou would a Visual BasicTst$le control. 3n either Flow.a$out or @rid.a$out mode) $ou can also drag and dro" controls from the Tool#o1 onto the "age at the desired location. 8. 9sing one of the techni(ues descri#ed in the "re%ious ste") add a <abel control) a ,rop,own<ist control) a 2utton control) and another <abel control to the "age. *nce the controls ha%e #een added) the "age should loo' similar to the following illustration.
Q. Set the "ro"erties of the added controls as follows) using the Pro"erties window= Co"trol roperty Value <abel> Te$t 2utton> Te$t <abel( Te$t &hat+s $our fa%orite ice creamU Enter ?#lan'A
Co"trol
roperty
Value
<abel( 1ontCSi3e .arger 6. Select 0ro"0own.ist2 #$ clic'ing it in the designer window) and then select its "tems "ro"ert$ in the Pro"erties window. ,lic' the elli"sis #utton ?XA to o"en the .ist3tem ,ollection Editor and edit the "tems "ro"ert$. K. 9se the Add #utton to add three items to the collection. Set their Te$t and Dalue "ro"erties #$ t$"ing 'h c late) Straw#err)) and Vanilla) res"ecti%el$. The result should loo' similar to the illustration on the following "age. &hen $ou are done adding items) clic' *>.
D. 0ou#le/clic' in an o"en area of the "age. This will o"en the code/#ehind module for the "age) and "lace the cursor in the Page0<oad e%ent handler. Add the following code) which adds two items to the ,rop,own<ist control and remo%es one) to the Page0<oad e%ent handler. ?This code is almost identical to the code used in the <TM. controls e1am"leI onl$ the control name has #een changed.A
G. (# Not (s/ostBacC T+en 1H. %"o*%o1nList1.(te&s.0!!2"/istac+io"3
28. 9sing the ta#s at the to" of the editor window) switch #ac' to 0ro"0own.ist.as"1. 0ou#le/clic' the #utton. This will add the 2utton>0=lick e%ent handler to the code/ #ehind module) and switch $ou #ac' to the code/#ehind module. Add the following code to the 2utton>0=lick e%ent handler=
18. Label$.Text = ">ou" #a,o"ite is " & < %"o*%o1nList1..electe!(te&.Value & "!"
26. Sa%e the "age and code/#ehind module) #uild the "ro;ect) and then #rowse the "age. The out"ut should loo' similar to the following illustration.
2K. Select 7oc'$ 7oad from the dro"/down list) and then clic' the Enter #utton. The out"ut should loo' similar to the following illustration.
&hat if $ou want to do something more com"licatedU &hile controls such as the <abel control e1"ose "ro"erties li'e 1ore=olor and 2ack=olor) at times these "ro"erties will not #e sufficient. .et+s sa$ $ou want to a""l$ a cascading st$le sheet ?,SSA class defined elsewhere ?either in a Style #loc' at the to" of the "age or in a lin'ed st$le sheetA to a ser%er control. *r ma$#e $ou ;ust want to use ,SS st$les directl$ in $our control tag. For these occasions) the =ss=lass and Style "ro"erties defined in the eb=ontrol #ase class ?and inherited #$ all eb=ontrol classesA come in hand$. &ith the =ss=lass "ro"ert$) $ou can set u" a ,SS class such as the following=
?st'le t'*e="textBcss"A .&'label Y #ont5siDeJ$4*tO #ont51ei)+tJbol!O colo"J"e!OZ ?Bst'leA
This techni(ue wor's fine for lin'ed st$le sheets as well. You can use the Style "ro"ert$ to s"ecif$ ,SS st$les directl$) as follows=
?as*Jlabel i!="&'Label" st'le="#ont5siDeJ$4*tO #ont51ei)+tJbol!O colo"J"e!O" "unat="se",e""A Hi t+e"e! ?Bas*JlabelA
Note that whether $ou set the color of a <abel control with the 1ore=olor "ro"ert$ or use the =ss=lass or Style "ro"erties declarati%el$) the result is rendered as a class or st$le attri#ute on the resulting :span; tag) which is the client/side re"resentation of the eb=ontrol control. NOTE Although $ou can set most control "ro"erties declarati%el$ #$ using the "ro"ert$ name as an attri#ute of the tag used to declare the control) some com"ound "ro"erties ?"ro"erties that are re"resented #$ another classA re(uire that $ou use a slightl$ different attri#ute s$nta1. A good e1am"le of this is the 1ont "ro"ert$ ?defined in the eb=ontrol #ase classA) which returns an instance of the 1ont"nfo class. To modif$ the font of a control that inherits from eb=ontrol ?such as the <abel controlA) $ou use attri#utes in the form fontC:propertyname;) as follows=
?as*Jlabel i!="&'Label" #ont5na&e="a"ial" "unat="se",e""A
You can also access these "ro"erties "rogrammaticall$) using the form :controlname;.1ont.:propertyname;) as follows=
&'Label.Font.Na&e = "0"ial"
Finall$) $ou can also a""l$ st$les to $our controls #ased on the client/side re"resentation of the control. As noted) <abel controls are rendered on the client as :span; tags) so if $ou define a st$le that a""lies to all :span; elements) $our <abel controls will also use this st$le. As long as $ou 'now the client/side re"resentation of a "articular control ?which $ou can get #$ %iewing the source of the "age from the #rowserA) $ou can create a st$le sheet to format that control.
Sending Mail
A common tas' for man$ &e# a""lications is sending e/mail to customers or %isitors. *ften) this e/mail is generated automaticall$) without the need for s"ecific data entr$. But site o"erators might also want a wa$ to send a (uic' e/mail through the site. &e# controls) in com#ination with the .NET Smtp9ail and 9ail9essage classes) can ma'e adding this functionalit$ to a &e# a""lication (uic' and eas$.
NOTE This e1am"le assumes that $ou ha%e access to an SMTP ser%er from which to send $our e/mail. Microsoft &indows 2 ) Microsoft &indows -P Professional) and Microsoft &indows Ser%er 2 ! come with an SMTP ser%ice that is "art of the ser%ices "ro%ided #$ 33S. The SMTP ser%ice is relati%el$ eas$ to install and configure. You can find details for setting u" the SMTP ser%ice at http://msdn.microsoft.com/library/enCus/dnduwon/html/d)smtp.asp.
!. Add a <abel control and a Te$t2o$ control to each of the first fi%e rows of the ta#le) as shown in the following illustration. Note that in addition to dragging controls from the tool#o1 to the "age) $ou can create new controls #$ clic'ing an e1isting control of the desired t$"e ?such as a <abel controlA and dragging it to the new location while holding down the ,trl 'e$. ?,lic' first) then "ress control and drag.A This techni(ue has the
ad%antage of creating a co"$ of the e1isting controls including its "ro"erties ?with the e1ce"tion of the ", "ro"ert$A.
8. Add a 2utton control and an Ktml"nput2utton control with the t$"e set to reset to the last row of the ta#le. To add the <TM. 7eset #utton) $ou will need to switch to the <TM. ta# of the tool#o1) drag the 7eset Button to the a""ro"riate ta#le cell) and then right/clic' the 7eset Button and select 7un As Ser%er ,ontrol. 9sing an Ktml"nput2utton control allows $ou to reset the form fields on the client without a round/tri" to the ser%er) while allowing $ou to mani"ulate the control on the ser%er side as well) as $ou+ll do in a later ste". Q. Set the "ro"erties of the added controls as follows= Co"trol roperty Value <abel> <abel( <abelA <abelB Te$t Te$t Te$t Te$t To: ==: 2==: Sub*ect:
Co"trol <abel)
roperty Te$t
2utton> Te$t Send 6. &hen $ou+%e finished) the "age should loo' li'e the following illustration. K.
D. Switch to the code/#ehind module #$ dou#le/clic'ing an em"t$ area of the "age. Add an "mports directi%e to im"ort the System. eb.9ail names"ace so $ou can refer to its classes without using the names"ace name each time. This directi%e should go at the to" of the code/#ehind module) #efore the class definition=
(&*o"ts .'ste&.4eb.7ail
C. Now $ou need to add code to send the mail when the Send #utton is clic'ed. Switch #ac' to Smt"Email.as"1) and dou#le/clic' the Send #utton) which will o"en the code/#ehind
module for the "age and insert a =lick e%ent handler for the #utton) and then add the following code) which creates an instance of the 9ail9essage class) sets the necessar$ "ro"erties) and then sends the message using the Send method of the Smtp9ail class. ?Because the Send method is a Static method) it is not necessar$ to create an instance of Smtp9ail to use the method.A
1H. '-"eate 7ail7essa)e instance, set *"o*e"ties, an! sen! 11. %i& 7ail 0s Ne1 7ail7essa)e 1$. 13. 7ail.To = TextBox1.Text 14. 7ail.-- = TextBox$.Text 18. 7ail.B-- = TextBox3.Text 1:. 7ail..ubLect = TextBox4.Text 1E. 7ail.Bo!' = TextBox8.Text 1F. 1G. '.et t+e *"o*e"t' belo1 to a ,ali! e&ail a!!"ess $H. 7ail.F"o& = "<valid email address>" $1. .&t*7ail..&t*.e",e" = "local+ost" $$. .&t*7ail..en!27ail3 $3. $4. $8. $:. '=se t+e #i"st label to !is*la' status $E. Label1.Text = "7ail .ent" $F. $G. 'Hi!e t+e "est o# t+e cont"ols 3H. TextBox1.Visible = False 31. Label$.Visible = False 3$. TextBox$.Visible = False 33. Label3.Visible = False 34. TextBox3.Visible = False 38. Label4.Visible = False
3:. TextBox4.Visible = False 3E. Label8.Visible = False 3F. TextBox8.Visible = False 3G. Button1.Visible = False 4H. 6eset1.Visible = False 41. 4$. '0!! a H'*e"linC cont"ol to allo1 sen!in) anot+e" e&ail 43. %i& LinC 0s Ne1 H'*e"LinC 44. LinC.Text = "-licC +e"e to sen! anot+e" e&ail." 48. LinC.Na,i)ate="l = ".&t* &ail.as*x" 4:. 4E. 'T+is line is onl' necessa"' i# t+e *a)e is in ;"i!La'out &o!e 4F. LinC.0tt"ibutes2".t'le"3 = "L FTJ F*xO /9.(T(9NJ absoluteO " & < 4G. "T9/J 8H*x" /a)e.-ont"ols.0!!2LinC3
*nce the mail has #een sent) the code hides all of the form controls #$ setting the Disible "ro"ert$ for each control to 1alse and adds a Kyper<ink control to lin' #ac' to the original "age to send another e/mail) if desired. Note that $ou need to set 9ail.1rom to a %alid e/mail address and change Smtp9ail.SmtpSer%er to the name of an a%aila#le ser%er running SMTP if the local machine is not running an SMTP ser%ice. Q . Sa%e the "age and code/#ehind module) and then #uild the "ro;ect. Browse the "age #$ right/clic'ing Smt"Email.as"1 in Solution E1"lorer) selecting Browse &ith) and then selecting 3nternet E1"lorer. The out"ut should loo' something li'e the following illustration. *nce $ou+%e sent e/ mail) the lin' should ta'e $ou #ac' to the original "age.
This e1am"le shows how sim"le it can #e to send e/mail using ser%er controls on a &e# Form) #ut it does ha%e a cou"le of shortcomings. *ne is that if $ou don+t enter an address in the To) ,,) or B,, field) $ou+ll get an error. Another is that it ta'es a fair amount of code to hide all the controls once $ou+%e sent the e/mail. You can fi1 this second shortcoming #$ adding another <abel control outside the ta#le) and then turning the ta#le into an KtmlTable control #$ adding the runat56ser%er7 attri#ute. You can then hide all of the controls in the ta#le #$ setting the Disible "ro"ert$ of KtmlTable to 1alse.
Registrati n !iAard
Another common need in &e# a""lications is "ro%iding users with an eas$ wa$ to register. 7egistration allows $ou to "ro%ide $our %isitors with "ersonaliGed ser%ices) sa%ed sho""ing carts) and other %alua#le assistance. To ma'e registration as sim"le as "ossi#le) $ou might want to use a multi"age format similar to a &indows &iGard interface. This t$"e of interface will #e immediatel$ familiar to &indows users. The following listing shows the code for a sim"le registration wiGard im"lemented as an ASP.NET &e# Form. This listing also shows how $ou can use a single/"age structure for controls and code) as o""osed to the code/#ehind structure of Visual Studio .NET. 9nli'e &e# Forms created in Visual Studio .NET) the code in the following listing does not need to #e "recom"iled. <owe%er) since the code is included in the "age ?which
must #e de"lo$ed to the &e# ser%er on which it will runA) an$one with file access to the &e# ser%er can read the code ?assuming the$ ha%e the correct "ermissionsA. B$ contrast) using code/ #ehind modules allows $ou to de"lo$ ;ust the .as"1 files and com"iled assem#l$ ?or assem#liesA without de"lo$ing the code/#ehind modules that contain the 93/related code.
7eg&iG.as"1
?IM /a)e Lan)ua)e=",b" IA ?+t&lA ?+ea!A ?sc"i*t "unat="se",e""A .ub /a)e<Loa!23 (# Not (s/ostBacC T+en .te*1.Font.Bol! = T"ue n! (# n! .ub .ub Next<-licC2.en!e" 0s 9bLect, e 0s .elect -ase .en!e"./a"ent.(% -ase "/a)e1" /a)e1.Visible = False .te*1.Font.Bol! = False /a)e$.Visible = T"ue .te*$.Font.Bol! = T"ue -ase "/a)e$" /a)e$.Visible = False .te*$.Font.Bol! = False /a)e3.Visible = T"ue .te*3.Font.Bol! = T"ue 6e,ie1FNa&e.Text = "Fi"st Na&eJ " & Fi"stNa&e.Text 6e,ie17Na&e.Text = "7i!!le Na&eJ " & 7i!!leNa&e.Text 6e,ie1LNa&e.Text = "Last Na&eJ " & LastNa&e.Text 6e,ie1 &ail.Text = " &ailJ " & &ail.Text ,ent0")s3
6e,ie10!!"ess.Text = "0!!"essJ " & 0!!"ess.Text 6e,ie1-it'.Text = "-it'J " & -it'.Text 6e,ie1.tate.Text = ".tateJ " & .tate.Text 6e,ie1Ki*.Text = "Ki*J " & Ki*.Text n! .elect n! .ub .ub /"e,ious<-licC2.en!e" 0s 9bLect, e 0s .elect -ase .en!e"./a"ent.(% -ase "/a)e$" /a)e$.Visible = False .te*$.Font.Bol! = False /a)e1.Visible = T"ue .te*1.Font.Bol! = T"ue -ase "/a)e3" /a)e3.Visible = False .te*3.Font.Bol! = False ,ent0")s3
/a)e$.Visible = T"ue .te*$.Font.Bol! = T"ue n! .elect n! .ub ?Bsc"i*tA ?st'le t'*e="textBcss"A !i, Y bacC)"oun!Jsil,e"O 1i!t+J4HH*xO bo"!e"J$*x outsetO &a")inJ8*xO
*a!!in)J8*xO Z ?Bst'leA ?B+ea!A ?bo!'A ?#o"& "unat="se",e""A ?as*Jlabel i!="6e)4iD" text="6e)ist"ation 4iDa"!" #ont5bol!="t"ue" #ont5siDe="1:" #ont5na&e=",e"!ana" "unat="se",e""BA ?b"BA ?as*Jlabel i!=".te*1" text=".te* 1J nte" /e"sonal (n#o"
#ont5na&e=",e"!ana" "unat="se",e""BA ?b"BA ?as*Jlabel i!=".te*3" text=".te* 3J 6e,ie1" #ont5na&e=",e"!ana" "unat="se",e""BA ?b"BA ?as*J*anel i!="/a)e1" "unat="se",e""A ?table ali)n="cente""A ?t"A
?as*Jtextbox i!="Fi"stNa&e" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A ?as*Jlabel i!="7i!!leNa&eLabel" text="7i!!le Na&eJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!="7i!!leNa&e" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A ?as*Jlabel i!="LastNa&eLabel" text="Last Na&eJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!="LastNa&e" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A ?as*Jlabel i!=" &ailLabel" text=" &ailJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!=" &ail" "unat="se",e""BA ?Bt!A
?Bt"A ?t"A ?t! cols*an="$" ali)n="cente""A ?as*Jbutton i!="/1/"e,ious" Text="/"e,ious" enable!="#alse" onclicC="/"e,ious<-licC"
"unat="se",e""BA ?as*Jbutton i!="/1Next" Text="Next" onclicC="Next<-licC" "unat="se",e""BA ?in*ut i!="/16eset" t'*e=""eset" "unat="se",e""BA ?Bt!A ?Bt"A ?BtableA ?Bas*J*anelA ?as*J*anel i!="/a)e$" ,isible="#alse" "unat="se",e""A ?table ali)n="cente""A ?t"A ?t!A ?as*Jlabel i!="0!!"essLabel" text=".t"eet 0!!"essJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!="0!!"ess" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A ?as*Jlabel i!="-it'Label" text="-it'J" "unat="se",e""BA
?Bt!A ?t!A ?as*Jtextbox i!="-it'" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A ?as*Jlabel i!=".tateLabel" text=".tateJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!=".tate" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A
?t!A ?as*Jlabel i!="Ki*Label" text="Ki* -o!eJ" "unat="se",e""BA ?Bt!A ?t!A ?as*Jtextbox i!="Ki*" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$" ali)n="cente""A ?as*Jbutton i!="/$/"e,ious" Text="/"e,ious" onclicC="/"e,ious<-licC" "unat="se",e""BA ?as*Jbutton i!="/$Next" Text="Next"
onclicC="Next<-licC" "unat="se",e""BA ?in*ut i!="/$6eset" t'*e=""eset" "unat="se",e""BA ?Bt!A ?Bt"A ?BtableA ?Bas*J*anelA ?as*J*anel i!="/a)e3" ,isible="#alse" "unat="se",e""A ?table ali)n="cente""A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie1FNa&e" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie17Na&e" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie1LNa&e" "unat="se",e""BA ?Bt!A ?Bt"A
?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie10!!"ess" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie1-it'" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie1.tate" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jlabel i!="6e,ie1Ki*" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*Jbutton i!="/3/"e,ious" Text="/"e,ious" onclicC="/"e,ious<-licC" "unat="se",e""BA ?as*Jbutton i!="/3Next" Text="Next" enable!="#alse" onclicC="Next<-licC" "unat="se",e""BA ?in*ut i!="/36eset" t'*e=""eset" !isable!="t"ue" "unat="se",e""BA ?Bt!A
The 'e$s to the functionalit$ of the registration wiGard are the three Panel controls and the Ne$t0=lick and Pre%ious0=lick e%ent handlers. The Panel controls contain <abel) Te$t2o$) and 2utton &e# controls ?as well as an Ktml"nput2utton control for resetting the form fieldsA) which are formatted using standard <TM. ta#le elements. &hen the user clic's the Ne1t #utton or the Pre%ious #utton ?de"ending on which one is ena#led for that "ageA) the e%ent handlers hide the currentl$ %isi#le "anel) show the ne1t ?or "re%iousA "anel) and u"date the <abel controls that tell the user which ste" in the "rocess the$ are on currentl$. Since ASP.NET ta'es care of maintaining the state of the controls from re(uest to re(uest ?using ViewStateA) it is sim"le to dis"la$ the data entered #$ the user on the third "anel #$ sim"l$ accessing the Te$t "ro"ert$ of the Te$t2o$ controls on the other "anels. Notice that the ca"tion te1t of the controls on the third "anel is set declarati%el$ in the tag) and then the te1t that the user entered is a""ended to this te1t "rogrammaticall$ in the e%ent handler using the _ o"erator. The first "age of the registration wiGard is shown in the following illustration.
NOTE The :style; #loc' defined in 7eg&iG.as"1 ta'es care of formatting for the Panel controls #$ defining the desired st$le for the :di%; <TM. element. Note that since the Panel control is rendered as a :di%; on 3nternet E1"lorer and as a :table; element on Netsca"e and other nonT 3nternet E1"lorer #rowsers) $ou might need to find another wa$ to do the formatting if $ou want cross/#rowser com"ati#ilit$. *ne wa$ to accom"lish this is through #rowser sniffing. The .e4uest o#;ect e1"osed #$ the Page class has a 2rowser "ro"ert$ that "ro%ides information on the #rowser ma'ing the current re(uest. B$ (uer$ing the 2rowser "ro"ert$ ?and its su#"ro"ertiesA) $ou can "erform a sim"le if statement that lin's to one st$le sheet if the #rowser is 3nternet E1"lorer and to another st$le sheet if it is another #rowser.
S"ecialt$ ,ontrols
3n addition to the standard suite of &e# controls that "ro%ide functionalit$ much li'e that "ro%ided #$ the Visual Basic @93 controls) ASP.NET offers a set of richer s"ecialt$ controls that reside in the System. eb.!". eb=ontrols names"ace. ,urrentl$ these controls include the /d.otator) =alendar) and Xml controls. 3n this section 3+ll descri#e the "ur"oses of these controls and show some e1am"les.
$d0otator
The /d.otator control is used to dis"la$ a random selection from a collection of #anner ad%ertisements s"ecified in an -M./#ased ad%ertisement file. The ad%ertisement file contains an :/d; element for each s"ecified ad%ertisement. This element contains su#/elements that configure the "ath to the image to dis"la$ for the ad) the 97. to na%igate to when the ad is clic'ed) the te1t to #e dis"la$ed when and if the image is not a%aila#le) the "ercentage of time the ad should come u" in rotation) and an$ 'e$word associated with the ad. ?You can use 'e$words to filter ads) allowing the use of a single ad%ertisement file with multi"le /d.otator controls and "ro%iding each control with different content.A NOTE The random selection for the /d.otator control will #e identical for an$ /d.otator controls on the "age that ha%e identical attri#utes. You can ta'e ad%antage of this #$ using the /d.otator control to dis"la$ a random selection of headerEfooter information that $ou want to #e the same for #oth header and footer.
:. ?b"BA?b"BA E. ?as*Jlabel i!="%e,Label" #ont5na&e="Ve"!ana" #ont5siDe="1:" F. G. ?b"BA 1H. ?as*J0!6otato" i!="0!6ot%e," ta")et="<blanC" "unat="se",e"" 11. a!,e"tise&ent#ile="0!s.x&l" Ce'1o"!#ilte"="%e,elo*e"s"BA text="0! 1" "unat="se",e""BA
1$. ?b"BA?b"BA 13. ?as*Jlabel i!="=se"Label" #ont5na&e="Ve"!ana" #ont5siDe="1:" 14. 18. ?b"BA text="0! $" "unat="se",e""BA
2K. ,reate a new -M. file #$ right/clic'ing the ,ha"terO D "ro;ect in Solution E1"lorer) selecting Add) then Add New 3tem) and then choosing -M. File as shown in the following illustration. T$"e the name of the file as Ads.0%l.
2D. Add the following -M. to the file) and then sa%e Ads.1ml=
1G. ?0!,e"tise&entsA $H. $1. $$. $3. $4. $8. $:. $E. ?0!A ?(&a)e="lAi&a)esBi&a)e1.)i#?B(&a)e="lA ?Na,i)ate="lA+tt*JBB111.&ic"oso#t.co&?BNa,i)ate="lA ?0lte"nateTextA7ic"oso#t 7ain .ite?B0lte"nateTextA ?(&*"essionsA:H?B(&*"essionsA ?[e'1o"!A=se"s?B[e'1o"!A ?B0!A ?0!A
$F. $G. 3H. 31. 3$. 33. 34. 38. 3:. 3E. 3F. 3G. 4H. 41. 4$. 43. 44. 48. 4:. 4E. 4F.
?(&a)e="lAi&a)esBi&a)e$.)i#?B(&a)e="lA ?Na,i)ate="lA+tt*JBB&s!n.&ic"oso#t.co&Bnet?BNa,i)ate="lA
?0lte"nateTextA7ic"oso#t .N T on 7.%N?B0lte"nateTextA ?(&*"essionsAFH?B(&*"essionsA ?[e'1o"!A%e,elo*e"s?B[e'1o"!A ?B0!A ?0!A ?(&a)e="lAi&a)esBi&a)e3.)i#?B(&a)e="lA ?Na,i)ate="lA+tt*JBB111.&ic"oso#t.co&?BNa,i)ate="lA ?0lte"nateTextA7ic"oso#t 7ain .ite?B0lte"nateTextA ?(&*"essionsA4H?B(&*"essionsA ?[e'1o"!A=se"s?B[e'1o"!A ?B0!A ?0!A ?(&a)e="lAi&a)esBi&a)e4.)i#?B(&a)e="lA ?Na,i)ate="lA+tt*JBB&s!n.&ic"oso#t.co&Bnet?BNa,i)ate="lA ?0lte"nateTextA7ic"oso#t .N T on 7.%N?B0lte"nateTextA ?(&*"essionsA$H?B(&*"essionsA ?[e'1o"!A%e,elo*e"s?B[e'1o"!A ?B0!A ?B0!,e"tise&entsA
8C. ,reate a new folder in the "ro;ect) t$"ing its name as i%ages. ,o"$ the images contained in the images director$ of the "ractice files for ,ha"ter D to this new folder. Q . Sa%e and #uild the "ro;ect) and then #rowse Ad7otator.as"1. The out"ut should loo' similar to the following illustration. &hen $ou refresh the "age) $ou should see the ads change randoml$) #ased on the weightings set in the -M. file.
Cale"dar
The =alendar control is one of the richest and most fle1i#le of the s"ecialiGed controls) "ro%iding nearl$ ! "ro"erties for controlling the a""earance of the calendar. The =alendar control allows $ou to "ro%ide a calendar/#ased interface for choosing dates or for %iewing date/ related data. For e1am"le) $ou could (uer$ date data for a series of e%ents or a""ointments and then use a =alendar control to dis"la$ them #$ adding the dates to the calendar+s Selected,ates collection. &hen a user clic's on a selected date on the calendar) $ou could then dis"la$ additional information a#out the e%ent on that date. You could also allow users to s"ecif$ one or more dates for data entr$ #$ "ro%iding a =alendar control for them to clic'. The =alendar control su""orts selection of #oth single dates and date ranges ?#$ wee' or monthA. 9sing a =alendar control instead of a te1t #o1 for date entr$ can hel" "re%ent errors in con%erting the date entered #$ the user into a ,ate data t$"e for storage or mani"ulation.
!. Switch to <TM. %iew) and use the following code to add three <abel controls) two .adio2utton controls) two Te$tbo$ controls) and a =alendar control #etween the :form; tags. Note that the -roupName "ro"ert$ is used to ma'e the radio #uttons mutuall$ e1clusi%e.
4. ?as*Jlabel i!="title" text="-alen!a" 8. :. ?b"BA E. ?as*Jcalen!a" i!="-alen!a"1" "unat="se",e""BA F. ?b"BA G. ?as*J"a!iobutton i!=".ta"t6a!io" text=".ta"t %ate" 1H. )"ou*na&e="-+oose"" "unat="se",e""BA xa&*le"
11. ?as*J"a!iobutton i!=" n!6a!io" text=" n! %ate" 1$. 13. 14. ?b"BA 18. ?as*Jlabel i!=".ta"t%ateLabel" text=".ta"t %ate" "unat="se",e""BA 1:. ?as*Jtextbox i!=".ta"t%ate"" "unat="se",e""BA 1E. ?b"BA 1F. ?as*Jlabel i!=" n!%ateLabel" text=" n! %ate" "unat="se",e""BA ?as*Jtextbox i!=" n!%ate" "unat="se",e""BA )"ou*na&e="-+oose"" "unat="se",e""BA
2C. Sa%e the "age) then #uild the "ro;ect) and then #rowse the "age. The out"ut should loo' similar to the following illustration.
2 . Now $ou need to relate clic'ing on a date on the calendar to setting the te1t in the te1t #o1es. Switch #ac' to design %iew) and then dou#le/clic' the =alendar control. This will switch to the code/#ehind module for ,alendar.as"1 and will add the =alendar>0Selection=hanged e%ent handler. Add the following code to the e%ent handler=
$1. (# .ta"t6a!io.-+ecCe! = T"ue T+en $$. $3. $4. .ta"t%ate.Text = -alen!a"1..electe!%ate lse ' n!6a!io &ust be c+ecCe! n!%ate.Text = -alen!a"1..electe!%ate n! (#
2Q. Add the following code to the Page0<oad e%ent handler in the code/#ehind module to ta'e care of initialiGing the controls=
$:. (# Not /a)e.(s/ostBacC T+en
!2. Sa%e the "age and code/#ehind module) and then #uild the "ro;ect and #rowse ,alendar.as"1. At this "oint) $ou should #e a#le to use the calendar to set the %alue of #oth te1t #o1es. &hich te1t #o1 is set de"ends on which radio #utton is chec'ed. !2. At this "oint the calendar is fairl$ "lain) so let+s use some of the a%aila#le "ro"erties to li%en it u" a #it. Switch #ac' to ,alendar.as"1 and modif$ the :asp:calendar; tag to match the following code. Notice that $ou need to add a closing :/asp:calendar; tag so that $ou can use the child :titlestyle; tag to set attri#utes of the calendar+s TitleStyle "ro"ert$.
33. ?as*Jcalen!a" i!="-alen!a"1" 34. 38. 3:. 3E. 3F. 3G. 4H. bacCcolo"="li)+t)"a'" bo"!e"st'le=")"oo,e" bo"!e"1i!t+="8" bo"!e"colo"="blue" "unat="se",e""A ?titlest'le bacCcolo"="blue" #o"ecolo"="sil,e"" #ont5bol!="t"ue"BA ?Bas*Jcalen!a"A
82. Sa%e and #rowse the "age again. ?Because $ou onl$ changed the .as"1 file) $ou don+t need to re#uild the "ro;ect.A The out"ut should loo' similar to the following illustration.
Xml
The Xml control is a s"ecialt$ control that lets $ou dis"la$ -M. code in &e# Forms "ages. This is im"ortant #ecause raw -M. within an ASP.NET &e# Form will not #e dis"la$ed "redicta#l$. The Xml control can read -M. from a string) from a "ro%ided 97.) or from an o#;ect of t$"e System.Xml.Xml,ocument. 3n addition to sim"l$ dis"la$ing -M. from a gi%en source) the Xml control can a""l$ an -S. Transform document to the -M. to "erform formatting on the document. The -S. Transform can come from a 97.) or it can #e "ro%ided #$ an o#;ect of t$"e System.Xml.Xsl.XslTransform. The files -ml.as"1 and -ml.1slt) included with the "ractice files for this cha"ter) show how $ou can use the Xml control to dis"la$ the contents of the Ads.1ml document in an <TM. ta#le.
Another s"ecialiGed set of controls that reside in the System. eb.!". eb=ontrols names"ace are the Dalidation controls) which "erform %arious 'inds of %alidation on other controls. You can use Dalidation controls to do the following=
Ensure that re(uired fields are filled out Ensure that data entered #$ the user falls within a gi%en range Ensure that data entered #$ the user matches a s"ecific "attern ,om"are the %alues of two controls for a gi%en condition ?e(ualit$) greater than) and so onA or com"are the %alue of a control to a s"ecified %alue Ensure that all controls on a "age are %alid #efore su#mitting the "age
Shared Me%#ers
All Dalidation controls share a num#er of im"ortant "ro"erties and methods. These "ro"erties and methods are inherited from the 2aseDalidator class and include the following=
=ontrolToDalidate This "ro"ert$ sets or retrie%es a %alue of t$"e String that s"ecifies the in"ut control to %alidate.
,isplay This "ro"ert$ sets or retrie%es a %alue that determines how the error message for a Dalidation control will #e dis"la$ed. The %alue must #e one of the %alues s"ecified #$ the Dalidator,isplay enumeration. The default is Static.
Enable=lientScript This "ro"ert$ sets or retrie%es a Boolean %alue that determines whether client/side %alidation will #e "erformed. Ser%er/side %alidation is alwa$s "erformed with the Dalidation controls) regardless of this setting. The default is True.
Enabled This "ro"ert$ sets or retrie%es a Boolean %alue that determines whether the control is ena#led. The default is True.
Error9essage This "ro"ert$ sets or retrie%es a %alue of t$"e String that s"ecifies the error message to #e dis"la$ed if the in"ut from the user is not %alid.
1ore=olor This "ro"ert$ sets or retrie%es a %alue of t$"e =olor that re"resents the color of the error message s"ecified in the Error9essage "ro"ert$. The default is =olor..ed.
"sDalid This "ro"ert$ sets or retrie%es a Boolean %alue that signifies whether the control s"ecified #$ the =ontrolToDalidate "ro"ert$ "asses %alidation.
Dalidate This method causes the control on which it is called to "erform %alidation) and it u"dates the "sDalid "ro"ert$ with the result.
Ta#le D/2 lists the Dalidation controls a%aila#le in ASP.NET. Ta#le G3*. Dalidation =ontrols Co"trol Type =ompareDalidator urpose I#porta"t Me#2ers Performs %alidation of a =ontrolTo=ompare user/entered field with This "ro"ert$ sets or retrie%es a %alue of either a constant or t$"e String containing the name of the another user/entered field. control whose %alue will #e com"ared to The =ontrolTo=ompare the %alue of the control s"ecified #$ the and DalueTo=ompare =ontrolToDalidate "ro"ert$. "ro"erties are mutuall$ +perator e1clusi%e. 3f #oth are set) This "ro"ert$ sets or retrie%es a %alue the =ontrolTo=ompare that re"resents the t$"e of com"arison to "ro"ert$ ta'es "recedence. #e "erformed. The %alue must #e one of the %alues s"ecified #$ the Dalidation=ompare+perator enumeration. The default is E4ual. DalueTo=ompare This "ro"ert$ sets or retrie%es a %alue of t$"e String containing a constant %alue to which the %alue of the control s"ecified #$ the =ontrolToDalidate "ro"ert$ will #e com"ared. Performs customiGed Ser%erDalidate %alidation #ased on This e%ent is raised when ser%er/side de%elo"er/s"ecified logic. %alidation is to #e "erformed. Ma" the +nSer%erDalidate method in the Dalidation control tag to the desired ser%er/side e%ent handler to "erform
=ustomDalidator
Ta#le G3*. Dalidation =ontrols Co"trol Type urpose I#porta"t Me#2ers custom %alidation. =lientDalidation1unction This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the name of a client/side function with which to "erform client/side %alidation) if desired. .angeDalidator Performs %alidation of a user/entered field to ensure that the %alue entered is within a s"ecified range. 9a$imumDalue This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the ma1imum %alue of the range to %alidate against. 9inimumDalue This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the minimum %alue of the range to %alidate against. DalidationE$pression This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the regular e1"ression to %alidate against. "nitialDalue This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the initial %alue of the control to %alidate against. The default is an em"t$ string. 3f this "ro"ert$ is set to a string %alue) %alidation will fail for the control onl$ if the user/entered %alue matches the %alue of this "ro"ert$. ,isplay9ode This "ro"ert$ sets or retrie%es a %alue that determines the wa$ the control will #e dis"la$ed. The %alue must #e one of the %alues s"ecified #$ the DalidationSummary,isplay9ode enumeration. The default is 2ullet<ist. KeaderTe$t This "ro"ert$ sets or retrie%es a %alue of t$"e String containing the header te1t to #e dis"la$ed for the %alidation summar$. Show9essage2o$ This "ro"ert$ sets or retrie%es a Boolean
.egularE$pressionDalidator Performs %alidation of a user/entered field to ensure that the %alue entered matches a s"ecified "attern. .e4uired1ieldDalidator Performs %alidation of a user/entered field to ensure that a %alue is entered for the s"ecified field.
DalidationSummary
Pro%ides a summar$ of %alidation errors in a gi%en &e# Form) either in the &e# Form "age) a message #o1) or #oth.
Ta#le G3*. Dalidation =ontrols Co"trol Type urpose I#porta"t Me#2ers %alue that determines whether the %alidation summar$ is dis"la$ed in a client/side message #o1. The default is 1alse. This "ro"ert$ has no effect if the Enable=lientScript "ro"ert$ is set to 1alse. ShowSummar$ This "ro"ert$ sets or retrie%es a Boolean %alue that determines whether the %alidation summar$ is dis"la$ed in the &e# Form "age. The default is True.
.e4uired1ieldDalidator> =ontrolToDalidate Te$t2o$> .e4uired1ieldDalidator> ,isplay .e4uired1ieldDalidator> Error9essage .e4uiredH !. Sa%e the "age and #rowse it with 3nternet E1"lorer using the Browse &ith o"tion. ?Again) since $ou ha%e changed onl$ the .as"1 file) the "ro;ect does not need to #e re#uilt.A 3f $ou do not enter a To address) the out"ut will loo' something li'e the following illustration) and $ou will not #e a#le to su#mit the "age.
*ne "ro#lem with this setu" is that once $ou add a To address and su#mit the "age) $ou might get a Fa%aScri"t error. This is #ecause the newl$ added Dalidation control is loo'ing for the te1t #o1 on the client) #ut since $ou hid the control in the e%ent handler #$ setting its Disible "ro"ert$ to 1alse) the control no longer e1ists on the client. You can sol%e this #$ modif$ing how $ou hide the elements on the "age) as $ou+ll see in the ste"s that com"lete this e1am"le. 8. Add a new <abel control for $our status message. ?3n the original "age) the first la#el in the ta#le was used for this "ur"ose.A This control should go ;ust #efore the <TM. :table; element.
?as*Jlabel i!=".tatus" text="" "unat="se",e""BA
Q. Turn the <TM. :table; element into an KtmlTable control #$ adding an id attri#ute ?if necessar$I otherwise) ;ust modif$ the id attri#ute to match the code sni""et that followsA and then switch to design %iew) right/clic' the ta#le #order) and select 7un As Ser%er ,ontrol=
?table i!="7ailTable" "unat="se",e""A
6. Switch to code %iew and ta'e out the line of code in the 2utton>0=lick e%ent handler that sets the status message and re"lace it with the following code=
E. '=se t+e #i"st label to !is*la' status .tatus.Text = "7ail .ent"
D. 7e"lace the lines of code in the 2utton>0=lick e%ent handler that set the Disible "ro"ert$ of the controls to 1alse with the following lines=
G. 'Hi!e t+e table 7ailTable.Visible = False
2 . Sa%e the "age) #rowse it) and su#mit an e/mail. You should no longer get the Fa%aScri"t error ?and $our code+s a lot cleaner to #ootA. 3n addition to using the .e4uired1ieldDalidator to ensure that an e/mail address is entered) $ou could add a .egularE$pressionDalidator to each of the addressfields to ensure that the data entered #$ the user matches the "attern for a %alid e/mail address. This "re%ents deli%er$ errors that are due to malformed e/mail addresses and hel"s "re%ent the mail ser%er+s resources from #eing wasted attem"ting to deli%er such mail. A good "lace to find regular e1"ressions for use with the 7egularE1"ressionValidator control is http://www.rege$lib.com/.
Validating #$ ,om"arison
Another one of the "re%ious e1am"les with the "otential for trou#le is the =alendar control e1am"le. As coded in the e1am"le) the =alendar control can #e used to set a start date that is later than the end date. ,learl$) if $ou+re storing these dates or using them to dri%e some "rogrammatic logic) this is not something $ou want to allow. Fortunatel$) the =ompareDalidator control can hel" "re%ent this "ro#lem) as illustrated #$ the following e1am"le.
Co"trol
roperty
Value
=ompareDalidator> Error9essage Start ,ate must be before End ,ateT !. 7ight/clic' an em"t$ area of the "age and select View ,ode to switch to the code/#ehind module) and then add a line of code to the =alendar>0Selection=hanged e%ent handler to cause the Dalidation control to %alidate each time the e%ent handler is fired. The Page.Dalidate call should go #etween the End "f and End Sub statements=
/a)e.Vali!ate23
8. Sa%e the file and code/#ehind module) and then re#uild the "ro;ect. Browse the "age and set the end date to a date earlier than the start date. The %alidation error message will a""ear) as shown in the following illustration. Additionall$) the "sDalid "ro"ert$ of the "age will #e set to 1alse. You can test this "ro"ert$ #efore sa%ing the date %alues to ensure that the$ are %alid.
Validation controls can also im"ro%e the securit$ of $our a""lication. For e1am"le) $ou can use the .egularE$pressionDalidator control to ensure that "asswords entered #$ users ?such as when esta#lishing account informationA meet minimum length and com"le1it$ re(uirements. This can ma'e it more difficult for the #ad gu$s to crac' $our a""lication.
0ata/Bound ,ontrols
*ne of the most significant ad%ances in ASP.NET is in the area of data #inding. The System. eb.!". eb=ontrols names"ace contains a set of data/#ound controls that offer su#stantial functionalit$ and fle1i#ilit$) without the necessit$ of t$ing front/end 93 logic into #ac'/end data#ase logic) as was the case with the data/#ound 0esign/Time ,ontrols a%aila#le in classic ASP through the Microsoft Visual 3nter0e% 6. de%elo"ment en%ironment. The data/ #ound controls also allow $ou to "ro%ide data #inding regardless of the #rowser that $our clients are using. This is #ecause the controls run on the ser%er and return "lain <TM. to the client) unli'e some of the data/#inding techni(ues that were "ossi#le with 3nternet E1"lorer %ersions 8. and later. Another ma;or im"ro%ement is that the data/#ound controls can use a %ariet$ of sources) not ;ust data from a data#ase. 0ata/#ound controls in ASP.NET can #e #ound to data from an arra$) an A0*.NET 0ataSet) a 0ataView) or an$ data source that im"lements the 3,ollection or 3.ist interfaces. The data/#ound controls include the ,ata-rid) ,ata<ist) and .epeater controls. 3n ,ha"ter C $ou+ll learn more a#out these controls.
The new controls included s"ecificall$ for mo#ile include the following=
1orm The 1orm control acts as a container for other mo#ile controls. You can ha%e multi"le forms on a mo#ile &e# Forms "age) #ut forms cannot #e nested. 9se the Panel control for nesting content or controls.
Te$tDiew
Similar to a <abel control) the Te$tDiew control is used to dis"la$ larger amounts of te1t and su""orts mar'u" tags within the te1t content.
=ommand The =ommand control is the mo#ile e(ui%alent of a 2utton control) and it renders a de%ice/ a""ro"riate 93 element to allow "osting #ac' of a mo#ile &e# Forms "age.
<ink The <ink control) which is similar to the ASP.NET Kyperlink control) "ro%ides a lin' to another 1orm control on the "age) or to a 97..
<ist The <ist control is a control that renders a list of items and can #e data#ound.
Selection<ist The Selection<ist control is similar to the <ist control #ut "ro%ides the a#ilit$ to select one or more items from the list.
+b*ect<ist The +b*ect<ist control dis"la$s multi"le fields "er item in a gi%en list of o#;ects. This control can #e data#ound to a ,ataSet or ,ataDiew) as well as to collections or arra$s.
,e%iceSpecific The ,e%iceSpecific control "ro%ides a means of s"ecif$ing multi"le content alternati%es. The content dis"la$ed is de"endent on the de%ice "rofiles s"ecified within the ,e%iceSpecific control.
To see how the ASP.NET mo#ile controls wor') let+s re/create the 4Fa%orite 3ce ,ream5 "age using the mo#ile controls.
&hen the "ro;ect is created) the default "age) Mo#ile&e#Form2.as"1) will #e o"ened in the Visual Studio editor. The "age will contain one 1orm control) as shown in the following illustration.
2. Add a <abel control) a Selection<ist control) and a =ommand control ?in that orderA to the e1isting form. !. Set the Te1t "ro"ert$ of the <abel control to !hat"s ) ur fa& rite ice crea%@) and the Te$t "ro"ert$ of the =ommand control to Enter. &hen finished) the form should loo' li'e the following illustration.
8. Select the Select<ist control) then scroll down in the Pro"erties window to find its "tems "ro"ert$ and highlight it. ,lic' the elli"sis #utton to o"en the Pro"erties dialog #o1 for the control. 9sing the ,reate New 3tem #utton) create three items) and set the te1t and %alue of each #$ t$"ing 'h c late) Straw#err)) and Vanilla) res"ecti%el$. &hen finished) the dialog #o1 should loo' li'e the following illustration. ,lic' *> to close the dialog #o1.
Q. Press FK to switch to the code/#ehind module for the "age. Add the following code to the Page0<oad e%ent handler=
(# Not (s/ostBacC T+en .electionList1.(te&s.0!!2"/istac+io"3 .electionList1.(te&s.0!!2"6ocC' 6oa!"3 '4e !on't liCe .t"a1be""' .electionList1.(te&s.6e&o,e2".t"a1be""'"3 n! (#
6. Switch #ac' to Mo#ile&e#Form2.as"1) and dou#le/clic' the =ommand control. This will add the =ommand>0=lick e%ent handler to the code/#ehind module. Add the following code to the e%ent handler=
E. Label1.Text = ">ou" #a,o"ite is " & < .electionList1..election.Text & "!"
D. Sa%e the o"en files and #uild the "ro;ect. You can test $our wor' using the standard #uilt/in #rowser) #ut that+s not terri#l$ useful in telling $ou how it will loo' on a cell "hone or P0A. A #etter #et is to use either the actual de%ice $ou+re de%elo"ing for or an emulator for that de%ice. Emulators are often a%aila#le from the
manufacturer of the de%ice $ou+re de%elo"ing for. The following illustration shows the initial out"ut of the "re%ious e1am"le on the Poc'etP, 2 2 Emulator.
3f $ou selected 7oc'$ 7oad from the list #o1 and then "ress Enter) the out"ut would loo' li'e the following illustration.
The following screen shots show how the same Mo#ile &e# Form would a""ear on a mo#ile "hone ?or) in this case) the *"en&a%e "hone emulator) a%aila#le at http://de%eloper.openwa%e.com/d%l/A. The illustration #elow shows the initial out"ut.
"mage courtesy of +penwa%e Systems "nc. 3f $ou selected 7oc'$ 7oad from the list) the out"ut would loo' li'e the following illustration.
Add or modif$ the attri#ute #$ its name using the /ttributes collection of the control= 9y=ontrol./ttributesE6/ttribute7F. Note that all attri#utes) including those e1"osed as "ro"erties on a control) are a%aila#le %ia the /ttributes collection.
Set the Style or =ss=lass ?&e# controls onl$A of the control to the desired ,SS st$le or class string. Add a Dalidator ser%er control to the "age) and set its =ontrolToDalidate "ro"ert$ to the 30 of the control the user will use to enter in"ut. The t$"e of control to use de"ends on what $ou want to %alidate.
,onnect to a data#ase using A0*.NET. 9se ASP.NET data/#ound controls to dis"la$ and edit data. 9se the ,ata-rid) ,ata<ist) and .epeater controls.
3n the "re%ious two cha"ters) $ou learned a#out creating &e# Forms and ta'ing ad%antage of ASP.NET ser%er controls in $our &e# Forms a""lications. &ith that o%er%iew of these two im"ortant technologies under $our #elt) let+s loo' at data access. The a#ilit$ to store and access data is central to most &e# a""lications) and this is an area that classic ASP made %er$ sim"le for de%elo"ers through the Acti%e- 0ata *#;ects ?A0*A ,*M com"onents. The Microsoft .NET "latform "ro%ides a set of classes called A0*.NET that is the logical successor to A0*) although the underl$ing o#;ect model has undergone significant changes. ASP.NET) meanwhile) e1"oses a set of data/#ound controls ?which 3 touched on #riefl$ in ,ha"ter DA that integrate seamlessl$ with A0*.NET to "ro%ide data/#inding ser%ices. IMPORTANT A0*.NET is a large enough to"ic to merit a #oo' of its own) so at #est this cha"ter will "ro%ide an o%er%iew. 3 strongl$ encourage $ou to use the a%aila#le resources) such as the ASP.NET and <owTo :uic'Start tutorials ?installed with the Microsoft .NET Framewor' S0> sam"lesA) which ha%e numerous A0*.NET e1am"les. *ther resources include the .NET Framewor' S0> and Microsoft Visual Studio .NET documentation) and of course other #oo's) such as /,+.NET Step by Step #$ 7e#ecca M. 7iordan ?Microsoft Press) 2 2A) and 2uilding eb Solutions with /SP.NET and /,+.NET ?Microsoft Press) 2 2A #$ 0ino Es"osito) a noted e1"ert on A0* and A0*.NET.
Understanding A6O.NET
3n classic ASP) the most common wa$ to access data was through A0*. 0e%elo"ers used A0* =onnection o#;ects to connect to a data#ase) and then used A0* =ommand and .ecordset o#;ects to retrie%e) mani"ulate) and u"date data. &hen designing a""lications) "articularl$ those with high scala#ilit$ re(uirements or those whose #ac'/end datasource might change at some "oint) de%elo"ers needed to #e careful not to tie in their front/end "resentation code with their #ac'/end data#ase. *therwise) the$+d end u" ha%ing to rewrite e%er$thing if there was a change in the #ac'/end data#ase. The A0*.NET class architecture is factored somewhat differentl$ from classic A0*. A0*.NET classes are se"arated into two ma;or categories= datasource/s"ecific and non/datasource/s"ecific.
The S4l=onnection class is used to esta#lish a connection to a S:. Ser%er data#ase. 9nli'e the A0* =onnection o#;ect) the S4l=onnection class ?or its *.E 0B e(ui%alent) the +le,b=onnection classA cannot #e used to e1ecute S:. statements against a datasource. The S4l=onnection class is used solel$ for o"ening connections) setting or retrie%ing "ro"erties of a connection) or handling connection/related e%ents. You+ll learn how to use the S4l=onnection class to connect to a data#ase later in this cha"ter. The S4l=ommand class is used to e1ecute S:. statements or stored "rocedures against a S:. Ser%er data#ase. The S4l=ommand class ?and its *.E 0B e(ui%alent) the +le,b=ommand classA can e1ecute statements or stored "rocedures that do not return %alues) or that return single %alues) -M.) or datareaders. The S4l,ata.eader class "ro%ides forward/onl$) read/onl$ access to a set of rows returned from a S:. Ser%er data#ase. 0atareaders ?including #oth the S4l,ata.eader and +le,b,ata.eaderA "ro%ide lightweight) high/"erformance access to read/onl$ data and are the #est choice for accessing data to #e dis"la$ed in ASP.NET. The S4l,ata/dapter class is used as a #ridge #etween the ,ataSet class and S:. Ser%er. You can use the S4l,ata/dapter class to create a dataset from a gi%en S:. statement or stored "rocedure re"resented #$ a S4l=ommand instance) to u"date the #ac'/end S:. Ser%er data#ase #ased on the contents of a dataset) or to insert rows into or delete rows from a S:. Ser%er data#ase. The +le,b/dapter class "erforms the same tas's for *.E 0B datasources.
IMPORTANT You might ha%e noticed that in the discussion of the classes that ma'e u" the S:. Ser%er .NET 0ata Pro%ider) the names of the classes start with S4l rather than S#<. This is #ecause the names of the classes in the .NET Framewor' use Pascal casing ?after the st$le of the Pascal languageA) in which the first character of each distinct word in a gi%en class is ca"italiGed. This naming con%ention is es"eciall$ im"ortant #ecause $ou must declare class and names"ace names with the "ro"er case when using a case/sensiti%e language such as ,J. 9sing the incorrect case name ?for e1am"le) S#<=onnection instead of S4l=onnectionA will result in a com"iler error. So if $ou get an error com"laining that the t$"e isn+t defined or the names"ace doesn+t e1ist) $ou+re "ro#a#l$ dealing with a ca"italiGation "ro#lem. But e%en in a language that isn+t case sensiti%e) such as Visual Basic .NET) using the "ro"er case for names"aces and classes will result in code that+s easier to read and maintain.
9nderstanding 0atasets
The main class not s"ecific to a datasource is the ,ataSet class. This is essentiall$ an in/memor$ re"resentation of one or more ta#les of data. This data can #e read from an -M. file or stream) or it can #e the result of a (uer$ against a datasource. *ne im"ortant thing a#out the ,ataSet class is that it doesn+t 'now an$thing a#out the datasource from which it recei%es its data) other than what that data is and sometimes the t$"es of the data columns. ?See the section on t$"ed datasets later in this cha"ter.A The following illustration shows the ma;or classes associated with the ,ataSet class and how the$ relate to one another. Note that the .ows) =olumns) and =onstraints o#;ects are "ro"erties of the ,ataTable class.
The fact that a dataset 'nows nothing a#out the source of its data means that it+s a#stracted from the #ac'/end datasource. This is im"ortant #ecause it means that if $ou "ass a dataset from a com"onent used for data retrie%al to $our &e# Forms "age to #e used for data/#inding) $our &e# Forms "age neither 'nows nor cares where the data comes from) as long as the dataset structure remains the same. You can change the #ac'/end data#ase without necessitating an$ changes in the &e# Forms "age) ma'ing it much easier to maintain a &e# a""lication.
0atasets contain a collection of ta#les) each of which contains a collection of rows) a collection of columns) and a collection of constraints. You can use these collections to get information on the o#;ects contained within them) as well as to access and u"date indi%idual data %alues. The dataset can also contain a collection of relationshi"s #etween the ta#les it contains) allowing hierarchical data to #e re"resented. You+ll learn a#out the ,ataSet class and related classes in detail later in this cha"ter. IM: in A6O.NET 9nli'e classic A0*) in which -M. su""ort was added after the initial o#;ect model had #een created) -M. su""ort has #een designed into the A0*.NET model from the ground u". ,lasses such as S4l=ommand) +le,b=ommand) and ,ataSet ha%e #uilt/in su""ort for reading and writing -M. data. 0atasets in "articular can #e #uilt from or sa%ed as -M.) ma'ing them ideal for trans"orting data #etween tiers in a multi/tier a""lication or for tem"oraril$ storing data to dis' for later retrie%al.
S4lCo""ectio"
For a""lications that use S:. Ser%er as the #ac'/end data#ase and are unli'el$ to change to a different data#ase in the future) the S4l=onnection class is the a""ro"riate choice. This class is o"timiGed for the #est "erformance when connecting to a S:. Ser%er data#ase. The S4l=onnection class will also "ro%ide su"erior "erformance when accessing data in an MS0E data#ase) since MS0E uses the same data#ase engine and "rotocols as S:. Ser%er. ,reating a S4l=onnection class is sim"le and can #e done in one line of code=
%i& &'.@l-onn as Ne1 .@l-onnection27'-onnection.t"in)3
This creates a connection called m$S(l,onn to the S:. Ser%er s"ecified #$ the M$,onnectionString "arameter "assed to the constructor of the S(l,onnection class. *"ening the connection is as sim"le as calling the following=
&'.@l-onn.9*en23
&'.@l-onn.-lose23
IMPORTANT As with classic A0*) it is %er$ im"ortant that $ou close an$ connection $ou o"en when $ou are finished with it. ,onnections are not closed automaticall$ when the$ go out of sco"e. *"en connections are not returned to the connection "ool) where the$ would #e a%aila#le to other clients. .ea%ing connections o"en can "re%ent $our a""lication from effecti%el$ handling larger num#ers of users without unacce"ta#le "erformance degradation. 3n addition to setting the connection string #$ "assing it to the constructor of the S4l=onnection instance) $ou can also create the S4l=onnection instance with no constructor argument and set the connection string later through the =onnectionString "ro"ert$. The connection string for S4l=onnection consists of 'e$E%alue "airs se"arated #$ semicolons. You can delimit %alues #$ using either single or dou#le (uotes) #ut $ou cannot use #oth for the same %alue. ?For e1am"le) 'e$M^%alue+s\ should #e 'e$M4%alue+s5.A All s"aces e1ce"t those a""earing in (uotes are ignored. IMPORTANT &hen $ou+re creating connection strings d$namicall$ #ased on user in"ut) ma'e sure to %alidate user in"ut so that additional 'e$s are not intentionall$ added to the connection string #$ the user. For e1am"le) a malicious user could add the data#ase 'e$ to his "assword in an attem"t to connect to a different data#ase. Since the last 'e$ with the same name will #e used to set the %alue for a connection string) failure to %alidate in"ut can result in ina""ro"riate access. Ta#le C/2 lists the %alid 'e$s for a S4l=onnection connection string. Ta#le H34. S4l=onnection =onnection String Leys 6ey /pplication Name Descriptio" The name of the a""lication from which the connection is #eing made.
/ttach,21ilename The filename and full "ath to the "rimar$ file of an attacha#le data#ase. This 'e$ re(uires the ,atabase 'e$ to s"ecif$ the data#ase name. =onnect Timeout or =onnection Timeout =onnection <ifetime The num#er of seconds #efore an attem"ted connection is a#orted and an error is raised. The default is >).
The time) in seconds) that a "ooled connection should remain ali%e. &hen a connection is returned to the connection "ool) it is destro$ed if the current time is more than this man$ seconds "ast its creation time. The default is Q) meaning that the connection will not #e destro$ed. A Boolean %alue that determines whether the connection state is reset when a connection is retrie%ed from the "ool. 3f this 'e$ is set to 1alse) the
=onnection .eset
Ta#le H34. S4l=onnection =onnection String Leys 6ey Descriptio" connection state will not #e reset) which sa%es a tri" to the ser%er. But the "rogrammer must then manuall$ ta'e an$ ste"s necessar$ to ensure that the connection state is a""ro"riate for the a""lication+s use. The default is True. =urrent <anguage The S:. Ser%er language name. ,ata Source or Ser%er or /ddress or /ddr or Network /ddress Enlist "nitial =atalog or ,atabase "ntegrated Security or Trusted =onnection 9a$ Pool Si3e 9in Pool Si3e Network <ibrary or Net The ser%er name or networ' address of the S:. Ser%er instance to connect to.
0etermines whether the connection is automaticall$ enlisted in the creator+s current transaction conte1t. The default is True. The name of the data#ase to connect to.
0etermines whether the connection uses the &indows authentication credentials of the caller to authenticate against S:. Ser%er. Setting this to True alle%iates the need for authenticating a user 30 and "assword) which means that $ou don+t need to worr$ a#out storing these %alues. The default is 1alse. 0etermines the ma1imum num#er of connections to #e "ooled. The default is >QQ. 0etermines the minimum num#er of connections that should #e in the "ool. The default is Q. S"ecifies the networ' li#rar$ to use when connecting to the s"ecified S:. Ser%er. The default is dbmssocn) which s"ecifies the T,PE3P soc'ets li#rar$. *ther %alid %alues are dbnmpntw Named "i"es dbmsrpcn Multi"rotocol dbmsadsn A""le Tal' dbmsgnet V3A dbmsipcn Shared memor$ dbmssp$n 3P-ESP-. The ser%er must ha%e the a""ro"riate 0.. for the s"ecified networ' li#rar$. S"ecifies the num#er of #$tes "er networ' "ac'et to use in communicating with S:. Ser%er. The default is V>R(. S"ecifies the "assword to use to log into the S:. Ser%er data#ase.
Ta#le H34. S4l=onnection =onnection String Leys 6ey Pwd Persist Security "nfo Pooling 3f set to 1alse) this 'e$ "re%ents sensiti%e information) such as "asswords) from #eing returned as a "art of the connection if the connection is o"en. The default is 1alse. 0etermines whether "ooling is ena#led for this connection. &hen True) a re(uested connection will #e "ulled from the a""ro"riate "ool. 3f no connections are a%aila#le from the "ool) the re(uested connection is created and then returned to the "ool when closed. The default is True. The name of the S:. Ser%er user account with which to log into the ser%er. The name of the machine connecting to S:. Ser%er. The default is the local machine name. Descriptio"
1leD2Co""ectio"
For a""lications that need to #e a#le to (uer$ data#ases other than S:. Ser%er) such as Microsoft Access or *racle) the +le,b=onnection class is the a""ro"riate choice. This class uses a standard *.E 0B Pro%ider string to connect to an$ *.E 0B datasource through the *.E 0B "ro%ider for that datasource. ,reating an +le,b=onnection class is sim"le and can #e done in one line of code=
%i& &'9le%b-onn as Ne1 9le%b-onnection27'-onnection.t"in)3
This creates a connection called m$*le0#,onn to the data#ase s"ecified #$ the M$,onnectionString "arameter "assed to the constructor of the *le0#,onnection class. The ,onnectionString argument is a standard *.E 0B "ro%ider string. The following) from the MS0N .NET Framewor' ,lass .i#rar$ 7eference) shows some e1am"les of *.E 0B Pro%ider strings for connecting to *racle) Access) and S:. Ser%er datasources) res"ecti%el$=
/"o,i!e"=7.%0960O %ata .ou"ce=960-L FiEO =se" (%=9L %BO/ass1o"!=9L %BO
The Pro%ider5 clause is re(uired. You can also use other clauses su""orted #$ the "articular *.E 0B "ro%ider to set other "ro"erties for the "ro%ider. For e1am"le) the "nitial =atalog5
clause is used #$ the S:. Ser%er *.E 0B Pro%ider to indicate the data#ase against which (ueries will #e run. NOTE &ith the integration of data "ro%iders for *racle and *0B, data sources into the .NET Framewor') $ou should use those data "ro%iders) rather than the *.E 0B data "ro%ider) when accessing *racle or *0B, data.These "ro%iders are o"timiGed for this "ur"ose and are more efficient than attem"ting to use the .NET Framewor' 0ata Pro%ider for *.E 0B along with the *.E 0B "ro%ider for the s"ecific data#ase t$"e. You o"en the connection #$ calling the following=
&'9le%b-onn.9*en23
.ater in this cha"ter) $ou+ll see e1am"les of using connections to "erform data access. NOTE Most of the discussion and e1am"les in this cha"ter use either the .NET Framewor' 0ata Pro%ider for S:. Ser%er or the .NET Framewor' 0ata Pro%ider for *.E 0B. 9sing other data "ro%iders is similar) although $ou might find minor differences in the S:. s$nta1 used to (uer$ a gi%en data#ase. For more information on the s"ecifics of a gi%en data "ro%ider) refer to the MS0N documentation for Visual Studio .NET 2 !) which contains detailed documentation and e1am"les for all of the .NET Framewor' 0ata Pro%iders.
9se &indows authentication and im"ersonation to connect to the data#ase using the credentials of the logged/in user. Set u" the ASPNET account as a login in S:. Ser%er ?or an$ other data source that su""orts trusted connectionsA.
3n this section $ou+ll learn how to use the latter techni(ue to ena#le the use of trusted connections without the need for &indows authentication. IMPORTANT Setting u" the ASPNET account in S:. Ser%er will allow an$ ASP.NET a""lication on the &e#
ser%er to access the data#ase with whate%er "ri%ileges ha%e #een granted to the ASPNET account. For this reason) $ou should use this techni(ue onl$ on de%elo"ment s$stems or "roduction s$stems on which $ou are in control of all ASP.NET a""lications. This techni(ue should generall$ not #e considered for shared ser%er a""lications. There are a cou"le of wa$s to "ro%ide access to a data#ase for the ASPNET account) de"ending on the software $ou ha%e installed. 3f $ou ha%e the full %ersion of S:. Ser%er installed) $ou can use the gra"hical tool S:. Enter"rise Manager to add the ASPNET account as a S:. Ser%er login. 3f $ou ha%e onl$ MS0E installed) $ou will need to use the oS:. command/line utilit$ to "erform these tas's. You+ll learn #oth techni(ues in the following two sections.
9se the oS(l command/line tool to set u" the ASPNET account
2. Start the oS(l command/line utilit$ #$ entering the following code at a command "rom"t. ?3f $ou+re using a S:. Ser%er data#ase other than a local %ersion of the VSdotNET MS0E instance) enter that ser%er or instance name as the CS "arameter.A
o.@l 5.2local3QV.!otN T ]
You should see a 2S "rom"t if the command com"letes successfull$. 2. ,all the s"Ograntlogin s$stem stored "rocedure to grant login access to the ASPNET account. The s$nta1 should loo' li'e the following) with :domain; re"laced #$ $our domain or local machine name. The go command entered at the 2S "rom"t tells oS(l to e1ecute the stored "rocedure.
1A s*<)"antlo)in '<domain>Q0./N T' $A )o
!. ,all the s"Odefaultd# s$stem stored "rocedure to change the default data#ase for the ASPNET account to "u#s. NOTE The VSdotNET MS0E instance that shi"s with Visual Studio .NET does not automaticall$ install sam"le data#ases) including the Pu#s data#ase. See A""endi1 , for instructions on manuall$ adding the Pu#s data#ase to the VSdotNET MS0E instance. The s$nta1 should loo' li'e the following) with :domain; re"laced #$ $our domain or local machine name.
1A s*<!e#ault!b '<domain>Q0./N T', '*ubs' $A )o
8. ,all the s"Oadduser s$stem stored "rocedure to add the ASPNET login account to the "u#s data#ase) "assing the db0datareader argument to add the account to the d#Odatareader role. The s$nta1 should loo' li'e the following) with :domain; re"laced #$ $our domain or local machine name.
1A s*<a!!use" '<domain>Q0./N T', '0./N T', '!b<!ata"ea!e"' $A )o
Q. 3f desired) call the s"Oaddrolemem#er s$stem stored "rocedure to add the ASPNET account to the d#Odatawriter role. 3n this ste") ASPNET is the username added to the "u#s data#ase in the "re%ious ste". The s$nta1 should loo' li'e the following=
:. 1A s*<a!!"ole&e&be" '!b<!ata1"ite"', '0./N T' $A )o
K. T$"e e0it and "ress the Enter 'e$ to e1it the oS(l utilit$. *nce $ou+%e set u" the ASPNET account as descri#ed in the "receding ste"s) $ou should #e a#le to access the desired data#ase using a trusted connection) as shown in the connection strings used in the sam"les later in this cha"ter.
S4lCo##a"d
The S4l=ommand class is the a""ro"riate class to use when $ou want to run commands against a S:. Ser%er data#ase. Each of the following ste"s outlines one or more wa$s to initialiGe or use the S4l=ommand class.
'/assin) in a @ue"' %i& .NL 0s .t"in) = ". L -T au<i! F697 aut+o"s" %i& &'.@l-&!$ as Ne1 .@l-o&&an!2.NL3
'/assin) in a @ue"' an! a connection %i& -onn.t" 0s .t"in) -onn.t" = "!atasou"ce=local+ostQV.!otN TO!atabase=*ubsO" & < "inte)"ate!secu"it'=t"ue"
%i& &'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 %i& .NL 0s .t"in) = ". L -T au<i! F697 aut+o"s" %i& &'.@l-&!3 as Ne1 .@l-o&&an!2.NL, &'.@l-onn3
'/assin) in a @ue"', a connection, an! a t"ansaction %i& -onn.t" 0s .t"in) -onn.t" = "!atasou"ce=local+ostQV.!otN TO!atabase=*ubsO" & < "inte)"ate!secu"it'=t"ue"
%i& &'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 %i& &'.@lT"ans 0s .@lT"ansaction = &'.@l-onn.Be)inT"ansaction23 %i& .NL 0s .t"in) = ". L -T au<i! F697 aut+o"s" %i& &'.@l-&!4 as Ne1 .@l-o&&an!2.NL, &'.@l-onn, &'.@lT"ans3
2. 3f $ou ha%en+t set them in the constructor) set the =ommandTe$t "ro"ert$ to the desired S:. (uer$ or stored "rocedure name and set the =onnection "ro"ert$ to an o"en S4l=onnection o#;ect.
3. &'.@l-&!.-o&&an!Text = ". L -T au<i! F697 aut+o"s" 4. '0ssu&es t+at &'.@l-onn +as al"ea!' been c"eate! an! o*ene! &'.@l-&!.-onnection = &'.@l-onn
Q. ,all one of the following four methods that e1ecute the command. ?Note that the %alue of the =ommandTe$t "ro"ert$ will %ar$ de"ending on the method $ou call.A
:. '=se E. '% L T
o"
@ue"' 1+e"e t+at @ue"' t'*e +as been set usin) t+e
F. '-o&&an!Text *"o*e"t' G. &'.@l-&!. xecuteNonNue"'23 1H. 11. '=se xecute6ea!e" to execute a . L -T co&&an! an!
1$. '"etu"n a !ata"ea!e" 13. %i& &'.@l6ea!e" 0s .@l%ata6ea!e" = &'.@l-&!. xecute6ea!e" 14. 18. '=se xecute.cala" to execute a co&&an! an! "etu"n t+e ,alue o#
1:. 't+e #i"st colu&n o# t+e #i"st "o1. 0n' a!!itional "esults 1E. 'a"e i)no"e!. 1F. %i& 6esult 0s 9bLect 1G. 6esult = &'.@l-&!. xecute.cala" $H. $1. '=se xecute^&l6ea!e" to execute a . L -T co&&an! an!
$$. '#ill a %ata.et usin) t+e "etu"ne! ^&l6ea!e" $3. %i& .NL 0s .t"in) $4. .NL = ". L -T U F697 aut+o"s F96 ^7L 0=T9, ^7L%0T0" $8. $:. %i& &'.@l-&! as Ne1 .@l-o&&an!2.NL, &'.@l-onn3 $E. %i& &'%. 0s Ne1 %ata.et23 $F. 7'%..6ea!^&l2&'.@l-&!. xecute^&l6ea!e"23, < ^&l6ea!7o!e.F"a)&ent3
2C. Ma'e sure to close the connection when $ou+re finished with it. The following e1am"le wal's $ou through creating the code necessar$ to retrie%e the contents of the Authors ta#le of the Pu#s sam"le S:. Ser%er data#ase as -M. and to dis"la$ that data in a &e# Forms "age. NOTE The data access sam"les in this #oo' are written to run against the MS0E sam"le data#ase
included with Microsoft Visual Basic .NET. For information on installing MS0E) see A""endi1 ,. 3f $ou want to run the data access sam"les against a S:. Ser%er data#ase other than the VSdotNET MS0E data#ase) or if $ou are una#le to use a trusted connection to S:. Ser%er or MS0E) $ou must modif$ the connection string in the e1am"les to match the a""ro"riate ser%er name and login credentials.
6. Scroll down to the Page0<oad e%ent handler and add the following code=
E. %i& -onn.t" 0s .t"in) F. -onn.t" = "!ata sou"ce=2local3QV.!otN TO " & < G. "!atabase=*ubsOinte)"ate! secu"it'=t"ue"
1H. '-"eate an! o*en t+e connection 11. 1$. %i& 7'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 13. 7'.@l-onn.9*en23 14. T"' 18. 1:. 1E. 1F. %i& &'.@l-&! 0s Ne1 .@l-o&&an!2.NL, 7'.@l-onn3 %i& .NL 0s .t"in) .NL = ". L -T U F697 aut+o"s F96 ^7L 0=T9, ^7L%0T0"
'Fill t+e !ataset usin) t+e ^7L "ea! #"o& 7.% B.NL .e",e" 7'%..6ea!^&l2&'.@l-&!. xecute^&l6ea!e"23, < ^&l6ea!7o!e.F"a)&ent3 ^&l%is*la'.%ocu&ent-ontent = 7'%..;et^&l23
2K. Sa%e the "ro;ect and #oth o"en files. 2D. Build the "ro;ect. 2C. Test the "age #$ right/clic'ing E1ecute-ml7eader.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
This e1am"le creates a S4l=onnection o#;ect that o"ens a connection to the Pu#s data#ase) creates a S:. (uer$ string to retrie%e the contents of the Authors ta#le as -M.) and creates a new S4l=ommand o#;ect) "assing in the S:. (uer$ and S4l=onnection o#;ect. Then it creates a dataset and uses the E$ecuteXml.eader method of the S4l=ommand o#;ect to "ass an Xml.eader o#;ect to the dataset+s .eadXml method) which allows the dataset to "o"ulate itself from the Xml.eader. Finall$) the code sets the ,ocument=ontent "ro"ert$ of the declared Xml ser%er control to the result of the -etXml method of the dataset. The Xml control uses the -S. Transformation document authors.1sl to format the -ml content dis"la$ed #$ the Xml control. IMPORTANT The code in Ste" 6 in the "re%ious e1am"le shows an im"ortant "attern when using data#ase connections. 3mmediatel$ after the call to +pen) $ou enter a Try #loc'. 3n the 1inally section) $ou close the connection. This ensures that the connection is closed) e%en if an e1ce"tion occurs in the code after the call to +pen. 3t+s also not a #ad idea to add =atch #loc's for e1ce"tions that might occur in connecting to and reading from the data#ase. This will ma'e $our data#ase code more ro#ust) which will ma'e $our users ha""ierH The following listing shows the content of authors.1sl.
0ut+o"s.xsl
?xslJst'les+eet ,e"sion='1.H' x&lnsJxsl='+tt*JBB111.13.o")B1GGGB^.LBT"ans#o"&'A ?xslJte&*late &atc+="B"A ?st'leA .+ea!e"Y#ont51ei)+tJbol!Ocolo"J1+iteObacC)"oun!5colo"JblacCOZ .,alueY#ont5#a&il'Ja"ialO#ont5siDeJ.Ee&ObacC)"oun!5colo"Jsil,e"Z ?Bst'leA ?table bo"!e"="1" cells*acin)="H" cell*a!!in)="1" bo"!e"colo"="blacC"A ?t" class="+ea!e""A ?t+A0ut+o" (%?Bt+A ?t+ALast Na&e?Bt+A ?t+AFi"st Na&e?Bt+A ?t+A/+one?Bt+A ?t+A0!!"ess?Bt+A ?t+A-it'?Bt+A ?t+A.tate?Bt+A ?t+AKi*?Bt+A ?t+A-ont"act?Bt+A ?Bt"A ?xslJ#o"5eac+ select='.c+e&a1Baut+o"s'A ?t"A ?t! no1"a*="t"ue" class=",alue"A ?bA ?xslJ,alue5o# select='Mau<i!' BA ?BbA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A
?xslJ,alue5o# select='Mau<lna&e' BA
?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='Mau<#na&e' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='M*+one' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='Ma!!"ess' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='Mcit'' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='Mstate' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='MDi*' BA ?Bt!A ?t! no1"a*="t"ue" class=",alue"A ?xslJ,alue5o# select='Mcont"act' BA ?Bt!A ?Bt"A ?BxslJ#o"5eac+A ?BtableA ?BxslJte&*lateA ?BxslJst'les+eetA
1leD2Co##a"d
For most "ur"oses) using the +le,b=ommand class is effecti%el$ the same as using the S4l=ommand class. 3nstead of connecting with the S4l=onnection class) $ou can ;ust use the +le,b=onnection class. *ne significant difference) howe%er) is that the +le,b=ommand class does not ha%e an E$ecuteXml.eader method. The following e1am"le assumes that $ou ha%e the Northwind.md# data#ase installed locall$= 2. ,reate and o"en an +le,b=ommand o#;ect with the a""ro"riate connection string for connecting to the Northwind data#ase) where :filepath; is the "ath to Northwind.md# on $our machine.
$. %i& -onn.t" 0s .t"in) 3. -onn.t" = "/"o,i!e"=7ic"oso#t.\et.9L %B.4.HO" 4. -onn.t" &= "%ata .ou"ce=?#ile*at+AQno"t+1in!.&!bO" 8. %i& &'9le%b-onn 0s Ne1 9le%b-onnection2-onn.t"3 &'9le%b-onn.9*en
6. ,reate a %aria#le to contain the S:. (uer$. ?Note that the (uer$ can also #e "assed as a literal string to the constructor of the +le,b=ommand class.A
%i& .NL 0s .t"in) = ". L -T -ount2U3 F697 *"o!ucts"
K. ,reate an +le,b=ommand o#;ect) "assing the S:. (uer$ and the connection o#;ect to the constructor.
%i& &'9le%b-&! as Ne1 9le%b-o&&an!2.NL, &'9le%b-onn3
D. ,reate a %aria#le to recei%e the return %alue from the command. This %aria#le is declared as t$"e +b*ect #ecause that is the return t$"e of the E$ecuteScalar method of the +le,b=ommand o#;ect.
%i& 6esult 0s 9bLect
C. ,all the E$ecuteScalar method of the +le,b=ommand o#;ect) and use the returned %alue. Note that $ou must cast the %alue to the correct t$"e #efore using it #ecause the returned t$"e is +b*ect. This is es"eciall$ im"ortant if $ou need to use methods of a "articular t$"e that are not im"lemented #$ +b*ect.
1H. 6esult = &'9le%b-&!. xecute.cala"23 Value.Text &= -T'*e26esult, .t"in)3
The following e1am"le shows how $ou would use the o#;ects in the +le,b names"ace to dis"la$ the returned result in a &e# Forms "age.
6. Scroll down to the Page0<oad e%ent handler and add the following code. This code assumes that a co"$ of the Northwind Microsoft Access sam"le data#ase e1ists in the same director$ as E1ecuteScalar.as"1=
E. %i& %b/at+ 0s .t"in) = .e",e".7a*/at+2"No"t+1in!.&!b"3 F. %i& -onn.t" 0s .t"in) G. %i& .NL 0s .t"in) 1H. -onn.t" = "/"o,i!e"=7ic"oso#t.\et.9L %B.4.HO " & < 11. "%ata .ou"ce=" & %b/at+ & "O"
1$. %i& 7'9le%b-onn 0s Ne1 9le%b-onnection2-onn.t"3 13. 7'9le%b-onn.9*en23 14. T"' 18. 1:. 1E. 1F. 1G. $H. .NL = ". L -T -ount2U3 F697 *"o!ucts" %i& 7'9le%b-o&&an! 0s Ne1 9le%b-o&&an!2.NL, 7'9le%b-onn3 %i& 6esult 0s 9bLect 6esult = 7'9le%b-o&&an!. xecute.cala"23 Value.Text = "T+e"e a"e " & 6esult.To.t"in)23 & < " *"o!ucts in t+e No"t+1in! !atabase."
2!. Sa%e the "age and code/#ehind module) and then #uild the "ro;ect.
28. Test the "age #$ right/clic'ing E1ecuteScalar.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
NOTE Although the "re%ious e1am"le uses Microsoft Access to demonstrate the a#ilit$ of the +le,b=ommand o#;ect to connect to nonTS:. Ser%er data#ases) $ou should generall$ a%oid using Access for ASP.NET a""lications. For initial "rotot$"ing and de%elo"ment) or for a""lications with minimal scala#ilit$ re(uirements ?u" to 2 or so concurrent users) de"ending on the acti%it$ generated #$ each userA) MS0E is the #etter choice. MS0E is a S:. Ser%erTcom"ati#le data#ase that is a%aila#le with a num#er of Microsoft "roducts) including S:. Ser%er) Microsoft *ffice) and Visual Studio. A %ersion of MS0E also comes with Visual Basic .NET Standard) as well as with the .NET Framewor' S0>) and it+s installed with and used to run the S0> sam"les) if $ou choose to install them. ?Please refer to ,ha"ter 6 for im"ortant guidance a#out installing sam"le a""lications.A MS0E is #uilt on the same data#ase engine as S:. Ser%er) #ut it+s tuned for a""ro1imatel$ fi%e concurrent users. The ad%antage of using MS0E is that all of $our de%elo"ment tas's are then identical to de%elo"ing against S:. Ser%er) without the licensing e1"ense of a full/#lown S:. Ser%er. ?The license to use and distri#ute MS0E is included in the aforementioned "roducts. ,hec' the end/ user license agreement to ensure that $our use is within the terms of the agreement.A And if $our
a""lication+s scala#ilit$ needs to grow) $ou can sim"l$ mo%e $our data#ase to S:. Ser%er for increased "erformance and scala#ilit$) with no code or data changes re(uired.
6. Scroll down to the Page0<oad e%ent handler and add the following code=
E. %i& -onn.t" 0s .t"in) F. %i& .NL 0s .t"in) G. -onn.t"="%ata .ou"ce=2local3QV.!otN TO " & < 1H. "!atabase=*ubsOinte)"ate! secu"it'=t"ue"
1$. 7'.@l-onn.9*en23 13. T"' 14. 18. 1:. 1E. 1F. 1G. $H. $1. $$. $3. $4. $8. $:. $E. $F. $G. .NL = "b'"o'alt'" %i& 7'.@l-&! 0s Ne1 .@l-o&&an!2.NL,7'.@l-onn3 7'.@l-&!.-o&&an!T'*e = -o&&an!T'*e..to"e!/"oce!u"e %i& 7'.@l/a"a& 0s Ne1 .@l/a"a&ete"2"M*e"centa)e",.@l%bT'*e.(nt3 7'.@l/a"a&.Value = 4H 7'.@l-&!./a"a&ete"s.0!!27'.@l/a"a&3 %i& 6ea!e" 0s .@l%ata6ea!e" 6ea!e" = 7'.@l-&!. xecute6ea!e"23 (# 6ea!e".Has6o1s T+en 7';"i!.%ata.ou"ce = 6ea!e" 7';"i!.%ataBin!23 lse %i& 7essa)e 0s Ne1 Label23 7essa)e.Text = "No "o1s to !is*la'" /a)e.-ont"ols.0!!27essa)e3 n! (#
!2. Sa%e the "age and code/#ehind module. !!. Build the "ro;ect. !8. Test the "age #$ right/clic'ing E1ecute7eader.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
The "re%ious e1am"le creates and o"ens a connection to the Pu#s data#ase) creates a S4l=ommand o#;ect and sets its =ommandType "ro"ert$ to =ommandType.StoredProcedure) and then creates a S4lParameter o#;ect) "assing the "arameter name and data t$"e to the "arameter+s constructor. IMPORTANT 9nli'e in A0*) when $ou s"ecif$ a "arameter name to A0*.NET $ou must use the e1act name the stored "rocedure e1"ects) including the at s$m#ol ?]A. The code then sets the %alue of the "arameter) adds it to the Parameters collection of the S4l=ommand o#;ect) and e1ecutes the command. The code then chec's the datareader+s Kas.ows "ro"ert$) and if the (uer$ returned one or more rows) the S4l,ata.eader o#;ect is then #ound to a ,ata-rid control) which dis"la$s the results.
Using 6atasets
0atasets are one of the two main wa$s of wor'ing with data in A0*.NET. ?The other wa$ is with 0ata7eaders) which $ou+%e #een using alread$ and will learn a#out in more detail later in this cha"ter.A 9nli'e most other o#;ects we ha%e loo'ed at) where there is one %ersion in the S4l=lient names"ace and a similar o#;ect in the +le,b names"ace) there is a single ,ataSet class) found in the System.,ata names"ace. 0ataset o#;ects "ro%ide a data#ase/inde"endent in/ memor$ re"resentation of data. This data can #e used for dis"la$ or to u"date a #ac'/end data#ase through the a""ro"riate ,ata/dapter o#;ect. A dataset can also read data from and write data to an -M. file or a Stream o#;ect. 0ataset o#;ects can #e constructed and mani"ulated "rogrammaticall$ #$ adding) modif$ing) or deleting ,ataTable) ,ata=olumn) and ,ata.ow o#;ects in the dataset. You can also use such datasets to u"date a #ac'/end data#ase ?assuming that the schema of the ta#les $ou+%e constructed is com"ati#leA #$ calling the !pdate method of the dataset o#;ect. You can wor' with t$"ed datasets to ma'e $our code easier to read and $our A0*.NET code less error "rone. Also) $ou can use a ,ataDiew o#;ect to filter the contents of a dataset for use in dis"la$ ?such as for data #indingA or calculations.
&'.@l0!a*te".Fill2&'%.3 &'.@l-onn.-lose23
At this "oint) the data in the dataset can #e u"dated or deleted) new rows can #e added) or the entire dataset can #e "assed to another com"onent #ecause it no longer has a connection to the #ac'/end data#ase. 3t+s im"ortant to understand that u"dating the dataset does not automaticall$ u"date the #ac'/end data#ase ?or other data sourceA from which the dataset was filled. To u"date the #ac'/end data#ase) $ou need to call the !pdate method of the data ada"ter used to fill the dataset. You+ll learn how to do this later in this cha"ter.
8. 9nli'e "re%ious e1am"les) this e1am"le will use an <TM. ta#le to format the out"ut. To ma'e this easier) use the Pro"erties window to change the page<ayout "ro"ert$ from -rid<ayout to 1low<ayout. ?,lic' an em"t$ area of the "age to ma'e sure the "ro"erties for the "age are dis"la$ed.A Q. ,hange to <TM. mode #$ clic'ing on the <TM. ta# at the #ottom of the design window. 3nsert the following <TM. #etween the #eginning and ending form tags. ?3f $ou+%e downloaded and installed the "ractice files) $ou can co"$ the code from the AddTitle.as"1 sam"le to sa%e t$"ing.A The <TM. code sets u" a ta#le to #e used to dis"la$ ca"tions and te1t#o1es.
:. E. F. G. 1H. 11. 1$. 13. 14. 18. 1:. 1E. 1F. 1G. $H. $1. $$. $3. $4. $8. $:. $E. ?Bt!A ?Bt"A ?t"A ?t! ?t!A ?as*Jtextbox i!="t'*e" text="*o*ula"<co&*" no1"a* AT'*eJ ?Bt!A ?+3A(nse"tin) a Title?B+3A ?table 1i!t+="3HH"A ?t"A ?t! cols*an="$" b)colo"="sil,e""A0!! a Ne1 TitleJ?Bt!A ?Bt"A ?t"A ?t! no1"a*ATitle (%J ?Bt!A ?t!A ?as*Jtextbox i!="title<i!" text="^^HHHH" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! no1"a*ATitleJ ?Bt!A ?t!A ?as*Jtextbox i!="title" text="T+e Tao o# 0./.N T" "unat="se",e""BA
$F. $G. 3H. 31. 3$. 33. 34. 38. 3:. 3E. 3F. 3G. 4H. 41. 4$. 43. 44. 48. 4:. 4E. 4F. 4G. 8H. 81. 8$. 83. 84. 88. 8:. ?Bt!A ?Bt"A ?t"A
"unat="se",e""BA
?t!A/ublis+e" (%J ?Bt!A ?t!A ?as*Jtextbox i!="*ub<i!" text="13FG" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A/"iceJ ?Bt!A ?t!A ?as*Jtextbox i!="*"ice" text="3G.GG" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A0!,anceJ ?Bt!A ?t!A ?as*Jtextbox i!="a!,ance" text="$HHH" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A6o'alt'J ?Bt!A ?t!A ?as*Jtextbox i!=""o'alt'" text="8" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! no1"a*A>ea"5to5%ate .alesJ ?Bt!A
8E. 8F. 8G. :H. :1. :$. :3. :4. :8. ::. :E. :F. :G. EH. E1. E$. E3. E4. E8. E:. EE. EF. EG. FH. F1. F$. F3. F4. F8.
?t!ANotesJ ?Bt!A ?t!A ?as*Jtextbox i!="notes" text&o!e="&ultiline" text="/+iloso*+' an! -o!e...a *e"#ect &ix." "o1s="3" colu&ns="3H" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! no1"a*A/ublication %ateJ ?Bt!A ?t!A ?as*Jtextbox i!="*ub!ate" text="1$BH1BH1" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t!A?Bt!A ?t! st'le="*a!!in)5to*J18"A ?as*Jbutton text="0!! Title" "unat="se",e""BA ?Bt!A ?Bt"A ?t"A ?t! cols*an="$"A ?as*J!ata)"i! i!="title)"i!" "unat="se",e""
F:. FE. FF. FG. GH. G1. G$. G3. G4. G8. G:. GE. GF. GG. 1HH. 1H1. 1H$. 1H3. 1H4. 1H8. 1H:. 1HE. 1HF. 1HG. 11H. 111. 11$. 113.
Bo"!e"-olo"="XGGGGGG" Bo"!e".t'le="None" Bo"!e"4i!t+="1*x" BacC-olo"="4+ite" -ell/a!!in)="3" ;"i!Lines="Ve"tical"A ?.electe!(te&.t'le Font5Bol!="T"ue" Fo"e-olo"="4+ite" BacC-olo"="XHHF0F-"A ?B.electe!(te&.t'leA ?0lte"natin)(te&.t'le BacC-olo"="X%-%-%-"A ?B0lte"natin)(te&.t'leA ?(te&.t'le Fo"e-olo"="BlacC" BacC-olo"="X ?B(te&.t'leA ?Hea!e".t'le Font5Bol!="T"ue" Fo"e-olo"="4+ite" BacC-olo"="XHHHHF4"A ?BHea!e".t'leA "A
?Foote".t'le Fo"e-olo"="BlacC" BacC-olo"="X------"A ?BFoote".t'leA ?/a)e".t'le Ho"iDontal0li)n="-ente"" Fo"e-olo"="BlacC" BacC-olo"="XGGGGGG" 7o!e="Nu&e"ic/a)es"A ?B/a)e".t'leA ?Bas*J!ata)"i!A ?Bt!A ?Bt"A ?BtableA
After inserting this code) switch #ac' to design mode #$ clic'ing in the 0esign ta# at the #ottom of the editor window. 3n the designer) the screen should loo' similar to the following illustration.
228. Switch to the code window #$ "ressing FK) or #$ selecting View) and then ,ode. At the to" of the file) add the following "mports clauses=
118. (&*o"ts .'ste&.%ata (&*o"ts .'ste&.%ata..@l-lient
226.
Scroll down to the Page0<oad e%ent handler and add the following code=
11E. %i& 7'%. 0s Ne1 %ata.et23 11F. %i& TitleTable 0s %ataTable 11G. %i& Title6o1 0s %ata6o1 1$H. %i& -onn.t" 0s .t"in) 1$1. %i& .NL 0s .t"in) 1$$. -onn.t" = "se",e"=2local3QV.!otN TO!atabase=*ubsO " & <
1$3.
"T"uste!<-onnection='es"
1$4. .NL = ". L -T U F697 Titles" 1$8. %i& 7'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 1$:. %i& 7'.@l0!a*te" 0s Ne1 .@l%ata0!a*te"2.NL,-onn.t"3 %i& 7'.@l-B 0s Ne1 .@l-o&&an!Buil!e"27'.@l0!a*te"3 7'%..6ea!^&l.c+e&a2.e",e".7a*/at+2"0!!Title.xs!"33 (# (s/ostBacC = T"ue T+en TitleTable = 7'%..Tables2H3 Title6o1 = TitleTable.Ne16o123 Title6o12"title<i!"3 = title<i!.Text Title6o12"title"3 = title.Text Title6o12"t'*e"3 = t'*e.Text Title6o12"*ub<i!"3 = *ub<i!.Text Title6o12"*"ice"3 = %ouble./a"se2*"ice.Text3 Title6o12"a!,ance"3 = %ouble./a"se2a!,ance.Text3 Title6o12""o'alt'"3 = (nte)e"./a"se2"o'alt'.Text3 Title6o12"'t!<sales"3 = (nte)e"./a"se2't!<sales.Text3 Title6o12"notes"3 = notes.Text Title6o12"*ub!ate"3 = %ateTi&e./a"se2*ub!ate.Text3 TitleTable.6o1s.0!!2Title6o13
'=*!ate bacC5en! table base! on ne1 "o1 7'.@l0!a*te".=*!ate27'%.3 '6eset !ataset be#o"e #illin) 1it+ !ata #"o& %B 7'%..6eset23 'Fill !ataset 1it+ !ata #"o& t+e Titles table 7'.@l0!a*te".Fill27'%.3 title)"i!.%ata.ou"ce = 7'%..Tables2H3.%e#aultVie1 title)"i!.%ataBin!23
lse 'To *"e,ent con#licts on &ulti*le inse"ts, 1e can ')ene"ate a "an!o& ,alue #o" title<i! %i& 6an!o&Nu& 0s Ne1 6an!o&23 title<i!.Text = "^^" & .t"in).Fo"&at2"YHJHHHXZ", < 6an!o&Nu&.Next2GGGG33 n! (#
22K. 22D.
22C. Test the "age #$ right/clic'ing AddTitle.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration. After $ou clic' the Add Title #utton) a 0ata@rid will #e dis"la$ed #elow the form fields with the current data in the Titles ta#le) including the added row.
allow $ou to treat them as true relational data and to maintain an$ hierarch$ and foreign 'e$ relationshi"s inherent in the data. The ,ataSet class fulfills this need with its .elations collection) which contains a collection of ,ata.elation o#;ects) each of which descri#es a "arentEchild relationshi" #etween two matching columns in different ta#les in the dataset. You can add ,ata.elation o#;ects to a dataset "rogrammaticall$) or the$ can #e inferred from a su""lied -S0 schema.
Accessing Values
Values in a dataset are accessed #$ referring to the ,ataTable and ,ata.ow o#;ects containing the data. The ,ataTables are a%aila#le %ia the Tables collection of the dataset) and $ou can reference a "articular ta#le either #$ inde1 ?Gero/#asedA or #$ ta#le name ?'e$A as follows=
%i& &'Table 0s %ataTable = &'%..Tables2H3 %i& &'Table 0s %ataTable = &'%..Tables2"tablena&e"3
You can also iterate o%er the ,ataTable=ollection ?returned #$ the Tables "ro"ert$ of the datasetA) ,ata.ow=ollection ?returned #$ the .ows "ro"ert$ of a ,ataTableA) or the ,ata=olumn=ollection ?returned #$ the =olumns "ro"ert$ of a ,ataTableA. The code in the following e1am"le iterates o%er all of the ta#les in a dataset and all of the rows in each ta#le. Then it dis"la$s the %alue of each column in the row) using an ASP.NET <iteral control as a "laceholder for the te1t.
6. Scroll down to the Page0<oad e%ent handler and add the following code=
E. %i& 7'%. 0s Ne1 %ata.et23 F. %i& -onn.t" 0s .t"in)
G. %i& .NL 0s .t"in) 1H. -onn.t" = 11. "se",e"=2local3QV.!otN TO!atabase=*ubsO" & <
"T"uste!<-onnection='es"
1$. .NL = ". L -T U F697 Titles " & < 13. ". L -T U F697 /ublis+e"s"
14. %i& 7'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 18. %i& 7'.@l0!a*te" 0s Ne1 .@l%ata0!a*te"2.NL,-onn.t"3 1:. 1E. 'T+e .@l%ata0!a*te" 1ill auto&aticall' o*en an! 1F. 'close t+e .@l-onnection 7'.@l0!a*te".Fill27'%.3
Most of this should loo' somewhat familiar #$ now. *ne difference is that the S:. command contains two distinct SE<E=T statements. This is to cause two ta#les to #e retrie%ed into the ,ataSet. 2C. Add code to iterate o%er the ,ataTables) ,ata.ows and ,ata=olumns. Fust #elow the code added in the "re%ious ste") add the following code=
$H. ';et eac+ %ataTable in t+e %ataTable -ollection $1. 'an! !is*la' eac+ "o1 ,alue b' a**en!in) it to $$. 't+e Text *"o*e"t' o# t+e Lite"al cont"ol. $3. $4. %i& -u""entTable 0s %ataTable $8. %i& -u""ent6o1 0s %ata6o1 $:. %i& -u""ent-olu&n 0s %ata-olu&n $E. $F. Fo" $G. 3H. 31. 3$. 33. ac+ -u""entTable in 7'%..Tables Value.Text &= "TableJ " & < -u""entTable.TableNa&e.To.t"in)23 & "?b"BA" Value.Text &= "5555555555555555555555555555555555555?b"BA" Fo" ac+ -u""ent6o1 (n -u""entTable.6o1s Value.Text &= "?b"BA&nbs*O&nbs*O&nbs*O"
34. 38. 3:. 3E. 3F. 3G. 4H. 41. 4$. 43. 44. 48. 4:. 4E. Next
Fo"
(# Not -u""ent6o12-u""ent-olu&n3 (s Not+in) T+en (# Not (s%bNull2-u""ent6o12-u""ent-olu&n33 T+en ,alue.Text &= -.t"2-u""ent6o12-u""ent-olu&n33 lse Value.Text &= "N=LL" n! (# Value.Text+="?b"BA&nbs*O&nbs*O&nbs*O" n! (# Next Next Value.Text &= "555555555555555555555555555555555?b"BA" Value.Text &= "?b"BA?b"BA"
8D. Sa%e the "age and code/#ehind module. 8C. Build the "ro;ect. Q . Test the "age #$ right/clic'ing 0is"la$0ataSet3tems.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
Q2. Scroll toward the #ottom of the screen. You should see the transition #etween the titles and "u#lishers ta#les) as the following illustration shows.
9"dating 0atasets
*nce $ou+%e "o"ulated a dataset with dataBeither #$ using a ,ata/dapter or #$ calling the .eadXml method of the datasetB$ou might want to u"date that data. You can edit an indi%idual %alue #$ s"ecif$ing the ta#le) row) and column of the item $ou want to edit and then su""l$ing a new %alue.
&'%..Tables2H3.6o1s2H3.-olu&ns2$3 = "*o*ula"<co&*"
But what if $ou edit se%eral %alues) and then $ou realiGe that $ou want to roll #ac' one or more of the changesU Fortunatel$) the dataset "ro%ides ro#ust su""ort for acce"ting and re;ecting changes in its data #$ maintaining multi"le %ersions of the data for each row. Each row contains the following %ersions=
,efault
,ontains the default %alues for the row ?s"ecified #$ the ,efaultDalue "ro"ert$ of the row+s columnsA. 3f no defaults ha%e #een s"ecified) this contains the same data as +riginal.
=urrent ,ontains u"dated data for an$ columns that ha%e #een u"dated) and the same data as +riginal for columns that ha%e not #een u"dated.
Proposed Valid after calling 2eginEdit on a row and #efore calling the EndEdit or =ancelEdit methods of the ,ata.ow) the Proposed %ersion contains changes to data that ha%e not $et #een a""lied to the =urrent %ersion. 3f =ancelEdit is called) the Proposed %ersion is deleted. 3f EndEdit is called) the changes in the Proposed %ersion are a""lied to the =urrent %ersion.
You can determine whether changes ha%e #een made to an item in a row #$ com"aring the item+s +riginal or ,efault %ersion with the =urrent %ersion=
%i& -u""ent6o1 0s %ata6o1 = 7'%ata.et.Tables2H3.6o1s2H3 (# -u""ent6o121, %ata6o1Ve"sion.-u""ent3 (s < -u""ent6o121, %ata6o1,e"sion./"o*ose!3 T+en 'TaCe a**"o*"iate action n! (#
Finall$) $ou can chec' the current state of a row #$ chec'ing the row+s 7owState "ro"ert$=
%i& -u""ent.tate 0s .t"in) %i& -u""ent6o1 0s %ata6o1 = 7'%ata.et.Tables2H3.6o1s2H3
/dded 7e"resents a row that has #een added to the ta#le "rior to /ccept=hanges #eing called. *nce /ccept=hanges is called) this row+s .owState will #e set to !nchanged.
,etached 7e"resents a newl$ created row that has not $et #een added to a ,ata.ow=ollection) or a row that has #een remo%ed from a ,ata.ow=ollection #ut not destro$ed.
9odified 7e"resents a row whose data has changed) #ut whose /ccept=hanges method has not #een called.
!nchanged 7e"resents a row whose data has not changed since the last call to /ccept=hanges.
*nce $ou+%e called /ccept=hanges on the dataset) $ou would call the !pdate method of the ,ata/dapter used to load data into the dataset to u"date the underl$ing data#ase with the new %alues.
T)(ed 6atasets
*ne of the coolest new features of A0*.NET is the a#ilit$ to create strongl$ t$"ed datasets. T$"ed datasets are s"ecial classes) generated #$ the 1sd.e1e command/line utilit$) that inherit from the ,ataSet class. The$ use an -S0 schema to create additional "u#lic "ro"erties and methods that allow $ou to access the columns of the dataset+s ta#les directl$ #$ name) rather than ha%ing to use either an inde1 or a late/#ound 'e$. This can im"ro%e run/time "erformance and reduce the li'elihood of errors in coding against the dataset.
You can create t$"ed datasets two wa$s= You can create them using Visual Studio .NET) or) if $ou find the auto/generated code more than $ou need or $ou want finer control) $ou can create them manuall$. .et+s loo' at the manual "rocedure first. ,reating a t$"ed dataset manuall$ for the AddTitles e1am"le shown earlier re(uires ;ust a few ste"s. The following e1am"le assumes that $ou+%e alread$ created an -S0 schema for the ta#le or ta#les in the dataset ?$ou can use the AddTitle.1sd schema included with the "ractice filesA) which $ou can do with the riteXmlSchema method of a dataset that+s #een loaded with data from the ta#le or ta#les.
The Ed o"tion s"ecifies that we want to create a dataset) the El o"tion sets the language as Visual Basic) and the En o"tion s"ecifies that the class should use the names"ace /ddTitle. AddTitle.1sd is the name of $our -S0 schema file) which is shown in the AddTitle.1sd listing that follows this section. The out"ut of 1sd.e1e with these arguments is a .%# class file ?in this case) AddTitle.%#A. !. ,om"ile the class using the %#c.e1e command/line com"iler ?located #$ default in the folder 8windir8O9icrosoft.NETO1rameworkN 8%ersion8) where windir is the &indows director$) and %ersion is the %ersion of the framewor' that is installedA. Note that the three lines that follow should #e entered as a single command=
4. ,bc.exe BtJlib"a"' 0!!Title.,b B"J.'ste&.!ll 8. B"J.'ste&.%ata.!ll B"J.'ste&.^7L.!ll BoutJbinB0!!Title.!ll
The Et o"tion s"ecifies that $ou want to com"ile as a li#rar$ com"onent ?0..A) the Er o"tions s"ecif$ assem#lies that $ou need to reference) and the Eout o"tion directs the com"iler to sa%e the com"iled assem#l$ in the #in su#director$ of the current director$. TIP Note that to use 1sd.e1e and %#c.e1e without s"ecif$ing the entire "ath to the e1ecuta#le) the "aths to these "rograms must #e registered in the PAT< en%ironment %aria#le for the machine $ou+re wor'ing on. The ste"s necessar$ to do this are detailed in A""endi1 ,.
0!!Title.xs!
?Px&l ,e"sion="1.H" stan!alone="'es"PA ?xs!Jsc+e&a i!="Title%ata.et" ta")etNa&es*ace="+tt*JBB 111.as*netb.co&.ns" x&lns="" x&lnsJxs!="+tt*JBB111.13.o")B$HH1B ^7L.c+e&a" x&lnsJ&s!ata="u"nJsc+e&as5&ic"oso#t5co&Jx&l5&s!ata"A ?xs!Jele&ent na&e="Title%ata.et" &s!ataJ(s%ata.et="t"ue"A ?xs!Jco&*lexT'*eA ?xs!Jc+oice &ax9ccu"s="unboun!e!"A ?xs!Jele&ent na&e="Titles"A ?xs!Jco&*lexT'*eA ?xs!Jse@uenceA ?xs!Jele&ent na&e="title<i!" t'*e="xs!Jst"in)" &in9ccu"s="H" BA ?xs!Jele&ent na&e="title" t'*e="xs!Jst"in)" &in9ccu"s="H" BA ?xs!Jele&ent na&e="t'*e" t'*e="xs!Jst"in)" &in9ccu"s="H" BA ?xs!Jele&ent na&e="*ub<i!" t'*e="xs!Jst"in)" &in9ccu"s="H" BA ?xs!Jele&ent na&e="*"ice" t'*e="xs!J!eci&al" &in9ccu"s="H" BA ?xs!Jele&ent na&e="a!,ance" t'*e="xs!J!eci&al" &in9ccu"s="H" BA ?xs!Jele&ent na&e=""o'alt'" t'*e="xs!Jint" &in9ccu"s="H" BA ?xs!Jele&ent na&e="'t!<sales" t'*e="xs!Jint" &in9ccu"s="H" BA ?xs!Jele&ent na&e="notes" t'*e="xs!Jst"in)" &in9ccu"s="H" BA ?xs!Jele&ent na&e="*ub!ate" t'*e="xs!J!ateTi&e" &in9ccu"s="H" BA ?Bxs!Jse@uenceA ?Bxs!Jco&*lexT'*eA ?Bxs!Jele&entA ?Bxs!Jc+oiceA ?Bxs!Jco&*lexT'*eA ?Bxs!Jele&entA ?Bxs!Jsc+e&aA
You can also create a t$"ed dataset using Visual Studio .NET. The following ste"s wal' $ou through doing ;ust that on a new form modeled after AddTitle.as"1) the form $ou created in a "re%ious e1am"le.
6. ,reate a connection #$ clic'ing the New ,onnection #utton and the 0ata .in' Pro"erties dialog #o1 will a""ear. Select the ?localANVSdotNET instance of S:. Ser%er) set the log on information to use NT 3ntegrated securit$ and the data#ase to "u#s. The 0ata .in' Pro"erties dialog #o1) when filled in) should loo' li'e the following illustration ?assuming $ou are logged into a &indows account that has rights to connect to the VSdotNET MS0E instanceA. You can clic' the Test ,onnection #utton to ensure that the connection settings are correct=
K. ,lic' *> in the 0ata .in' Pro"erties dialog #o1) and then clic' Ne1t in the 0ata Ada"ter ,onfiguration &iGard. The ,hoose A :uer$ T$"e "age will a""ear) as shown in the following illustration.
You will "roceed to the @enerate The S:. Statements "age allowing $ou to generate the Select statement to use. &hile $ou can sim"l$ t$"e in commands ?for instance) SE.E,T V F7*M TitlesA) the :uer$ Builder "ro%ides the means to create a (uer$ %isuall$. D. ,lic' the :uer$ Builder #utton. The Add Ta#le dialog #o1 will a""ear. C. Select the Titles ta#le from the list and clic' Add) and then clic' ,lose to close the Add Ta#les dialog #o1) which will return $ou to the :uer$ Builder. You can clic' the ?All ,olumnsA chec' #o1 to select all columns) or $ou can select the columns indi%iduall$. Selecting e1"licitl$ the columns $ou want can often #e more efficient. 3n this e1am"le) chec' each column indi%iduall$) as shown in the following illustration. ,lic' *> to close the :uer$ Builder dialog #o1.
2 . ,lic' ne1t on the @enerate The S:. Statements "age. The final screen of the 0ata Ada"ter ,onfiguration &iGard should a""ear) as shown in the following illustration.
A new window should a""ear at the #ottom of the main editing window in Visual Studio .NET. 3t will ha%e two com"onents) s(l0ataAda"ter2 and s(l,onnection2. 9se the Pro"erties windows to change the names to daTitles and cnPu#) res"ecti%el$. &hen $ou+%e renamed the com"onents) the screen should loo' li'e the following illustration.
22. ,lic' on the daTitles com"onent. From the 0ata menu) select @enerate 0ataSet. The @enerate 0ataSet dialog #o1 will a""ear) as shown in the following illustration. The default name for the t$"ed dataset will #e 0ataSet2. ,hange the dataset name to Title6ataSet and clic' *>.
2!. Switch to the code window #$ "ressing FK) or #$ selecting View) and then ,ode. At the to" of the file) add the following "mports clauses=
14. (&*o"ts .'ste&.%ata (&*o"ts .'ste&.%ata..@l-lient
$:. $E. $F. $G. 3H. 31. 3$. 33. 34. 38. 3:. 3E. 3F. 3G. 4H. 41. 4$. 43. 44. 48. 4:. n! (# lse
7'Title6o1.*"ice = %eci&al./a"se2*"ice.Text3 7'Title6o1.a!,ance = %eci&al./a"se2a!,ance.Text3 7'Title6o1."o'alt' = (nte)e"./a"se2"o'alt'.Text3 7'Title6o1.'t!<sales = (nte)e"./a"se2't!<sales.Text3 7'Title6o1.notes = notes.Text 7'Title6o1.*ub!ate = %ateTi&e./a"se2*ub!ate.Text3 Title%ata.et1.titles.0!!titles6o127'Title6o13 !aTitles.=*!ate2Title%ata.et13 !aTitles.Fill2Title%ata.et13
'To *"e,ent con#licts on &ulti*le inse"ts, 1e can ')ene"ate a "an!o& ,alue #o" title<i! %i& 6an!o&Nu& 0s Ne1 6an!o&23 title<i!.Text = "^^" & .t"in).Fo"&at2"YHJHHHXZ", < 6an!o&Nu&.Next2GGGG33
8K. Sa%e the "age and code/#ehind module. 8D. Build the "ro;ect. 8C. Test the "age #$ right/clic'ing AddTitleOT$"ed0S.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' almost e1actl$ li'e the "re%ious AddTitles.as"1 e1am"le) with a different heading. Now when $ou create the dataset) $ou create an instance of Title,ataSetWthe class that im"lements the t$"ed datasetBinstead of ,ataSet. &hen $ou loo' at the code Visual Studio .NET adds to the code/#ehind module) $ou will see the following declaration ?note that in Visual
Studio .NET 2 !) this declaration is hidden in the region mar'ed &e# Form 0esigner @enerated ,odeA=
/"otecte! 4it+ ,ents Title%ata.et1 0s -+a*te"<HG.Title%ata.et
Similarl$) $ou+ll see strong t$"es for the ta#le and row. The code that $ou added to the Page0<oad e%ent handler) for e1am"le) includes a strongl$ t$"ed declaration for a row in the Titles ta#le=
%i& 7'Title6o1 0s Title%ata.et.titles6o1
Another useful feature of t$"ed datasets is that when $ou use them with Visual Studio .NET) $ou automaticall$ get 3ntelliSense code com"letion for all the mem#ers of the Title,ataSet. This ma'es coding against a t$"ed dataset much easier and considera#l$ less error "rone. The following illustration shows how eas$ it is to choose the correct field from a t$"ed dataset using 3ntelliSense.
3t+s im"ortant to note that when $ou+re "rogramming against a t$"ed dataset ?rather than a standard datasetA) the fields of the t$"ed dataset are e1"osed as strongl$ t$"ed "ro"erties. This means that if $ou tr$ to assign data of an incom"ati#le t$"e to a "ro"ert$) $ou+ll get an error at com"ile time ?allowing $ou to fi1 the "ro#lem #efore $our users find itA. Therefore) t$"ed datasets ma'e it easier to create error/free data access code.
*nce $ou ha%e a reference to the ,ataDiew) filter it #$ adding an e1"ression to the .ow1ilter "ro"ert$=
&'%V.6o1Filte" = "t'*e='business'"
You+%e alread$ seen some #asic e1am"les of #inding to a ,ataDiew. You+ll loo' at data #inding in more detail later in this cha"ter.
S4lData0eader
S4l,ata.eader is the class to use when accessing data from a S:. Ser%er data#ase. You create this class #$ calling the E$ecute.eader method on a S4l=ommand o#;ect.
%i& &'.@l%6 0s .@l%ata6ea!e" = &'.@l-&!. xecute6ea!e"23
To access the rows in a S(l0ata7eader instance) call the .ead method of the instance) usuall$ in a loo"=
4+ile &'.@l%6.6ea!23
6es*onse.4"ite2&'.@l%6.(te&2H33 n! 4+ile
TIP 3f $ou want a sim"le wa$ to chec' if a datareader contains data #efore "erforming an$ o"erations on it) $ou can chec' the Kas.ows "ro"ert$ ?new for %ersion 2.2 of the Framewor'A) which returns a True if the datareader contains one or more rows of data. *nce $ou+re finished with S4l,ata.eader) $ou should alwa$s call its =lose method) as well as calling the =lose method on the associated =onnection o#;ect= myS4l,..=loseEF. NOTE To a%oid ha%ing to e1"licitl$ close the connection associated with the ,ommand o#;ect used to create either a S4l,ata.eader or an +le,b,ata.eader) "ass the =ommand2eha%ior.=lose=onnection argument to the E$ecute.eader method of the ,ommand=
&'.@l%6 = &'.@l-&!. xecute6ea!e"2-o&&an!Be+a,io".-lose-onnection3
The connection associated with the ,ommand o#;ect will #e closed automaticall$ when the =lose method of the datareader is called. This ma'es it all the more im"ortant to alwa$s remem#er to call =lose on $our 0ata7eader o#;ectsH
1leD2Data0eader
,reating and using an +le,b,ata.eader o#;ect is essentiall$ the same as for the S4l,ata.eader) with one nota#le e1ce"tion. The +le,b,ata.eader can handle hierarchical recordsets retrie%ed using the 9S,ataShape *.E 0B Pro%ider ?also 'nown as the 0ata Sha"ing Ser%ice for *.E 0BA. &hen $ou create an +le,b,ata.eader #ased on an +le,b=ommand that returns a hierarchical recordset) the *.E 0B cha"ter is returned as a column in the +le,b,ata.eader. The %alue of the column is an +le,b,ata.eader re"resenting the child records. See http://msdn.microsoft.com/library/enCus/wp/htm/wpmdac0tf0shaping0ser%ice.asp for more information on the 0ata Sha"ing Ser%ice for *.E 0B.
6ata Binding
*ne e1citing ad%ance in the mo%e from classic ASP to ASP.NET is the a%aila#ilit$ of ser%er/side data #inding) which is the "rocess of declarati%el$ t$ing elements ?such as controlsA of the 93 for a "age to data in an underl$ing datastore. 0ata #inding on the client has #een a%aila#le in 3nternet E1"lorer for a num#er of $ears) #ut it re(uires all of $our users to use the same #rowser) or else $ou need to do a massi%e amount of testing to ensure com"ati#ilit$ with different #rowser %ersions. Ser%er/side data #inding sol%es this "ro#lem #$ #inding and rendering data on the ser%er and returning cross/#rowser/com"ati#le <TM.. ASP.NET allows $ou to #ind against a %ariet$ of sources) including "ro"erties and method call results) arra$s and collections) and 0ata7eader and 0ataView o#;ects. T$"icall$) #inding is done either declarati%el$) using the :8Ue$pression8; s$nta1) or #$ "rogrammaticall$ setting the ,ataSource "ro"ert$ of a control to the desired datasource. The data is #ound #$ calling the ,ata2ind method) either at the Page le%el ?which #inds all controls on the "ageA or on the control #eing #ound ?which #inds the control and an$ child controlsA. The ,ata2ind method causes the control and its children to e%aluate an$ data/#inding e1"ression?sA associated with the control and assign the resulting %alues to the a""ro"riate control attri#ute. 0ata #inding allows controls such as the ,ata-rid control) which can handle multi"le rows and columns) to iterate o%er and format the data s"ecified #$ their ,ataSource "ro"ert$ for dis"la$.
.i&*le%ataBin!in).as*x
?IM /a)e Lan)ua)e=",b" IA ?+t&lA ?+ea!A ?sc"i*t "unat="se",e""A %i& Na&e 0s .t"in) .ub btn.ub&it<-licC2sen!e" 0s 9bLect, e 0s Na&e = txtHello.Text lblHello.Visible = T"ue %ataBin!23 ,ent0")s3
n! .ub ?Bsc"i*tA ?B+ea!A ?bo!'A ?as*Jlabel i!="lblHello" ,isible="#alse" "unat="se",e""A Hello, ?IX Na&e IA! ?Bas*JlabelA ?#o"& "unat="se",e""A ?as*Jtextbox text="" i!="txtHello" "unat="se",e""BA ?b"A ?as*Jbutton text=".ub&it" i!="btn.ub&it" 9n-licC="btn.ub&it<-licC" "unat="se",e"" BA ?B#o"&A ?Bbo!'A ?B+t&lA
The out"ut of this listing after entering a %alue and clic'ing the #utton is shown in the following illustration.
Binding to ,ontrols
You can use the same s$nta1 to #ind to controls. For e1am"le) $ou can #ind the selected item of a ,rop,own<ist control to the Te$t "ro"ert$ of an ASP.NET <abel control) as shown in the following e1am"le.
K. Switch to the code window #$ "ressing FK) or #$ selecting View) then ,ode. D. Add the following code to the Page0<oad e%ent handler=
G. (# Not (s/ostBacC = T"ue T+en 1H. 11. 1$. 13. 14. 18. 1:. 1E. 1F. 1G. %i& 7'0""a'List 0s Ne1 0""a'List23 7'0""a'List.0!!2"-+ocolate"3 7'0""a'List.0!!2"Vanilla"3 7'0""a'List.0!!2".t"a1be""'"3 7'List.%ata.ou"ce = 7'0""a'List 'Bin! t+e 0""a'List to t+e %"o*%o1nList cont"ol 7'List.%ataBin!23 lse Fla,o".Visible = T"ue n! (#
$H. '-all t+e /a)e's %ataBin! &et+o! $1. 'T+is 1ill e,aluate t+e !atabin!in) ex*"ession in t+e Label's text $$. *"o*e"t' %ataBin!23
2!. Sa%e the "age and code/#ehind module. 28. Build the "ro;ect. 2Q. Test the "age #$ right/clic'ing ,ontrolBinding.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. After $ou select a fla%or from the dro"/down list and clic' Su#mit) the resulting screen should loo' li'e the following illustration.
Using DataBi"der.E%al
,ata2inder.E%al is a static method used to e%aluate a data/#inding e1"ression at run time. This can sim"lif$ the "rocess of casting %arious data t$"es to #e dis"la$ed as te1t. The #asic s$nta1 of ,ata2inder.E%al is
?IX %ataBin!e". ,al2-ontaine", ,al x*"ession, Fo"&at x*"ession3 IA
=ontainer is the o#;ect that contains the e1"ression to #e e%aluated. ?For ,ata-rid) ,ata<ist) or .epeater controls) this e1"ression is alwa$s =ontainer.,ata"tem.A E%alE$pression is the full name of the "ro"ert$ or item to #e e%aluated. 1ormatE$pression is a string formatting e1"ression ?such as HQ:cIA to #e used to format the string result. Note that if no format e1"ression argument is "assed) ,ata2inder.E%al will return an o#;ect instead of a string. IMPORTANT Because ,ata2inder.E%al uses late #inding and reflection ?which allows managed code to interrogate other managed code at runtimeA) it can #e significantl$ slower than the other data/ #inding techni(ues. For this reason) $ou should use ,ata2inder.E%al onl$ when $ou need to) such as for "erforming string formatting on numeric data.
Using Data7rids
The ,ata-rid control "resents #ound data in a ta#ular format and "ro%ides a num#er of "ro"erties that $ou can use to format the data. This control can automaticall$ generate all
columns in the ta#le from its ,ataSource "ro"ert$) or $ou can use s"ecialiGed column controls to "ro%ide additional functionalit$ or formatting for a gi%en column or columns. At its sim"lest) there are three #asic ste"s to using a ,ata-rid control. 2. Add the ,ata-rid control to the "age. 2. Set the ,ataSource "ro"ert$ of the ,ata-rid to an a""ro"riate data source. This data source can #e defined in the "age) or $ou can call a method in an e1ternal o#;ect to su""l$ the data. !. ,all the ,ata2ind method of the control to automaticall$ #ind the data to the control. You can also call the ,ata2ind method of the Page o#;ect) which will #ind ?or re#indA all of the data/#ound controls on the "age #$ calling ,ata2ind on each control in turn. .et+s loo' at an e1am"le. 3n 4<TM. ,ontrols5 in ,ha"ter D) $ou saw an e1am"le that used a dro"/down list #o1 to list fla%ors of ice cream for a user to choose from. Su""ose that $ou want to show similar information in a ta#le format. The "ro#lem with this a""roach is that the data is e1"licitl$ added to the control in the code ?or declarati%el$ #$ adding items to the control in its tag declarationA. Thus) an$ time the data changes $ou ha%e to e1"licitl$ change the code that creates the control. Additionall$) #ecause the creation of the data and the creation of the control are tightl$ cou"led) it+s not "ossi#le to reuse this data) either elsewhere on the "age or elsewhere in the a""lication. So in this first e1am"le) $ou+ll create the data that $ou want to use in a custom "rocedure in a :script; #loc') and then call that "rocedure in order to "o"ulate the data source of $our ,ata-rid control. Start with a %er$ sim"le ,ata-rid that has no formatting whatsoe%er.
This function sim"l$ creates an /rray<ist named ,ata/rray) adds a few items) and then returns the /rray<ist to the caller. D. Add the following code to the Page0<oad e%ent handler=
G. 7';"i!.%ata.ou"ce = -"eate%ata23 7';"i!.%ataBin!23
Because =reate,ata returns an /rray<ist ?which im"lements the "=ollection interfaceA) $ou can actuall$ use the function itself for the ,ataSource "ro"ert$ of the ,ata-rid control. 2 . Sa%e the "age and code/#ehind module. 22. Build the "ro;ect. 22. Test the "age #$ right/clic'ing 0ata@rid.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
Although this is a %er$ sim"le e1am"le) $ou used two lines of code ?setting the ,ataSource and calling ,ata2indA to accom"lish what would ha%e ta'en considera#l$ more code in classic ASP. Now let+s ;aGG things u" a #it #$ #inding to li%e data with multi"le columns "er row in a grid.
K. Switch to the code/#ehind module for the "age and add the following code to the Page0<oad e%ent handler=
F. /ub0!a*te".Fill2/ublis+e"%ata.et13 7';"i!.%ataBin!23
C. Sa%e the "age and code/#ehind module. 2 . Build the "ro;ect. 22. Test the "age #$ right/clic'ing 0ata@ridEdit.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration. .ea%e 0ata@ridEdit.as"1 o"en in the 30E #ecause $ou+ll #e wor'ing on it again in the ne1t e1am"le.
But waitH There+s more. 3n addition to autogenerating columns from the #ound data) ,ata-rids also su""ort creating columns declarati%el$. This gi%es $ou greater control o%er #oth the formatting and the #eha%ior of indi%idual columns. For e1am"le) $ou can use a 2ound=olumn control to "ro%ide customiGed header te1t for a column) or to a""l$ s"ecial formatting to the #ound te1t in each row. You can also use a 2utton=olumn control to dis"la$ a command #utton in each row of a column) an Edit2utton=olumn control to "ro%ide in/"lace editing for a row) or a Kyperlink=olumn control to "ro%ide a h$"erlin' for each row of the grid) with the te1t ca"tion) the 97.) or #oth #eing data/#ound. Finall$) $ou use a Template=olumn control to a""l$ com"le1 formatting to each row of a s"ecific column. 3n addition to manuall$ creating and modif$ing the %arious controls within the grid) $ou can also use Visual Studio .NET to control the #eha%ior and loo' of the ,ata-rid. .et+s see how we can im"ro%e this e1am"le+s a""earance using Visual Studio .NET.
Sim"l$ #$ selecting the scheme from the Auto Format dialog) the <TM. declaration for the ,ata-rid will change from a %er$ sim"le declaration to something similar to the following code. 9sing schemes hel"s $ou (uic'l$ create a consistent loo' for all $our datagrids.
?as*J%ata;"i! i!="7';"i!" st'le="K(N% ^J 1H1O L FTJ 1G*xO /9.(T(9NJ absoluteO T9/J $$*x" "unat="se",e"" Bo"!e"-olo"="XGGGGGG" Bo"!e".t'le="None" Bo"!e"4i!t+="1*x" BacC-olo"="4+ite" -ell/a!!in)="3" ;"i!Lines="Ve"tical"A ?.electe!(te&.t'le Font5Bol!="T"ue" Fo"e-olo"="4+ite" BacC-olo"="XHHF0F-"A ?B.electe!(te&.t'leA ?0lte"natin)(te&.t'le BacC-olo"="X%-%-%-"A ?B0lte"natin)(te&.t'leA ?(te&.t'le Fo"e-olo"="BlacC" BacC-olo"="X ?B(te&.t'leA ?Hea!e".t'le Font5Bol!="T"ue" Fo"e-olo"="4+ite" BacC-olo"="XHHHHF4"A "A
?BHea!e".t'leA ?Foote".t'le Fo"e-olo"="BlacC" BacC-olo"="X------"A ?BFoote".t'leA ?/a)e".t'le Ho"iDontal0li)n="-ente"" Fo"e-olo"="BlacC" BacC-olo"="XGGGGGG" 7o!e="Nu&e"ic/a)es"A ?B/a)e".t'leA ?Bas*J%ata;"i!A
!. ,lic' on the Pro"ert$ Builder lin' at the #ottom of the Pro"erties window. The Pro"erties dialog #o1 a""ears) as shown in the following illustration.
8. ,lic' the ,olumns item in the left side of the dialog #o1. 9nchec' ,reate ,olumns Automaticall$ At 7un Time. 9se the Add ?SA #utton to add a column to the Selected ,olumns list #o1 for each data field in the A%aila#le ,olumns list #o1) changing the <eader te1t to a friendlier name for each column) as shown in the following illustration.
Q. ,lic' the Format item on the left side of the dialog #o1) and then $ou can select se%eral o"tions from a tree %iew on the resulting dialog #o1. ,lic' on <eader and change the <oriGontal Alignment to ,enter. &hen finished) the dialog #o1 should loo' li'e the following illustration.
6. ,lic' *> to a""l$ the changes and close the dialog #o1. K. Sa%e the "age. Because $ou didn+t change an$thing in the code/#ehind module) $ou don+t need to re#uild the "ro;ect. D. Test the "age #$ right/clic'ing 0ata@ridEdit.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration. .ea%e 0ata@ridEdit.as"1 o"en in the 30E #ecause $ou+ll #e wor'ing on it again in the ne1t e1am"le.
This loo's much #etter) #ut there is still more we can do to im"ro%e this e1am"le. &e might want to add the a#ilit$ to sort #$ one or more of the columns.
Sort a 0ata@rid
2. &ith the 0ata@rid control selected in 0ata@ridEdit.as"1) clic' on the Pro"ert$ Builder lin'. The Pro"ert$ Builder dialog #o1 will a""ear. 2. ,lic' on ,olumns on the left side of the dialog #o1) and note that the Sort E1"ression for each column is set to the name of the field the column is #ased u"on. This is #ecause in the "re%ious e1am"le) $ou used #ound columns to create the columns for the grid) which automaticall$ set a default Sort E1"ression #ased on the t$"ed dataset to which the datagrid is #ound. !. To ena#le sorting) clic' the @eneral item on the left side of the dialog #o1) and then chec' the Allow Sorting chec' #o1. 8. To ma'e sorting wor') $ou+ll also add code to "erform the sort and re/#ind the grid in a later ste") so change the 0ataSource dro"/down list from Pu#lisher0ataSet2 to ?9n#oundA. ,lic' *> to close the dialog #o1 when $ou+re finished. Q. Switch to the code/#ehind module for the "age) and in the left/hand dro"/down list at the to" of the "age) select M$@rid. The right/hand dro"/down list will now contain a list of the %alid e%ents for M$@rid. Select the Sort=ommand e%ent from the list. This will insert an e%ent handler for the e%ent. The result should loo' similar to the following illustration.
This code creates a new ,ataDiew #ased on the "u#lishers ta#le from the t$"ed dataset) sets the sort e1"ression of the data%iew to the one "assed from the column whose header is clic'ed at run time) and then re/#inds the grid. 2 . Since $ou remo%ed the design/time #inding of the datagrid in Ste" 2) $ou+ll also need to change the code in the Page0<oad e%ent handler to the following code=
11. /ub0!a*te".Fill2/ublis+e"%ata.et13 1$. (# Not (s/ostBacC T+en 13. 7';"i!.%ata.ou"ce = /ublis+e"%ata.et1.*ublis+e"s.%e#aultVie1
14.
7';"i!.%ataBin!23 n! (#
This code fills the dataset and) if the re(uest is not the result of a "ost#ac') sets the ,ataSource of the datagrid to the default data%iew of the "u#lishers ta#le) and then data#inds the grid. 2Q. Sa%e the "age and code/#ehind module. 26. Build the "ro;ect. 2K. Test the "age #$ right/clic'ing 0ata@ridEdit.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration. .ea%e 0ata@ridEdit.as"1 o"en in the 30E) as $ou+ll #e wor'ing on it again in the ne1t e1am"le.
You can clic' on an$ of the column headers to sort the data #$ the selected column. Because $ou can s"ecif$ the e1act sort e1"ression) $ou can also choose to ma'e the sort more com"le1) "erha"s sorting #$ State and ,it$ when $ou clic' on the State header. TIP The "receding e1am"le of sorting onl$ im"lements sorting in one direction. That is) if $ou clic' a gi%en heading more than once) the second ?and su#se(uentA clic's ha%e no effect. 3f $ou want to ena#le #oth ascending and descending sorts for a datagrid) $ou will need to trac' the current sort
order. An eas$ wa$ to do this is to sa%e the current sort order to the ViewState field after setting the Sort "ro"ert$ of the data%iew) and then com"are that %alue to the SortE$pression "ro"ert$ the ne1t time the Sort=ommand e%ent is fired) adding Y0ES,Y to the Sort "ro"ert$ if the same column is clic'ed twice in a row ?and setting the Sort "ro"ert$ to e.SortE$pression normall$ otherwiseA. The code re(uired to "erform a two/wa$ sort follows=
.ub 7';"i!<.o"t-o&&an!2B'Val sou"ce 0s 9bLect, B'Val e 0s < %ata;"i!.o"t-o&&an! ,ent0")s3 Han!les 7';"i!..o"t-o&&an! %i& .o"tVie1 0s %ataVie1 = /ublis+e"%ata.et1.*ublis+e"s.%e#aultVie1 %i& -u""ent.o"t 0s .t"in) = "" (# Not Vie1.tate2".o"t"3 (s Not+in) T+en -u""ent.o"t = Vie1.tate2".o"t"3 n! (# (# -u""ent.o"t..ta"ts4it+2e..o"t x*"ession3 T+en (# -u""ent.o"t. n!s4it+2"% .-"3 T+en .o"tVie1..o"t = e..o"t x*"ession lse .o"tVie1..o"t = e..o"t x*"ession & " % .-" n! (# lse .o"tVie1..o"t = e..o"t x*"ession n! (# Vie1.tate2".o"t"3 = .o"tVie1..o"t 7';"i!.%ata.ou"ce = .o"tVie1 7';"i!.%ataBin!23 n! .ub
Now that $ou+%e seen how to sort data in a ,ata-rid) $ou might want to allow in/"lace editing) as shown in the following e1am"le.
0elete #utton column. 7earrange the columns so that the Edit) 9"date) ,ancel #utton is first in the list and 0elete is second) as shown in the following illustration.
2. To 'ee" the e1am"le sim"le) disa#le sorting for this e1am"le #$ clic'ing the @eneral item and then unchec'ing the Allow Sorting chec' #o1. ,lic' *> to a""l$ the changes and close the dialog #o1. !. Switch to the code/#ehind module) and add the following line to Page0<oad) ;ust #efore the call to ,ata2indEF. The ,ataLey1ield "ro"ert$ controls which field is used as the "rimar$ 'e$ for editing) to allow $ou to identif$ the selected record=
7';"i!.%ata[e'Fiel! = "*ub<i!"
8. 9sing the same techni(ues $ou used to add the Sort=ommand e%ent handler in the last e1am"le) add an e%ent handler for the Edit=ommand e%ent. Add the following code to the e%ent handler=
8. 7';"i!.%ata.ou"ce = /ublis+e"%ata.et1.*ublis+e"s.%e#aultVie1
This code sets the Edit"tem"nde$ to the inde1 "assed in as a mem#er of the ,ata-rid=ommandE%ent/rgs o#;ect and re/#inds the grid. D. Add an e%ent handler for the =ancel=ommand e%ent) using the same techni(ues as in Ste" 8. Add the following code to the e%ent handler=
G. 7';"i!.%ata.ou"ce = /ublis+e"%ata.et1.*ublis+e"s.%e#aultVie1 1H. 7';"i!.%ata[e'Fiel! = "*ub<i!" 11. 7';"i!. !it(te&(n!ex = 51 7';"i!.%ataBin!23
This code sets the Edit"tem"nde$ to /2) indicating that no row should #e selected as an edit row. 22. Add an e%ent handler for the !pdate=ommand e%ent. Add the following code to the e%ent handler=
13. %i& *ubTable 0s /ublis+e"%ata.et.*ublis+e"s%ataTable 14. *ubTable = /ublis+e"%ata.et1.*ublis+e"s 18. %i& "o1To=*!ate 0s /ublis+e"%ata.et.*ublis+e"s6o1 1:. "o1To=*!ate = *ubTable.6o1s2e.(te&.(te&(n!ex3 1E. "o1To=*!ate.*ub<na&e = -T'*e2e.(te&.-ells233.-ont"ols2H3, < 1F. TextBox3.Text
7';"i!.%ataBin!23
This code u"dates the t$"ed dataset with the %alues from the datagrid and then calls the S4l,ata/dapter.!pdate method to u"date the #ac'/end data#ase. Because the code gets the %alues from the item "assed in as "art of the ,ata-rid=ommandE%ent/rgs) $ou ha%e to cast the control to the a""ro"riate t$"e ?in this case) Te$t2o$A to get its Te$t "ro"ert$) which contains the u"dated %alue. 2D. Add an e%ent handler for the ,elete=ommand e%ent. Add the following code to the e%ent handler=
$G. /ublis+e"%ata.et1.*ublis+e"s.6o1s.(te&2e.(te&.(te&(n!ex3.%elete23 3H. /ub0!a*te".=*!ate2/ublis+e"%ata.et13 31. 7';"i!.%ata.ou"ce = /ublis+e"%ata.et1.*ublis+e"s.%e#aultVie1 3$. 7';"i!. !it(te&(n!ex = 51 7';"i!.%ataBin!23
This code deletes the a""ro"riate row from the dataset and then calls !pdate on the data ada"ter. Note that if) as in the Pu#lishers ta#le) foreign 'e$ relationshi"s are associated with a gi%en ta#le) $ou might not #e a#le to delete a row if a row in a related ta#le is de"endent on that row. !!. Sa%e the "age and code/#ehind module. !8. Build the "ro;ect. !Q. Test the "age #$ right/clic'ing 0ata@ridEdit.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
You should now #e a#le to edit) u"date) and delete rows ?assuming there are no foreign 'e$ constraints that would "re%ent deletion) as there are in the case of the Pu#lishers ta#leA from the ta#le. IMPORTANT 3n/"lace editing in a ,ata-rid is not alwa$s the #est solution to "ro%iding editing. Alternati%el$) es"eciall$ when there are a num#er of columns) $ou could insert a lin' column to an edit form) or e%en use the Edit=ommand to lin' to a different %iew of the data for editing.
Using Data&ists
,ata<ists "ro%ide an e1cellent mi1 of #uilt/in functionalit$ and control o%er dis"la$ formatting. 9nli'e the ,ata-rid control) in which the rows are dis"la$ed one after the other in a ta#le format) the ,ata<ist can dis"la$ its items in multi"le columns and can dis"la$ rows horiGontall$ or %erticall$.
8. &hile Visual Studio .NET also has a Pro"ert$ Builder for 0ata.ist controls) sometimes it is useful to manuall$ create the code to #e dis"la$ed for each row in the 0ata.ist. 3n this case) $ou will start with a sim"le #it of code for the 3tem Tem"late) #ut it will #ecome more com"le1 as the e1am"le #ecomes more com"le1. To do this) switch to <TM. mode) and find the :asp:,ata<ist; o"ening tag) and then insert the following code #etween the o"ening and closing :asp:,ata<ist; tags=
8. ?(te&Te&*lateA :. E. ?+8A?IX %ataBin!e". ,al2-ontaine".%ata(te&,"title"3IA?B+8A ?b"BA ?B(te&Te&*lateA
D. Switch to the code window #$ "ressing FK) or #$ selecting View) then ,ode. Add the following "mports clauses at the to" of the code file=
G. (&*o"ts .'ste&.%ata (&*o"ts .'ste&.%ata..@l-lient
2 . Scroll down to the Page0<oad e%ent handler. 3n this e1am"le) $ou will use a ,ata/dapter and a ,ataSet to fill the ,ata<ist. 3nsert the following code=
11. %i& -onn.t" 0s .t"in) 1$. %i& 7'%. 0s Ne1 %ata.et23 13. -onn.t" = "se",e"=2local3QV.!otN TO!atabase=*ubsO" & < 14. "T"uste!<-onnection='es"
18. %i& .NL 0s .t"in) 1:. .NL = ". L -T U F697 Titles" 1E. %i& 7'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 1F. %i& 7'.@l0!a*te" 0s Ne1 .@l%ata0!a*te"2.NL,7'.@l-onn3 1G. 7'.@l-onn.9*en23 $H. T"' $1. $$. $3. 7'.@l0!a*te".Fill27'%.3 TitleList.%ata.ou"ce=7'%..Tables2H3.%e#aultVie1 TitleList.%ataBin!23
n! T"'
26. Sa%e the "age and code/#ehind module. 2K. Build the "ro;ect. 2D. Test the "age #$ right/clic'ing Titles0ata.ist2.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
The :"temTemplate; is #ut one of the tem"lates that $ou can use with the ,ata<ist control) #ut the$ all wor' similarl$. *ther tem"lates that $ou can define include the following=
Edit"temTemplate Formats the fields used when an item in the ,ata<ist is switched to Edit mode.
1ooterTemplate
Selected"temTemplate Sets the formatting for the item in the ,ata<ist that has #een selected #$ the user.
SeparatorTemplate Sets the format of the di%ider #etween items in the ,ata<ist.
.i'e a ,ata-rid) a ,ata<ist can #e set u" for in/"lace editing of %alues. This re(uires adding a <ink2utton or 2utton control to the "temTemplate with the =ommandName set to 4edit5I im"lementing an Edit"temTemplateI setting u" the e%ent handlers for the Edit=ommand) ,elete=ommand) =ancel=ommand) and !pdate=ommand e%entsI and ma""ing the e%ent handlers to the e%ents. &hen the Edit #utton for an item is clic'ed) the e%ent handler should set the Edit"tem"nde$ to the num#er of the item that was clic'ed) which can #e retrie%ed from the ,ata<ist=ommandE%ent/rgs "assed to the e%ent handler. The Edit"temTemplate should include <ink2utton or 2utton controls for the ,elete=ommand) =ancel=ommand) and !pdate=ommand) and e%ent handlers should #e added for each.
Using Re(eaters
The .epeater control lets $ou go hog/wild with tem"lates. 3f $ou can write it in <TM. andEor ser%er controls) $ou can "ut it into a tem"late. IMPORTANT Because of the wa$ that $ou add <TM. code to a .epeater control) it is "ossi#le to create a "erfectl$ %alid "age that will not dis"la$ "ro"erl$ in the Visual Studio .NET 0esigner window. The following listing shows how $ou can u"date the "re%ious e1am"le to wor' with a .epeater instead of a ,ata<ist. 3t adds a KeaderTemplate and a SeparatorTemplate to im"ro%e the loo' of the "age.
.a$out #$ right/clic'ing on the "age) selecting Pro"erties from the conte1t menu) and then setting the "age la$out to Flow .a$out. 8. Add a .a#el and a 7e"eater to the form. ,hange the Te$t "ro"ert$ of the .a#el to Binding t a Re(eater c ntr l. ,hange the 30 of the 7e"eater to TitleRe(eater. Q. Switch to <TM. mode) find the :asp:.epeater; o"ening tag) and then insert the following code #etween the o"ening and closing :asp:.epeater; tags=
:. E. F. G. 1H. 11. 1$. 13. 14. 18. 1:. 1E. 1F. 1G. $H. $1. $$. $3. $4. $8. $:. $E. $F. $G. ?(te&Te&*lateA ?tableA ?t"A ?t! "o1s*an="4"A ?i&) ali)n="to*" s"c='?IX %ataBin!e". ,al2-ontaine".%ata(te&, < "title<i!", "B@uicCsta"tBas**lusBi&a)esBtitle5YHZ.)i#"3 IA' A ?Bt!A ?Bt"A ?t"A ?t!A ?e&ATitleJ ?Be&A ?Bt!A ?t! no1"a*A ?IX %ataBin!e". ,al2-ontaine".%ata(te&, "title"3IA ?b"BA ?Bt!A ?Bt"A ?t"A ?t!A ?e&A/"iceJ ?Be&A ?Bt!A ?t! no1"a*A ?IX %ataBin!e". ,al2-ontaine".%ata(te&, "*"ice", <
3H. 31. 3$. 33. 34. 38. 3:. 3E. 3F. 3G. 4H. 41. 4$. 43. 44. 48. 4:. 4E. 4F. 4G.
"YHJcZ"3IA ?b"BA ?Bt!A ?Bt"A ?t"A ?t!A ?e&A-ate)o"'J ?Be&A ?Bt!A ?t! no1"a*A ?IX %ataBin!e". ,al2-ontaine".%ata(te&, "t'*e"3IA ?b"BA ?Bt!A ?Bt"A ?BtableA ?B(te&Te&*lateA ?Hea!e"Te&*lateA ?+4 st'le="bacC)"oun!5colo"Jsil,e"O"ATitles?B+4A ?BHea!e"Te&*lateA ?.e*a"ato"Te&*lateA ?+"A ?B.e*a"ato"Te&*lateA
Q . Switch to the code window #$ "ressing FK) or #$ selecting View) and then ,ode. Add the following "mports clauses at the to" of the code file=
81. (&*o"ts .'ste&.%ata (&*o"ts .'ste&.%ata..@l-lient
Q2. Scroll down to the Page0<oad e%ent handler. 3n this e1am"le) $ou will use a ,ata/dapter and a ,ataSet to fill the ,ata<ist. This code is identical to the code in the "re%ious e1am"le) e1ce"t that a .epeater is #ound to a 0ataSet rather than a ,ata<ist. 3nsert the following code=
83. %i& -onn.t" 0s .t"in)
84. %i& 7'%. 0s Ne1 %ata.et23 88. -onn.t" = "se",e"=2local3QV.!otN TO!atabase=*ubsOT"uste!<-onnection='e s" 8:. %i& .NL 0s .t"in) 8E. .NL = ". L -T U F697 Titles" 8F. %i& 7'.@l-onn 0s Ne1 .@l-onnection2-onn.t"3 8G. %i& 7'.@l0!a*te" 0s Ne1 .@l%ata0!a*te"2.NL,7'.@l-onn3 :H. 7'.@l-onn.9*en23 :1. T"' :$. :3. :4. 7'.@l0!a*te".Fill27'%.3 Title6e*eate".%ata.ou"ce=7'%..Tables2H3.%e#aultVie1 Title6e*eate".%ataBin!23
6K. Sa%e the "age and code/#ehind module. 6D. Build the "ro;ect. 6C. Test the "age #$ right/clic'ing Titles7e"eater.as"1) selecting Browse &ith) and then selecting Microsoft 3nternet E1"lorer. The resulting screen should loo' li'e the following illustration.
For the images in this e1am"le to #e dis"la$ed) the ASP.NET :uic'Start sam"les must #e installed on the machine on which the e1am"le is run.
All tem"lates a%aila#le to the ,ata<ist control can #e used with the .epeater control) and editing is handled the same with a .epeater as with a ,ata<ist.
9se an in/memor$ cache ,reate an instance of the ,ataSet class from the System.,ata of hierarchical data names"ace. Po"ulate the dataset #$ calling the 1ill method of the S4l,ata/dapter or +le,b,ata/dapter class. 0is"la$ read/onl$ data in Bind the control to a S4l,ata.eader or an +le,b,ata.eader. Be sure a #ound control to "ass the =ommand2eha%ior.=lose=onnection argument to the E$ecute.eader method when creating the datareader. This ensures that the underl$ing connection is closed when the datareader is closed. Bind data to a control Set the ,ataSource "ro"ert$ of the control to the ,ata.eader) ,ataDiew) or other data source) and then call the ,ata2ind method of the control ?or call the "age+s ,ata2ind methodA. Add an Edit) 9"date) ,ancel #utton column using the Pro"ert$ Builder) and add e%ent handlers for Edit) 9"date and ,ancel in code. Add a 0elete #utton column using the Pro"ert$ Builder) and add a ,elete e%ent handler in code. 9se a ,ata<ist control and set the .epeat=olumns attri#ute to the num#er of columns desired.
Edit #ound data in a ,ata-rid 0elete #ound data in a ,ata-rid 0is"la$ #ound data in multi"le columns
0is"la$ #ound data with 9se a .epeater control) and manuall$ add <TM. code) along with the greatest "ossi#le data/#inding directi%es. fle1i#ilit$
,hoose a #ase class for $our control. ,reate a names"ace for $our control. 7egister and use $our control in a "age. E1tend and aggregate e1isting controls. Maintain state in custom ser%er controls. <andle "ost#ac's.
You+%e s"ent the last two cha"ters stud$ing ASP.NET ser%er controls) Microsoft A0*.NET) and data/#inding. B$ now $ou+re "ro#a#l$ thin'ing) 4These ser%er controls sure are cool) #ut 3 wish 3 could create m$ own.5 &ell) wish no longerH 3n this cha"ter) $ou+ll learn how to create custom ASP.NET ser%er controls. There are nearl$ as man$ reasons for de%elo"ing custom ser%er controls as there are de%elo"ers) #ut generall$ these reasons fall into three main categories= reuse) s"ecialiGation) and maintenance. ,ustom ser%er controls ma'e reuse eas$. You can wra" u" a #unch of related functionalit$ and 93 elements into a control) and then reuse that control where $ou need that functionalit$. For e1am"le) $ou could create a ser%er control that enca"sulates all of the fields and %alidation logic necessar$ for user registration. Then) instead of rewriting that code e%er$ time $ou need a user registration screen) $ou sim"l$ add $our control to the "age. Speciali3ation refers to ta'ing an e1isting "iece of functionalit$) such as a ser%er control) and adding $our own customiGed functionalit$ to it. S"ecialiGation in ASP.NET ser%er controls is t$"icall$ done through inheritance. You s"ecialiGe through inheritance #$ inheriting from a class that "ro%ides most of the functionalit$ $ou want) and then adding additional functions or o%erriding e1isting ones and adding $our own im"lementation of those functions. The Te$t2o$Plus control sam"le later in this cha"ter "ro%ides an e1am"le of s"ecialiGation.
Finall$) custom ASP.NET ser%er controls sim"lif$ the maintenance of $our a""lications. *nce $ou ha%e de%elo"ed and tested a ser%er control) $ou can relia#l$ use it in man$ "laces. 3f $ou find a #ug in $our control) $ou can fi1 it in a single "lace ?the source class for $our controlA) and all $ou need to do to distri#ute the fi1 is re"lace the assem#l$ containing the fi1ed control. This is a ma;or im"ro%ement o%er reuse through include files ?or ha%ing no reuse at allA.
'reating a Na%es(ace
Each custom control must #elong to a names"ace. The @ .egister directi%e) which ma'es custom controls a%aila#le for use in a "age) has a Namespace attri#ute that is used to locate the control class to instantiate at runtime.
You create a names"ace using the Namespace 'e$word. 3n Microsoft Visual Basic .NET) $ou use #oth the Namespace 'e$word and a closing End Namespace 'e$word to define the sco"e of the names"ace.
Na&es*ace &'N. '-lass !e#initions, etc. )o insi!e t+e na&es*ace n! Na&es*ace
Note that if $ou are creating $our custom control using Microsoft Visual Studio .NET) the 30E will create the names"ace for $ou automaticall$. IMPORTANT Although Visual Studio .NET creates a names"ace for each new "ro;ect automaticall$) this is im"lemented differentl$ de"ending on the language $ou choose. For e1am"le) in a Visual Basic .NET &e# a""lication) the names"ace for the "ro;ect is defined #$ the .oot Namespace o"tion set in the Pro;ect Pro"erties dialog #o1 for the "ro;ect. This means that although $ou will not actuall$ see the Namespace 'e$word in $our class files) a names"ace will #e created when the class is com"iled during the #uild "rocess for the "ro;ect. 3n a Microsoft Visual ,J "ro;ect) the namespace 'e$word is added to class files and code/#ehind files automaticall$. 3n #oth languages) the default name for the names"ace is the name of the "ro;ect.
,reating a ,lass
Each custom ser%er control is defined in a class. You can ha%e more than one class defined in a single names"ace within a file) #ut the class is what defines the #oundar$ of the control. You can "ut multi"le controls within a single file) if $ou want. &hen $ou com"ile this file) all of the classes ?and the controls the$ re"resentA are com"iled into a single assem#l$. &hen $ou ha%e multi"le related controls) ha%ing them all in a single assem#l$ can ma'e de"lo$ing $our controls sim"ler. Similar to names"aces) classes in Visual Basic .NET are defined with a =lass E End =lass 'e$word "air that together define the sco"e of the class.
-lass &'-ont"ol 'Va"iables, *"oce!u"es, etc. n! -lass
As with names"aces) Visual Studio .NET automaticall$ ta'es care of creating a class for $ou when $ou create a new &e# ,ontrol .i#rar$ "ro;ect. This default class) which inherits from the &e#,ontrol class in the S$stem.&e#.93.&e#,ontrols names"ace) contains a "ro"ert$
declaration for a default Te1t "ro"ert$) as well as an o%erridden 7ender method that renders the contents of the Te1t "ro"ert$ to the #rowser. These default mem#ers are "ro%ided to gi%e $ou a head start in creating $our own control functionalit$. IMPORTANT The Standard Edition of Visual Basic .NET does not su""ort the &e# ,ontrol .i#rar$ "ro;ect t$"e. You can) howe%er) still add a &e# ,ustom ,ontrol to a &e# Pro;ect. 3f $ou want to create a standalone assem#l$ for $our custom control for reuse in other "ro;ects) $ou can sim"l$ remo%e the default &e# Form ?&e#Form2.as"1A from the &e# Pro;ect) and then add one or more &e# ,ustom ,ontrol classes to the "ro;ect for the control or controls $ou want to create.
/"otecte! 9,e""i!es .ub 6en!e"2B'Val out*ut 0s < .'ste&.4eb.=(.Ht&lText4"ite"3 'custo& "en!e"in) co!e n! .ub
As mentioned earlier) $ou can also call the .ender method of the #ase class in order to send its rendered out"ut to the #rowser. This is useful mainl$ for controls that inherit from classes that define their own 93) such as the Te$t2o$ class. Note that the call to the .ender method of the #ase class can a""ear an$where within the .ender method of the deri%ed control) allowing $ou to determine where in $our custom control the rendered out"ut of the #ase class will a""ear. The 9y2ase 'e$word in the following sni""et "ro%ides access to the mem#ers of the class from which the current class is inherited=
/"otecte! 9,e""i!es .ub 6en!e"2B'Val out*ut 0s < .'ste&.4eb.=(.Ht&lText4"ite"3 'custo& "en!e"in) co!e 7'Base.6en!e"2out*ut3 'a!!ition custo& "en!e"in) co!e, i# !esi"e! n! .ub
Note that since the ASP.NET runtime calls the o%erridden .ender method automaticall$ when the containing "age is re(uested) "assing in the necessar$ KtmlTe$t riter instance ?the output %aria#le in the "re%ious code sni""etA) $ou can sim"l$ "ass that instance as the argument to the .ender method in the #ase class.
2. *"en Visual Studio .NET and create a new &e# ,ontrol .i#rar$ "ro;ect. Name the "ro;ect 'ha(ter.4/.' ntr ls. &hen "ro;ect creation is com"lete) delete the default class) &e#,ustom,ontrol2.%#. 2. 7ight/clic' the "ro;ect in Solution E1"lorer) select Add) and then select Add ,om"onent. The dialog #o1 that a""ears has (uite a few li'el$ sounding o"tions ?including =omponent =lassA. Select the &e# ,ustom ,ontrol entr$ toward the #ottom of the list of o"tions. Name the control Te0tB 0Plus.&#) as shown in the following illustration.
The default class added #$ Visual Studio .NET is a com"letel$ functional ?though otherwise uninterestingA e1am"le control. 3t inherits from the eb=ontrol class) and it contains a string "ro"ert$ named Te$t. The .ender method sim"l$ writes the Te$t "ro"ert$ to the <TM. stream #eing written. *nce com"iled) the control will reside in the =hapter0>Q0=ontrols names"ace. Visual Studio .NET also automaticall$ adds metadata attri#utes to the class to "ro%ide design/time su""ort for the control. You+ll learn a#out these attri#utes later in this cha"ter. !. Begin customiGing the control #$ changing the class that the control inherits from to the Te$t2o$ class ?which also resides in the System. eb.!". eb=ontrols names"aceA in order to reuse its functionalit$. ,hange the "nherits statement that immediatel$ follows the class declaration from
(n+e"its .'ste&.4eb.=(.4eb-ont"ols.4eb-ont"ol
to
(n+e"its .'ste&.4eb.=(.4eb-ont"ols.TextBox
8. ,hange all occurrences of YTe$tZ ?the "ro"ert$ definitionA to :a#elTe0t) and all occurrences of .te0t ?the name of the "ri%ate instance %aria#le that contains the %alue of the "ro"ert$A to .la#elTe0t. The <abelTe$t "ro"ert$ will allow users of the control to set the te1t to #e dis"la$ed with the te1t #o1. Q. Add a call to render the #ase control. &ithin the .ender method) add the following line immediatel$ after the call to output. rite=
7'Base.6en!e"2out*ut3
This will cause the out"ut of the #ase Te$t2o$ control to #e rendered immediatel$ following the te1t of the <abelTe$t "ro"ert$. The com"lete code for the class is shown here. ?The attri#utes ha%e #een remo%ed for clarit$.A
/ublic -lass TextBox/lus (n+e"its .'ste&.4eb.=(.4eb-ont"ols.4eb-ont"ol %i& <labelText 0s .t"in) /"o*e"t' LabelText23 0s .t"in) ;et 6etu"n <labelText n! ;et .et2B'Val Value 0s .t"in)3 <labelText = Value n! .et n! /"o*e"t' /"otecte! 9,e""i!es .ub 6en!e"2B'Val out*ut 0s < .'ste&.4eb.=(.Ht&lText4"ite"3 out*ut.4"ite2LabelText3 7'Base.6en!e"2out*ut3 n! .ub n! -lass
6. Sa%e the class file) and #uild the "ro;ect. The control is now read$ for use.
The ne1t ste" is to actuall$ use the control. To ma'e using the control as eas$ as "ossi#le) $ou can add $our custom control to the Visual Studio .NET Tool#o1) as descri#ed in the following ste"s.
l# 0
2. &ithout closing the ,ha"terO2 O,ontrols "ro;ect) from the File menu) select Add Pro;ect then New Pro;ect. ,hoose the ASP.NET &e# A""lication t$"e) and name the "ro;ect 'ha(ter.4/. The 30E should automaticall$ load the &e#Form2.as"1 file of the new "ro;ect. 2. *"en the Tool#o1) right/clic' inside the Tool#o1) and then select AddE7emo%e 3tems from the dro"/down menu. The dialog #o1 shown in the following illustration will a""ear.
!. ,lic' the Browse #utton. 3n the resulting dialog #o1) na%igate to the #in folder under the ,ha"terO2 O,ontrols "ro;ect folder) select ,ha"terO2 O,ontrols.dll) and then clic' *>. You will #e returned to the "re%ious dialog #o1 with the Te$t2o$Plus control highlighted) as shown in the following illustration.
8. ,lic' *> to close the ,ustomiGe Tool#o1 dialog #o1. The Te$t2o$Plus control will #e added to the &e# Forms ta# of the Tool#o1 ?or whiche%er ta# was acti%e when $ou selected ,ustomiGe Tool#o1A. *f course) adding the control to the tool#o1 is onl$ "art of the "rocess. Ne1t $ou+ll learn how to use the custom control on a &e# Forms "age.
!. 0ou#le/clic' the Te$t2o$Plus control. This will add a co"$ of the control to &e#Form2.as"1. Select the control) and then use the Pro"erties window to change the <abelTe$t "ro"ert$ to Na%e,. The "age with the control should loo' li'e the following illustration.
8. Sa%e &e#Form2.as"1) and then #uild the "ro;ect. Q. 7ight/clic' &e#Form2.as"1) select Browse &ith) and then select Microsoft 3nternet E1"lorer. The out"ut should loo' similar to the following illustration.
&hile Visual Studio .NET ma'es it eas$ to add a control to a "age) there is no magic in%ol%ed. All of the things that Visual Studio .NET does while adding a com"onent could #e done without Visual Studio .NET. 3t is im"ortant to understand some of the things that Visual Studio .NET is doing. &hen $ou add a control #$ dou#le/clic'ing the control or #$ dragging it from the tool#o1 to the "age) an @ .egister directi%e is added at the to" of the .as"1 file) ;ust #elow the @ Page directi%e. 3n this e1am"le) the @ .egister directi%e loo's li'e the following line=
?IM 6e)iste" Ta)/"e#ix="cc1" Na&es*ace="-+a*te"<1H<-ont"ols" 0sse&bl'="-+a*te"<1H<-ont"ols" IA
Additionall$) the tag to create the control is added where%er the control has #een dro""ed ?or at the cursor location) in the case of dou#le/clic'ing the control in the Tool#o1A=
?cc1JTextBox/lus i!="TextBox/lus1" "unat="se",e"" LabelText="Na&eJ"A?Bcc1JTextBox/lusA
NOTE The default TagPrefi$ used #$ Visual Studio .NET is cc>) cc( and so on. You can manuall$ change the TagPrefi$ and then change the #eginning names"ace "art of the o"ening and closing tag from cc>: to whate%er $ou would li'e to use. Alternati%el$) $ou can use the TagPrefi$ attri#ute in the control to s"ecif$ a TagPrefi$ to #e used when the control is dro""ed onto a form in Visual Studio .NET. Add the following line to the Assem#l$3nfo.%# file in the control "ro;ect)
?asse&bl'JTa)/"e#ix2"-+a*te"<1H<-ont"ols","7'-ont"ols"3A
and then re#uild the "ro;ect. You might ha%e to remo%e the custom control from the tool#o1 and add it again as descri#ed earlier for the changes to ta'e effect in the Tool#o1.
9sing the "receding line) Te$t2o$Plus would ha%e a TagPrefi$ of 9y=ontrols rather than cc>. Pri%ate %s. Shared Assem#lies B$ default) all custom assem#lies that $ou create are "ri%ate. You ma'e them a%aila#le to a &e# a""lication #$ "lacing them in the #in director$ of the a""lication) where the$ are loaded #$ ASP.NET automaticall$. You can also share assem#lies across all clients on a machine #$ "lacing them in the @lo#al Assem#l$ ,ache ?@A,A. Barring an$ securit$ configuration in the assem#l$ that "re%ents it) assem#lies in the @A, can #e used #$ an$ managed a""lication on that machine. Pri%ate assem#lies allow $ou to limit the use of an assem#l$ to the a""lication in whose #in su#director$ the assem#l$ resides. Shared assem#lies allow $ou to reuse $our assem#lies in multi"le a""lications without needing to maintain a co"$ of an assem#l$ for each a""lication that uses it. To install an assem#l$ into the @A,) gi%e the assem#l$ a strong name ?signing it with a "u#lic 'e$) which $ou can generate with the sn.e1e .NET Framewor' utilit$A. Then add it to the @A, either #$ using the gacutil.e1e .NET Framewor' utilit$ or #$ dragging and dro""ing the assem#l$ into the 8windir8Nassem#l$ folder) which will add the assem#l$ to the @A, automaticall$. Note that when $ou de"lo$ assem#lies to the @A, for "roduction a""lications) Microsoft recommends using Microsoft &indows 3nstaller 2. to install the assem#l$ to the @A,) which "ro%ides roll#ac' "rotection) as well as automated uninstall. The &e# Setu" "ro;ect t$"e) a%aila#le in Visual Studio .NET Professional and later) will create a &indows 3nstaller "ac'age for $our &e# a""lication to which $ou can add a @lo#al Assem#l$ ,ache folder containing an$ controls $ou want to install in the @A,. The @A, su""orts %ersioning of assem#lies) so $ou can install multi"le %ersions of the same assem#l$ #$ setting its /ssemblyDersion/ttribute attri#ute. ,lients can then s"ecif$ which %ersion of an assem#l$ to load at runtime. This attri#ute is added to the Assem#l$3nfo.%# ?or Assem#l$3nfo.cs) for ,J "ro;ectsA file automaticall$ #$ Visual Studio .NET) with the %alue >.Q.?) which automaticall$ increments the #uild num#er of the assem#l$ each time the "ro;ect is #uilt.
add the missing "ro;ect to the solution #$ right/clic'ing the solution name) selecting Add and then E1isting Pro;ect. 2. Add a new &e# Form to the ,ha"terO2 "ro;ect. Name the form Add' ntr l.as(0) and change its page<ayout "ro"ert$ to $l w:a) ut. !. 0ou#le/clic' an$where on the "age and $ou will #e #rought to the Page0<oad e%ent handler in the code/#ehind module for Add,ontrol.as"1. Add the following code to the e%ent handler=
4. %i& TB/ 0s Ne1 -+a*te"<1H<-ont"ols.TextBox/lus23 8. TB/.LabelText = "/"o)"a&&atic -ont"ol LabelJ " 7e.-ont"ols.0!!2TB/3
6. Sa%e the changes) and then #uild the "ro;ect. Browse Add,ontrol.as"1. The result will #e an error informing $ou that 4,ontrol ^Octl + of t$"e ^Te1tBo1Plus\ must #e "laced inside a form tag with runatMser%er.5 The reason for this error is that the /dd method of the =ontrols collection actuall$ "laces the added control at the end of the controls collection. 3n this case) that means the control is "laced after the last <TM. tag in the "age ?which is re"resented in the =ontrols collection as an ASP.NET .iteral controlA. Because the Te$t2o$ control from which Te$t2o$Plus is deri%ed must #e "laced #etween the :form runat5Mser%erM; and :/form; tags) this code generates an e1ce"tion. There are a cou"le of solutions for this. You could use the /dd/t method rather than the /dd method to add the control to the =ontrols collection. /dd/t ta'es an additional "arameter) an inde1 into the arra$ of controls. This is not an ideal solution) since $ou need to 'now which inde1 to use. A #etter solution is to add an ASP.NET Placeholder control. K. Switch #ac' to Add,ontrol.as"1 #$ clic'ing on its ta# in the editor or #$ dou#le/clic'ing on Add,ontrol.as"1 in the Solution E1"lorer. 0rag a PlaceKolder control from the Tool#o1 onto the "age. D. Switch #ac' to the Page0<oad e%ent handler #$ dou#le/clic'ing an$where on the "age. ,hange the following line
7e.-ont"ols.0!!2TB/3
to
/laceHol!e"1.-ont"ols.0!!2TB/3
0ragging the PlaceKolder control onto the "age inserted it #etween the :form runat56ser%er7; and :/form; tags. Adding the Te$t2o$Plus control to the "laceholder+s =ontrols collection ensures that the control will #e rendered in the desired location ?and one that won+t generate an e1ce"tionHA.
C. Sa%e the changes) and then #uild the "ro;ect. &hen $ou #rowse Add,ontrol.as"1) the out"ut should loo' similar to the following illustration.
Add a "ro"ert$
2. *"en Te1tBo1Plus.%# in the ,ha"terO2 O,ontrols "ro;ect. 2. Add the following code to the to" of the file) ;ust #elow the "mports statements. The code creates an enumeration that defines the allowa#le %alues of the "ro"ert$ $ou+re going to add=
3. /ublic 4. nu& TextT'*es
-u""enc'Text
8. :. n!
K. ,o"$ the 0labelTe$t %aria#le definition and "aste a co"$ #elow the original. Modif$ the %aria#le name of the co"$ to .te0tT)(e) change the t$"e from String to Te0tT)(es) and then set its default %alue to Te0tT)(es.PlainTe0t. 9sing Te$tTypes as the datat$"e will restrict the allowa#le %alues for this "ro"ert$ to those defined #$ the Te$tTypes enumeration=
%i& <textT'*e 0s TextT'*es = TextT'*es./lainText
D. ,o"$ the <abelTe$t Property "rocedure and "aste a co"$ #elow the original. ,hange the ,efaultDalue attri#ute of this "ro"ert$ to Te0tT)(es.PlainTe0t) and then modif$ the "ro"ert$ "rocedure so that it loo's li'e the following code. ?The attri#utes ha%e #een omitted for clarit$.A
G. /"o*e"t' TextT'*e23 0s TextT'*es 1H. 11. 1$. 13. 14. 18. 1:. .et2B'Val Value 0s TextT'*es3 <textT'*e = Value n! .et n! /"o*e"t' ;et 6etu"n <textT'*e n! ;et
2K. Sa%e the file) #ut don+t close it $et. NOTE ,ontrar$ to what $ou might thin') the ,efaultDalue attri#ute $ou set in Ste" 8 does not actuall$ initialiGe the %alue of the %aria#le it is a""lied to. This attri#ute is actuall$ intended to allow de%elo"ers to (uer$ the metadata for a com"onent to determine the default %alue of a "ro"ert$ "rogrammaticall$) and reset it to that %alue if desired. Thus) if $ou want the %alue of a %aria#le to #e initialiGed to a "articular %alue) $ou should do so #$ initialiGing the %alue of the "ri%ate mem#er associated with the "ro"ert$) as shown in Ste" ! of the "receding e1am"le. You can find out more a#out this attri#ute at http://msdn.microsoft.com/library/enC us/cpref/html/frlrfsystemcomponentmodeldefault%alueattributeclasstopic.asp and http://support.microsoft.com/default.asp$Sscid5kb[enCus[#A>>AAR.
Add a method
2. Add the following code directl$ #elow the End Sub of the .ender method=
$. /"otecte! .ub Fo"&atText23 3. 4. 8. :. E. F. .elect -ase <textT'*e -ase TextT'*es.-u""enc'Text 7e.Text = Fo"&at-u""enc'27e.Text3 -ase TextT'*es.%eci&alText 7e.Text = Fo"&at2-on,e"t.To(nt3$27e.Text3, "F"3 n! .elect n! .ub
9sing the 1ormat=urrency and 1ormat methods ensures that the currenc$ and decimal formatting will wor' for multi"le locales) #ased on the <=", attri#ute of the @ Page directi%e. C. Add the following code to the .ender method) #efore the call to 9y2ase..ender=
1H. (# /a)e.(s/ostBacC T+en 11. 1$. 13. (# <textT'*e ?A TextT'*es./lainText T+en Fo"&atText23 n! (# n! (#
,hec'ing the "sPost2ack method "re%ents the te1t "ro"ert$ from #eing formatted at design time) since the .ender method of the control is called at design time each time a "ro"ert$ of the control is altered) in order to dis"la$ the design/time rendering of the control. 28. Sa%e the class file and re#uild the "ro;ect. 2Q. Add a new &e# Form to the ,ha"terO2 "ro;ect. ?Not the ,ha"terO2 O ,ontrols "ro;ect.A Name it TBP.'lient.as(0. 26. ,hange the page<ayout "ro"ert$ of the "age to $l w:a) ut. 2K. 9sing the Tool#o1) add an instance of the Te$t2o$Plus control to the "age) and then add a Button control to the "age.
2D. Set the Te$tType "ro"ert$ of the Te$t2o$Plus control to =urrencyTe$t) and the <abelTe$t "ro"ert$ to Enter a wh le nu%#er,. ?Note= 3f $ou don+t see the Te$tType "ro"ert$ listed) then) in the Solution E1"lorer) e1"and the 7eferences node under the ,ha"terO2 "ro;ect and delete the reference for ,ha"terO2 O,ontrols. 0elete the Te$t2o$Plus control $ou ;ust added to the form and add a fresh one. The reference for ,ha"terO2 O,ontrols will #e u"dated within the "ro;ect.A 2C. Sa%e TBPO,lient.as"1) #uild the "ro;ect) and then #rowse the "age. The out"ut should loo' similar to the following illustration.
2 . Enter *>/ in the te1t #o1) and then clic' the #utton. The resulting out"ut should loo' similar to the following illustration.
3f $ou add the .,30 attri#ute to the @ Page directi%e) and set its %alue to that of a countr$ other than the 9nited States ?such as 2 QK for the 9nited >ingdomA) the out"ut of the Te$t2o$Plus control will automaticall$ reflect the change) with no changes to the control necessar$.
<andling Post#ac's
As discussed "re%iousl$) a postback is the "rocess #$ which a &e# Forms "age su#mits an <TTP P+ST re(uest to itself in res"onse to some user action) such as clic'ing a #utton. The "ost#ac' itself is initiated #$ a control that causes the <TM. form to #e su#mitted) such as a client/side #utton element) the 2utton ser%er control) or a ser%er control that emits Fa%aScri"t code to su#mit the "age) such as the ,rop,own<ist control. ?Note that the ,rop,own<ist control emits Fa%aScri"t code for "osting #ac' the "age onl$ if its /utoPost2ack "ro"ert$ is set to True.A 3n this section we+ll #e focusing on the "rocessing of "ost#ac's) which occurs on the ser%er after the "ost#ac' has #een initiated #$ the user+s action. At some "oint) it is li'el$ that $ou will want to de%elo" a control that handles "ost#ac' data andEor e%ents. 3n this section) $ou+ll learn how to handle #oth. You ha%e the o""ortunit$ to wor' with "ost#ac' information during three "hases in the e1ecution of an ASP.NET &e# Forms "age= the <oadPost,ata "hase) the .aisePost,ata=hangedE%ent "hase) and the .aisePost2ackE%ent "hase. To wor' with the associated data or e%ents) $ou o%erride the associated method for the desired "hase. To o%erride the methods) $ou need to im"lement the "Post2ack,ataKandler interface) the "Post2ackE%entKandler interface) or #oth. "Post2ack,ataKandler defines the <oadPost,ata method and the .aisePost,ata=hangedE%ent method. "Post2ackE%entKandler defines the .aisePost2ackE%ent method. NOTE You im"lement interfaces in the fashion s"ecified #$ the language $ou+re using. As shown earlier) interfaces are im"lemented in Visual Basic .NET using the "mplements 'e$word. 9nli'e inheritance) which allows inheriting onl$ from a single #ase class) $ou can im"lement as man$ interfaces as $ou+d li'e. Se"arate each interface name with a comma) as follows=
(n+e"its -ont"ol (&*le&ents (/ostBacC%ataHan!le", (*ostBacC ,entHan!le"
Ta#le 2 /2 summariGes what the "ost#ac' methods are t$"icall$ used for.
Ta#le 4/34. PostbackCrelated 9ethods Method <oadPost,ata urpose .oads data "osted in form fields into local %aria#les for later "rocessing. 7eturns a Boolean indicating whether form %alues ha%e changed since the last "ost#ac'.
.aisePost2ack,ata=hangedE%ent ,alled if <oadPost,ata returns True. 9sed to res"ond to changes in "osted data. .aisePost2ackE%ent 9sed to "rocess data "osted #ac' from form fields) and raise an$ related e%ents from the control.
You+ll see e1am"les of how to wor' with "ost#ac' data in the registration and login control e1am"le that follows the ne1t section.
E%entName is the name of the e%ent #eing created. Notice that the e%ent is declared as t$"e E%ent<andler. NOTE The E%entKandler delegate is the #asis for all e%ent handler delegates. A delegate defines the signature for the e%entBthat is) it s"ecifies the arguments that an e%ent handler for that e%ent must acce"tBand acts as a t$"e/safe function "ointer to lin' the e%ent to its e%ent handler routine. The signature for E%entKandler is as follows=
/ublic %ele)ate .ub ,entHan!le"2sen!e" 0s 9bLect, e 0s ,ent0")s3
This means that an$ e%ent defined using the E%entKandler delegate must acce"t #oth an +b*ect and an E%ent/rgs argument=
.ub -ont"ol< ,ent2sen!e" 0s 9bLect, e 0s 'e,ent +an!lin) co!e n! .ub ,ent0")s3
You can create $our own e%ents that "ass data to their e%ent handlers #$ creating a custom class deri%ed from E%ent/rgs) then creating a new delegate for $our e%ent that s"ecifies $our custom class instead of E%ent/rgs as one of its arguments. Ne1t) $ou raise the e%ent ?#ased on the criteria $ou set u" within $our control to determine if the e%ent should #e calledA using the .aiseE%ents 'e$word as follows=
/ublic 9,e""i!able .ub 6aise/ostBacC ,ent2e,ent0")u&ent 0s .t"in)3 < (&*le&ents (/ostBacC ,entHan!le".6aise/ostBacC ,ent
(# .o&e x*"ession = T"ue T+en 6aise ,ent n! (# n! .ub ,entNa&e27e, ,ent0")s. &*t'3
This code is e1ecuted when the .aisePost2ackE%ent method is called during "age e1ecution. 3t tests whether SomeE$pression is True. 3f it is) it raises the E%entName e%ent) which is t$"icall$ handled outside of the control.
3n the "receding code) =ontrolName re"resents the name of the control in which the e%ent is defined) and E%entName re"resents the name of the e%ent. This s$nta1 is not re(uired) #ut it+s the naming con%ention t$"icall$ followed for e%ent handlers. You can call $our e%ent handlers whate%er $ou want) #ut following the =ontrolName0E%entName naming standard will ma'e $our code easier to read and maintain. A good e1am"le of this is the Page0<oad e%ent handler found in the code/#ehind module for e%er$ new &e# Form created in Visual Studio .NET. Since the Page class is deri%ed from the =ontrol #ase class) it e1"oses the <oad e%ent defined #$ the #ase class. Because Page0<oad is the most common e%ent for adding logic to a &e# Form) the tem"late for a &e# Form in Visual Studio .NET creates the handler for $ou #$ default. To wire the e%ent handler to $our control) $ou need to do one of two things) de"ending on whether $ou+re dealing with a declarati%e control or a control added "rogrammaticall$. For declarati%e controls ?those defined using a tag in the .as"1 fileA) add an +nE%entName attri#ute to the tag in which $ou declare the control) with the %alue set to the name of the e%ent handler routine=
?0./N T.B.J7'-ont"ol i!="7-1" 9nEventName="7-1< ,entNa&e" "unat="se",e""A
For "rogrammatic controls) $ou need to declare the control instance using the ithE%ents 'e$word) and then add a Kandles clause to the e%ent handler "rocedure for the control=
/"otecte! 4it+ ,ents 7'-tl 0s 7'Na&es*ace.7'-ont"ol
.ub 7'-tl<7' ,ent 2B'Val .ou"ce 0s 9bLect, B'Val e 0s Han!les 7'-ont"ol.7' ,ent
,ent0")s3 <
'
n! .ub
The good news is that Visual Studio "ro%ides su""ort for handling and wiring u" e%ents) including custom e%ents through the code editor and 3ntelliSense statement com"letion.
<oad Perform actions that need to #e "erformed for each re(uest once child controls ha%e #een created and initialiGed
,ata2inding Perform actions needed to e%aluate data/#inding e1"ressions associated with a control
Pre.ender Perform an$ modifications to the control or data necessar$ #efore rendering the control
!n<oad Perform cleanu" tas's #efore the control is remo%ed from memor$
To o%erride an e%ent e1"osed #$ an inherited class) $ou o%erride its associated +nE%entName method. For e1am"le) to o%erride the Pre.ender e%ent) $ou would use the following code in $our control. ?Note that the +nPre.ender method ta'es onl$ one argument) of t$"e E%ent/rgs.A
/"otecte! 9,e""i!es .ub 9n/"e6en!e"2e 0s ' ,ent +an!lin) co!e 7'Base.9n/"e6en!e"2e3 n! .ub ,ent0")s3
&hen $ou+re handling e%ents) it+s im"ortant to understand that the standard control e%ents and methods occur in a consistent order) including e%ents and methods related to "ost#ac's. This is im"ortant #ecause if $ou write code in an e%ent handler that occurs #efore the o#;ects mani"ulated #$ that code ha%e #een created and initialiGed) the results will #e un"redicta#le at #est. *ne of the most common "ro#lems relating to e%ent e1ecution order occurs when $ou add controls to the "age "rogrammaticall$. 3f $ou add those controls in the Page0<oad e%ent handler) the controls will not maintain their DiewState during "ost#ac's) #ecause the <oadDiewState e%ent) which ta'es care of re"o"ulating the state of controls on the "age) occurs before the <oad e%ent. Because the controls ha%e not $et #een created when the <oadDiewState e%ent is fired) the state for controls created in Page0<oad is discarded. 3f $ou want controls added "rogrammaticall$ to maintain DiewState) $ou should add those controls in the Page0"nit e%ent handler instead. The following is the order of the standard e%ents and methods for controls. "nitiali3e 0uring this "hase) the "nit e%ent is raised. <oadDiewState 0uring this "hase) controls that use DiewState are "o"ulated with data from the hidden 00D"E ST/TE field su#mitted with the re(uest. The <oadDiewState method can #e o%erridden to customiGe this "rocess. <oadPost,ata 0uring this "hase) data "osted #ac' with the re(uest is e%aluated and a""ro"riate action is ta'en. *%erride the <oadPost,ata method to write code for this "hase. <oad 0uring this "hase) the <oad e%ent is raised. .aisePost,ata=hangedE%ent 0uring this "hase) change e%ents are raised in res"onse to differences #etween the current state of a control+s mem#ers and the %alues su#mitted with the re(uest. *%erride the .aisePost,ata=hangedE%ent method to write code for this "hase. .aisePost2ackE%ent 0uring this "hase) e%ent handlers for ser%er/side e%ents are called. *%erride the .aisePost2ackE%ent method to write code for this "hase. Pre.ender 0uring this "hase) an$ modifications necessar$ #efore rendering are made. ,hanges made after this "hase will not #e sa%ed to DiewState. Sa%eDiewState 0uring this "hase) controls that use DiewState sa%e their data to the hidden 00D"E ST/TE field. The DiewState method can #e o%erridden to customiGe this "rocess.
.ender 0uring this "hase) the control and its children are rendered to the #rowser. ,ispose 0uring this "hase) an$ cleanu" of e1"ensi%e resourcesBfile handles) data#ase connections) and so onBis "erformed. *%erride the ,ispose method to write code for this "hase.
&hen o%erriding methods for inherited e%ents ?"nit) <oad) Pre.ender) and so onA) it+s usuall$ a good idea to call the #ase im"lementation of the e%ent+s method from within $our o%erridden %ersion. This ensures that an$ handlers associated with those e%ents are called. The s$nta1 for calling the #ase handler is as follows=
/"otecte! 9,e""i!es .ub 9nLoa!2e 0s ' ,ent +an!lin) co!e 7'Base.9nLoa!2e3 n! .ub ,ent0")s3
(&*o"ts .'ste&.4eb..ecu"it'
!. ,hange the class+s "nherits statement so that the control inherits from the System. eb.!".=ontrol class) rather than System. eb.!". eb=ontrol. ?Attri#utes ha%e #een omitted for clarit$.A
4. /ublic -lass 6e)Lo)in (n+e"its .'ste&.4eb.=(.-ont"ol
Q. 0elete the ,efaultPropertyE6Te$t7F attri#ute that "recedes the class definition) since we won+t #e using a Te$t "ro"ert$ in the control=
:. ?Toolbox%ata2"?YHZJ6e)Lo)in "unat=se",e"A?BYHZJ6e)Lo)inA"3A < /ublic -lass 6e)Lo)in
K. Sa%e 7eg.ogin.%#. NOTE 3n the "receding e1am"le) a Visual Basic line continuation character?OAwas added to the end of the attri#ute in Ste" 8 to allow the class declaration to a""ear on the ne1t line) enhancing reada#ilit$. B$ default) the Visual Basic .NET 30E "laces #oth the attri#ute and class definition on the same line. Now that $ou+%e got the control class created) let+s continue #$ adding mem#er %aria#les for storing the username) "assword) and other im"ortant information for the control) including a 9ode "ro"ert$ that will use an Enumeration as its t$"e.
Q. Add a Boolean mem#er %aria#le called 0display.eg<ink. This %aria#le will #e used to determine whether to dis"la$ a h$"erlin' that will allow the user to switch the control to 7egister mode. The default is 1alse.
6. Between the "mports statements and the class definition) add the following code) which creates an Enumeration for the 0mode mem#er %aria#le=
E. /ublic F. G. n! nu& 6e)Lo)in7o!e
An Enumeration allows $ou to s"ecif$ the %alid %alues for a gi%en "ro"ert$ or argument that uses the enumeration as its t$"e. The enumeration is also used #$ Visual Studio .NET to "ro%ide 3ntelliSense statement com"letion for mem#ers of that t$"e. Enumerations can ma'e wor'ing with %aria#les and "ro"erties less error/"rone #$ limiting in"ut to onl$ %alid %alues. 2 . Add a new mem#er %aria#le called 0mode) with the t$"e .eg<ogin9ode. Set the %alue of the mem#er to .eg<ogin9ode.<ogin=
%i& <&o!e 0s 6e)Lo)in7o!e = 6e)Lo)in7o!e.Lo)in
22. Modif$ the default Te$t "ro"ert$ "rocedure ?which was added automaticall$ when the file was createdA to loo' li'e this=
1$. ?Bin!able2False3, B"o1sable2False3A < 13. 6ea!9nl' /"o*e"t' .tatus7essa)e23 0s .t"in) 14. 18. 1:. ;et 6etu"n <status7essa)e n! ;et n! /"o*e"t'
This e1"oses 0status9essage as a "u#lic "ro"ert$) so that the consuming "age can read it. The "ro"ert$ is mar'ed as .ead+nly #ecause it is used onl$ to communicate information from the control to the "age. Because the "ro"ert$ %alue cannot #e set) we add the 2indable and 2rowsable attri#utes to the "ro"ert$ declaration and set the %alue of each to 1alse. This "re%ents the "ro"ert$ from #eing a%aila#le for data#inding) and from showing u" in the "ro"ert$ #rowser. 2K. Sa%e 7eg.ogin.%#. The ne1t "art of the "rocess is dis"la$ing a 93 for the control. As with the Te$t2o$Plus control) $ou+ll do this #$ o%erriding the .ender method. But in this case) the actual rendering will #e
"assed off to s"ecialiGed methods for the two modes= .ogin and 7egister. Two different rendering techni(ues will #e demonstrated. The first rendering techni(ue) which will #e used for rendering the login 93) will ma'e use of the methods and "ro"erties e1"osed #$ the KtmlTe$t riter class) an instance of which is "assed to the .ender method #$ the ASP.NET runtime. These include the rite<ine) rite2eginTag) riteEndTag) and rite/ttribute methods) which allow $ou to construct <TM. elements "rogrammaticall$) "iece #$ "iece) as well as the ,efaultTabString and Self=losingTagEnd "ro"erties. 9sing these methods and "ro"erties allows $ou to render code that will #e more reada#le ?hence) easier to trou#leshootA on the client end of the re(uest) without ha%ing to remem#er a language/s"ecific esca"e character for ta#s or linefeeds. The code "roduced using this techni(ue is a little heftier than that "roduced using the second techni(ue. The second rendering techni(ue) which will #e used for rendering the registration 93) will ma'e use of the String2uilder utilit$ class in the System.Te$t names"ace. 9se the String2uilder class whene%er $ou need to do a significant num#er ?generall$ Q or moreA of string concatenations. Since string concatenation results in a new String o#;ect #eing created #ased on the string andEor literals #eing concatenated) it can carr$ significant "erformance o%erhead. 9sing a String2uilder can significantl$ im"ro%e "erformance #$ allowing $ou to mani"ulate string data without ha%ing to create and allocate s"ace for a new String o#;ect with each mani"ulation. &ith this techni(ue) we create a String2uilder instance and call its /ppend method to add to the out"ut string. 9nli'e the techni(ue using the KtmlTe$t riter class) this techni(ue re(uires using constants li'e %bTab and %b=r<f ?or their literal e(ui%alentsA for formatting the rendered code.
Note that $ou use the 0mode mem#er %aria#le to decide which 93 to dis"la$. 3f the control is in .ogin mode ?the defaultA) the login 93 will #e dis"la$ed. 3f the control is in 7egister mode) the registration 93 will #e dis"la$ed. Note also that #oth 93 rendering
functions ?which $ou+ll add ne1tA acce"t the KtmlTe$t riter instance "assed into the .ender method as an argument. This will #e used in these functions to render out"ut to the #rowser. 2 . ,reate two "ri%ate Sub "rocedures) ,isplay<ogin!") and ,isplay.eg!"=
11. /"i,ate .ub %is*la'Lo)in=(2B'Val 4"ite" 0s Ht&lText4"ite"3 1$. 13. 14. 18. /"i,ate .ub %is*la'6e)=(2B'Val 4"ite" 0s Ht&lText4"ite"3 1:. n! .ub n! .ub
$$. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < $3. $4. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
$8. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < $:. $E. $F. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "=se"na&eJ "3
$G. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 3H. 31. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3
3$. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 33. 34. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
3G. 4"ite".4"iteBe)inTa)2"in*ut"3 4H. 4"ite".4"ite0tt"ibute2"na&e", 7e.=ni@ue(%3 41. 4"ite".4"ite0tt"ibute2"t'*e", "text"3 4$. 4"ite".4"ite0tt"ibute2",alue", <use"Na&e3 43. 4"ite".4"iteLineNoTabs2Ht&lText4"ite"..el#-losin)Ta) n!3 44. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 48. 4:. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3
81. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 8$. 83. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
84. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 88. 8:. 8E. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "/ass1o"!J "3
8F. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 8G. :H. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3
:1. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < :$. :3. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
:F. 4"ite".4"iteBe)inTa)2"in*ut"3 :G. 4"ite".4"ite0tt"ibute2"na&e", 7e.=ni@ue(%3 EH. 4"ite".4"ite0tt"ibute2"t'*e", "*ass1o"!"3 E1. 4"ite".4"iteLineNoTabs2Ht&lText4"ite"..el#-losin)Ta) n!3 E$. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < E3. E4. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3
EG. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < FH. F1. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
F$. 4"ite".4"ite2Ht&lText4"ite".%e#aultTab.t"in) & < F3. F4. F8. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in)3
F:. 4"ite".4"iteBe)inTa)2"in*ut"3 FE. 4"ite".4"ite0tt"ibute2"na&e", 7e.=ni@ue(%3 FF. 4"ite".4"ite0tt"ibute2"t'*e", "button"3 FG. 4"ite".4"ite0tt"ibute2",alue", ".ub&it"3 GH. 4"ite".4"ite0tt"ibute2"9n-licC", "La,asc"i*tJ " & < G1. /a)e.;et/ostBacC ,ent6e#e"ence27e, "Lo)in"33
G4. G8.
G:. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < GE. GF. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t!A"3
GG. 4"ite".4"ite2Ht&lText4"ite".%e#aultTab.t"in) & < 1HH. 1H1. 1H$. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in)3
1H3. 4"ite".4"iteBe)inTa)2"in*ut"3 1H4. 4"ite".4"ite0tt"ibute2"na&e", 7e.=ni@ue(%3 1H8. 4"ite".4"ite0tt"ibute2"t'*e", ""eset"3 1H:. 4"ite".4"iteLineNoTabs2Ht&lText4"ite"..el#-losin)Ta) n!3 1HE. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < 1HF. 1HG. Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3
11$. (# <!is*la'6e)LinC = T"ue T+en 113. 114. 118. 11:. 11E. 11F. 11G. 1$H. 1$1. 1$$. 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t"A"3 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?t! cols*an='$'A"3 4"ite".4"iteBe)inTa)2"a"3 4"ite".4"ite0tt"ibute2"na&e", "6e)LinC"3 4"ite".4"ite0tt"ibute2"+"e#", "La,asc"i*tJ " & < /a)e.;et/ostBacC ,ent6e#e"ence27e, "%is*la'6e)=("33 4"ite".4"ite2Ht&lText4"ite".Ta)6i)+t-+a"3
4"ite".4"ite2"6e)iste""3 4"ite".4"ite n!Ta)2"a"3 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt!A"3 4"ite".4"iteLine2Ht&lText4"ite".%e#aultTab.t"in) & < Ht&lText4"ite".%e#aultTab.t"in) & "?Bt"A"3
This code uses methods and "ro"erties e1"osed #$ the KtmlTe$t riter class to write out the desired <TM. out"utBin this case) an <TM. ta#le for formatting) with two te1t #o1es for in"ut) as well as an <TM. #utton for "osting #ac' the control+s contents) and a reset #utton. The code also uses these methods and "ro"erties to write white s"ace ?ta#s and carriage returnsA to the control out"ut. &hile this is not strictl$ necessar$ from a functional stand"oint) adding white s"ace can ma'e the rendered code easier to read) which can hel" in trou#leshooting when something isn+t wor'ing ?not that that e%er ha""ens) rightUA. Note the call to -etPost2ackE%ent.eference in the code for rendering the su#mit #utton. This allows a %alue ?4<ogin5A to #e "assed when the "age is "osted #ac') so that the code that "rocesses the "ost#ac' 'nows which #utton was clic'ed. Note also the "f statement that chec's the %alue of the 0display.eg!" mem#er %aria#le. 3f the %alue of this %aria#le is True) a h$"erlin' will #e rendered to allow the user to switch to registration mode. 2!2. Add the following code to ,isplay.eg!". This code creates a String2uilder o#;ect) concatenates the <TM. out"ut) and then writes the contents of the String2uilder to the #rowser.
133. '-"eate .t"in)Buil!e" #o" concatenatin) out*ut st"in) 134. %i& .B9ut 0s Ne1 .'ste&.Text..t"in)Buil!e"23 138. 13:. .B9ut.0**en!2,bTab & "?tableA" & ,b-"L#3 13E. .B9ut.0**en!2,bTab & ,bTab & "?t"A" & ,b-"L#3 13F. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 13G. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "=se"na&eJ " & ,b-"L#3
14H. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 141. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 14$. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?in*ut t'*e='text' " & < 143. 144. "na&e='" & 7e.=ni@ue(% & "' ,alue='" & < 7e.<use"Na&e & " 'BA" & ,b-"L#3
148. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 14:. .B9ut.0**en!2,bTab & ,bTab & "?Bt"A" & ,b-"L#3 14E. .B9ut.0**en!2,bTab & ,bTab & "?t"A" & ,b-"L#3 14F. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 14G. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "/ass1o"!J " & ,b-"L#3 18H. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 181. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 18$. .B9ut.0**en!2,bTab & ,bTab & ,bTab & < 183. 184. "?in*ut t'*e='*ass1o"!' " & "na&e=' " & 7e.=ni@ue(% & "'BA" & ,b-"L#3
188. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 18:. .B9ut.0**en!2,bTab & ,bTab & "?Bt"A" & ,b-"L#3 18E. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 18F. .B9ut.0**en!2,bTab & ,bTab & ,bTab & < 18G. "-on#i"& /ass1o"!J " & ,b-"L#3
1:H. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 1:1. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 1:$. .B9ut.0**en!2,bTab & ,bTab & ,bTab & < 1:3. 1:4. "?in*ut t'*e='*ass1o"!' " & < "na&e=' " & 7e.=ni@ue(% & "'BA" & ,b-"L#3
1:8. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 1::. .B9ut.0**en!2,bTab & ,bTab & "?Bt"A" & ,b-"L#3 1:E. .B9ut.0**en!2,bTab & ,bTab & "?t"A" & ,b-"L#3 1:F. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3
1:G. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?in*ut t'*e='button' " & < 1EH. 1E1. 1E$. ",alue='.ub&it' 9n-licC=""Lsc"i*tJ " & < /a)e.;et/ostBacC ,ent6e#e"ence27e, "6e)iste""3 """A" & ,b-"L#3 & <
1E3. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 1E4. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?t!A" & ,b-"L#3 1E8. .B9ut.0**en!2,bTab & ,bTab & ,bTab & < 1E:. "?in*ut t'*e='"eset'BA" & ,b-"L#3
1EE. .B9ut.0**en!2,bTab & ,bTab & ,bTab & "?Bt!A" & ,b-"L#3 1EF. .B9ut.0**en!2,bTab & ,bTab & "?Bt"A" & ,b-"L#3 1EG. .B9ut.0**en!2,bTab & "?BtableA" & ,b-"L#3 1FH. '.en! t+e out*ut to t+e b"o1se". 4"ite".4"ite2.B9ut3
Note that as with the ,isplay<ogin!" method) a call to -etPost2ackE%ent.eference is used to generate the code necessar$ for initiating the "ost#ac') including indicating which #utton was clic'ed ?in this case) 4.egister5A. 2D2. Sa%e 7eg.ogin.%#.
At this "oint) if $ou were to #uild the ,ha"terO2 O,ontrols "ro;ect and add the control to a "age) it would render the login 93 and could "ost#ac' the data in its form fields) #ut that+s a#out it. To ta'e things further) $ou+ll need to add "ost#ac' handling and custom e%ent code.
Q. 0irectl$ #elow the "nherits 'e$word) add an "mplements statement to im"lement the "Post2ack,ataKandler and "Post2ackE%entKandler interfaces=
D. 3m"lement the <oadPost,ata method defined in the "Post2ack,ataKandler interface to load the "osted %alues into the local %aria#les. Visual Studio .NET ma'es this "rett$ eas$. Fust select 3PostBac'0ata<andler from the dro"/down list at the to" left corner of the code editor ?,lass NameA) and then select .oadPost0ata from the dro"/down list at the to" right corner ?Method NameA) as shown in the following illustration. The definition of the method will #e automaticall$ inserted into the file. The return %alue of this function determines whether the .aisePost,ata=hangedE%ent method is called on this control.
-ase "%is*la'6e)=(" <&o!e = 6e)Lo)in7o!e.6e)iste" -ase "Lo)in" 6esult = Loa!Lo)in/ost%ata2ne1Values3 -ase "6e)iste"" <&o!e = 6e)Lo)in7o!e.6e)iste" 6esult = Loa!6e)iste"/ost%ata2ne1Values3 n! .elect
6etu"n 6esult
The code ta'es the collection of form field %alues "osted from the form and "laces them into the string arra$ newDalues. 3t then declares a Boolean for the return %alue of the <oadPost,ata method. Ne1t) it uses the 00EDENT/.-!9ENT form field) which is automaticall$ sent with each "ost#ac' ?than's to our use of -etPost2ackE%ent.eferenceA) to decide how to "rocess the loaded data ?or) in the case of the %alue ,isplay.eg!") to dis"la$ the registration 93 and forego further "rocessingA. 2!. After adding the code in Ste" 8) $ou+ll notice that two "arts of the code are underlined with s(uiggl$ #lue lines. This is #ecause these are calls to two methods $ou ha%en+t added $et) <oad<oginPost,ata and <oad.egisterPost,ata. Add declarations for these methods #elow the <oadPost,ata method=
$4. /"i,ate Function Loa!Lo)in/ost%ata2B'Val ne1Values 0s .t"in)233 < $8. $:. $E. $F. $G. /"i,ate Function Loa!6e)iste"/ost%ata2B'Val ne1Values 0s .t"in)233 < 3H. 31. n! Function 0s Boolean n! Function 0s Boolean
38. 3:. ')et t+e =se"Na&e 3E. ne1=se"Na&e = 2ne1Values2H33 3F. ' )et t+e /ass1o"! 3G. ne1/ass1o"! = 2ne1Values2133 4H. 41. '6etu"n T"ue i# ,alues +a,e c+an)e! since last *ostbacC 4$. (# 22Not ne1=se"Na&e = <use"Na&e3 9" < 43. 44. 48. 4:. 4E. 4F. 2Not ne1/ass1o"! = <*ass1o"!33 T+en <use"Na&e = ne1=se"Na&e <*ass1o"! = ne1/ass1o"! 6etu"n T"ue lse 6etu"n False n! (#
The "receding code retrie%es the username and "assword entered #$ the user) chec's to see if the$+%e changed since the last "ost#ac') and then loads them into local %aria#les for later "rocessing. 3f the %alues ha%e changed since the last "ost#ac') the code returns True) which will cause the Post2ack,ata=hangedE%ent method to #e called later in the "rocessing of the re(uest. 8C. Add the following code to <oad.egisterPost,ata=
8H. ')et t+e =se"Na&e 81. <use"Na&e = 2ne1Values2H33 8$. ' )et t+e /ass1o"! 83. <*ass1o"! = 2ne1Values2133 84. ' )et t+e /ass1o"! -on#i"&ation 88. <*ass1o"!-on#i"& = 2ne1Values2$33 8:. 8E. '4e !on't ex*ect t+e !ata to c+an)e #"o& "e@uest 8F. ' to "e@uest +e"e, so 1e'll Lust "etu"n False
6etu"n False
QC. 9sing the same techni(ue as $ou did for <oadPost,ata) im"lement the .aisePost,ata=hangedE%ent method. Although this control does not ma'e use of this method) $ou are still re(uired to im"lement it #ecause it is defined as "art of the "Post2ack,ataKandler interface. 6 . 3m"lement the .aisePost2ackE%ent method #$ selecting "Post2ackE%entKandler from the ,lass Name dro"/down list) and .aisePost2ackE%ent from the Method Name dro"/ down list.
:1. /ublic .ub 6aise/ostBacC ,ent2B'Val e,ent0")u&ent 0s .t"in)3 < :$. :3. n! .ub (&*le&ents .'ste&.4eb.=(.(/ostBacC ,entHan!le".6aise/ostBacC ,ent
<&o!e = 6e)Lo)in7o!e.6e)iste"
,ent0")s. &*t'3
Fo"&s0ut+entication..et0ut+-ooCie2<use"Na&e, False3 n! (#
The "receding code uses the 0mode %aria#le to decide how to "rocess the data that was loaded in the <oadPost,ata method) calling either Derify=redentials or Sa%e=redentials. You+ll add #oth of these methods in the ne1t section. 3f the authentication or registration succeeds) the a""ro"riate success e%ent is raised. .i'ewise) if the authentication or registration "rocessing fails) the a""ro"riate failure e%ent is raised. Note that if authentication succeeds) the code also calls the 1orms/uthentication.Set/uth=ookie method) "assing in the username of the current user. D6. Sa%e 7eg.ogin.%#. Now it+s time to get down to the nitt$ gritt$= %erif$ing and sa%ing user credentials. The techni(ue the control will use to store credentials is a sim"le -M. file. The -M. file) which will #e automaticall$ created #$ the control the first time the control is used) will contain the date a user registered) a username) and an M0Q hashed %alue re"resenting a "assword. Sa%ing new registration information will #e "erformed #$ the Sa%e=redentials method. Verif$ing the user+s credentials against e1isting credentials will #e "erformed #$ the Derify=redentials method. Finall$) the control will use a =reate2lank!sers1ile utilit$ method to create the initial -M. file. IMPORTANT You should not use this control for restricting access to critical information. This control is designed onl$ to limit anon$mous #rowsing of content. Because the control will allow users to register on their own) it "ro%ides onl$ a means of limiting who can access content on $our site. Note that $ou could further restrict access to content #$ adding a field to the -M. file for whether the user is a""ro%ed or ena#led. B$ setting this field to 1alse #$ default) $ou could choose whether someone who registered could access content before he or she logged in.
G. 1H. 11. 1$. 13. 14. 18. 1:. 1E. 1F. 1G. $H. $1. $$. $3. $4. $8. $:. $E. $F. $G. 3H. 31. 3$. 33. 34. 38. lse
=se"na&e & " '"3.Len)t+ A H T+en (# <*ass1o"! ?A "" 0n! < <*ass1o"! = <*ass1o"!-on#i"& T+en %i& Ne1Lo)in 0s %ata6o1 = Lo)in%..Tables2H3.Ne16o1
Ne1Lo)in2"use"na&e"3 = <use"Na&e Ne1Lo)in2"*ass1o"!"3 = < Fo"&s0ut+entication. < Has+/ass1o"!Fo".to"in)(n-on#i)File2<*ass1o"!, < "7%8"3 Ne1Lo)in2""e)iste"%ate"3 = < %ateTi&e.To!a'.To.+o"t%ate.t"in) Lo)in%..Tables2H3.6o1s.0!!2Ne1Lo)in3 Lo)in%..4"ite^&l2/a)e..e",e".7a*/at+2"=se"s.x&l"33 <status7essa)e = "6e)ist"ation succee!e!. " & < "/lease lo) in." 6etu"n T"ue lse <status7essa)e = "No *ass1o"! ente"e! " & < "o" *ass1o"!s !o not &atc+. /lease "e5ente". " 6etu"n False n! (#
<status7essa)e = "0n i!entical use"na&e exists. " & < "/lease c+oose anot+e". " 6etu"n False n! (# n! Function
The Sa%e=redentials method uses the .eadXml method of the ,ataSet class to read the current 9sers.1ml file) then chec's to see if there+s alread$ a user in the file with the same
name as that entered #$ the user in the registration form. 3f not) the method then chec's to ma'e sure that #oth the "assword and confirmation "assword %alues are identical. 3f the$ are) the method creates a new row from the dataset) stores the username and a hashed %ersion of the "assword) adds the row to the dataset) and then uses the ,ataSet+s riteXml method to sa%e the u"dated ta#le to the file. *nce all of this succeeds) the method sets the status9essage "ro"ert$ to indicate that registration succeeded) and returns True ?which causes the .egSuccess e%ent to #e raisedA. 3f the username alread$ e1ists) or if the "asswords don+t match) the status9essage "ro"ert$ is set to an a""ro"riate message) and the method returns 1alse ?causing the .eg1ailure e%ent to #e raisedA. !6. Add the following code to 7eg.ogin.%#) after the Sa%e=redentials method=
3E. /"i,ate Function 3F. Ve"i#'-"e!entials2B'Val =se"na&e 0s .t"in), < 3G. 4H. 41. 4$. 43. 44. 48. 4:. 4E. 4F. 4G. 8H. 81. 8$. 83. 84. 88. 8:. 8E. 8F. (# Lo)in%..Tables2H3..elect2"use"na&e=' " & < =se"na&e & " '"3.Len)t+ A H T+en %i& Lo)in6o123 0s %ata6o1 = < Lo)in%..Tables2H3..elect2"use"na&e=' " & < =se"na&e & " '"3 (# Lo)in6o12H3.(te&2"*ass1o"!"3.To.t"in) = < Fo"&s0ut+entication. < Has+/ass1o"!Fo".to"in)(n-on#i)File2/ass1o"!, < "7%8"3 T+en <status7essa)e = "-"e!entials Vali!ate!. " T"' Lo)in%..6ea!^&l2/a)e..e",e".7a*/at+2"=se"s.x&l"33 -atc+ #n# 0s .'ste&.(9.FileNotFoun! xce*tion -"eateBlanC=se"sFile23 Lo)in%..6ea!^&l2/a)e..e",e".7a*/at+2"=se"s.x&l"33 n! T"' B'Val /ass1o"! 0s .t"in)3 0s Boolean %i& Lo)in%. 0s %ata.et = Ne1 %ata.et23
8G. :H. :1. :$. :3. :4. :8. ::. :E. :F. :G. lse
<status7essa)e = "=se"na&e not #oun!. " & < "Ha,e 'ou "e)iste"e!P " <!is*la'6e)LinC = T"ue 6etu"n False n! (# n! Function
The Derify=redentials method also uses the .eadXml method to fill the dataset from 9sers.1ml. 9nli'e Sa%e=redentials) howe%er) the code in Derify=redentials is wra""ed in a TryG=atch #loc'. This is #ecause Derify=redentials will alwa$s #e called first) and if a 1ileNot1oundE$ception is thrown) the =reate2lank!sers1ile method is called to create the 9sers.1ml file. *nce the dataset has #een filled) the code selects the row that matches the "ro%ided username ?if it e1istsA and chec's the stored "assword hash against the hashed %ersion of the "assword entered #$ the user. 3f the "asswords match) the status9essage "ro"ert$ is set to indicate success) and the method returns True ?which results in the /uthSuccess e%ent #eing raisedA. 3f either the username does not e1ist in the -M. file) or the "asswords do not match) the status9essage "ro"ert$ is set to indicate these "ro#lems) and the method returns 1alse ?resulting in the /uth1ailure method #eing raisedA. K . Add the following code to 7eg.ogin.%#) after the Derify=redentials method=
E1. /ublic .ub -"eateBlanC=se"sFile23 E$. E3. E4. E8. E:. EE. EF. Ne1^&l.4"iteLine2"?use"sA"3 'use" #iel! !esc"ibes a sin)le use" Ne1^&l.4"iteLine2" ?use"A"3 %i& Ne1^&l 0s .'ste&.(9..t"ea&4"ite" = < .'ste&.(9.File.-"eateText2/a)e..e",e".7a*/at+2"=se"s.x&l"33
Ne1^&l.4"iteLine2"
'*ass1o"! #iel! contains 7%8 +as+ ,alue Ne1^&l.4"iteLine2" ?*ass1o"!A" & <
Fo"&s0ut+entication.Has+/ass1o"!Fo".to"in)(n-on#i)File2"*ass1o"!", F:. FE. FF. FG. "7%8"3 & "?B*ass1o"!A"3 Ne1^&l.4"iteLine2" ?Buse"A"3
The =reate2lank!sers1ile method allows the control to create its own storage file without re(uiring the inter%ention of the user. The method uses a Stream riter to create and write to a te1t file. &hen finished writing the default elements) the method closes the Stream riter. TIP To create the 9sers.1ml file) the ASPNET user account must ha%e write access to the director$ in which the "age that uses the .eg<ogin control resides ?in our case) the root of the ,ha"terO2 "ro;ectA. 3f) for securit$ reasons) $ou do not wish to "ro%ide the ASPNET account with these "ermissions) $ou can create the file manuall$ and "ro%ide the ASPNET account with write "ermissions to this file alone) rather than the entire director$. You can also "ro%ide the ASPNET account with write "ermissions to the director$ tem"oraril$) run a "age containing the control) and then remo%e the write "ermissions. 3f $ou create the file manuall$) ma'e sure the file e1tension is .1ml) not .1ml.t1t ?which can ha""en if $ou ha%e file e1tensions hidden in &indows E1"lorerA) or $ou will recei%e errors when the control attem"ts to write to the file. 3f the file is created #$ the ASP.NET "rocess) #$ default it will ha%e full "ermissions granted to the ASPNET user account under which ASP.NET is run) as well as to the SYSTEM account and the Administrators grou". <owe%er) the 9sers grou" will ha%e onl$ 7ead _ E1ecute and 7ead "ermissions on the file. This means that unless $ou are logged on as an Administrator) $ou will not #e a#le to manuall$ edit the 9sers.1ml file. C . Sa%e 7eg.ogin.%#) and #uild the ,ha"terO2 O,ontrols "ro;ect. 3f $ou entered all of the code correctl$) the "ro;ect should #uild correctl$) and the control will #e read$ to use. 3f
$ou ha%e an$ "ro#lems) $ou can chec' $our code against the finished e1am"le that is a%aila#le with the "ractice files for this cha"ter. The last "art of the "rocess is using the control in a "age. To use the control) $ou+ll need to create a new &e# Forms "age) create the control ?either declarati%el$ or "rogrammaticall$A) and set u" handlers for its e1"osed e%ents. You+ll also need to configure $our a""lication to use Forms Authentication) create a sam"le "age to #e "rotected #$ Forms Authentication) and configure $our a""lication to "re%ent #rowsing of the 9sers.1ml file created #$ the control.
This forces an$ re(uests for content that re(uire authentication to #e redirected to .ogin.as"1 if an authentication coo'ie is not "resent. 3t also s"ecifies that the coo'ie is #oth encr$"ted and su#;ect to %alidation to "rotect its contents. D. Add a :location; section with an :authori3ation; configuration element that loo's li'e the following. This code should go #etween the o"ening :configuration; tag and the o"ening :system.web; tag=
G. ?location *at+="/"otect7e.as*x"A 1H. 11. 1$. 13. 14. ?s'ste&.1ebA ?aut+o"iDationA ?!en' use"s="P"BA ?Baut+o"iDationA ?Bs'ste&.1ebA ?BlocationA
This section disallows an$ re(uests for the file ProtectMe.as"1 ?which $ou+ll add to the "ro;ect shortl$A #$ users who ha%e not #een authenticated. Than's to the
:authentication; section) such re(uests will #e redirected to .ogin.as"1 ?which $ou+ll also add to the "ro;ect shortl$) and which will ma'e use of the 7eg.ogin controlA. 2Q. Sa%e &e#.config) #ut don+t close it $et. The "receding ste"s will effecti%el$ "rotect the file ProtectMe.as"1 from unauthoriGed access ?once $ou+%e created it) an$wa$A) #ut the$ lea%e out something %er$ im"ortant= "rotecting the -M. file that will contain the user information. B$ default) -M. files are #rowsa#le from within a &e# a""lication. All someone needs to 'now is the name of the file to %iew its contents. &hile the .eg<ogin control does ma'e use of M0Q hashing to "rotect "asswords) it+s still a good idea to "re%ent #rowsing of the 9sers.1ml file. The ne1t set of ste"s will show $ou how to do this.
Secure 9sers.1ml
2. *"en the &e#.config file for the ,ha"terO2 "ro;ect if it+s not alread$ o"en. 2. Add the following section #etween the :system.web; and :/system.web; tags=
3. ?+tt*Han!le"sA 4. ?a!! ,e"b="U" *at+="=se"s.x&l"
8. t'*e=".'ste&.4eb.Htt*Fo"bi!!enHan!le""BA ?B+tt*Han!le"sA
This will "re%ent an$ re(uests for a file named 9sers.1ml within the sco"e of the a""lication from #eing fulfilled #$ "assing the re(uest to the Kttp1orbiddenKandler KttpKandler class. This is the same techni(ue used #$ ASP.NET to "rotect the glo#al.asa1) we#.config) and other non/#rowsa#le files. 6. Sa%e &e#.config. K. *"en the 3nternet 3nformation Ser%ices administration tool ?$ou must either #e logged in as an administrator) or use the 7un As feature to run the tool using an account with administrator rightsA) drill down to the ,ha"terO2 "ro;ect a""lication) right/clic' the a""lication icon) and then select Pro"erties. The "ro"erties dialog #o1 for the ,ha"terO2 a""lication will #e dis"la$ed) as shown in the following illustration.
D. ,lic' the ,onfiguration #utton. The A""lication ,onfiguration dialog #o1 will #e dis"la$ed) as shown in the following illustration.
C. 3n the Ma""ings ta#) which is selected #$ default) clic' the Add #utton. The AddEEdit A""lication E1tension Ma""ing dialog #o1 will #e dis"la$ed) as shown in the following illustration.
2 . ,lic' the Browse #utton) change the Files *f T$"e dro"/down to 6)na%ic :in9 :i#raries ;N.dll<) #rowse to the location of as"netOisa"i.dll ?#$ default 8windir 8NMicrosoft.NETNFramewor'N8%ersion8A) select it) and clic' the *"en #utton. 22. &hen $ou are returned to the AddEEdit A""lication E1tension Ma""ing dialog #o1) clic' in the E1ecuta#le= te1t #o1. ?This ste" is re(uired in Microsoft &indows -P to ena#le the *> #utton) as descri#ed in Microsoft >nowledge Base article :!2KC8D.A 22. 3n the E1tension= te1t #o1) t$"e .0%l. 2!. ,lic' the *> #utton to add the ma""ing. *nce the ma""ing has #een added) the A""lication ,onfiguration dialog #o1 will loo' similar to the following illustration.
28. ,lic' the *> #utton to close the A""lication ,onfiguration dialog #o1) and then ,lic' *> again to close the Pro"erties dialog #o1. Now) an$one attem"ting to %iew 9sers.1ml will see the message shown in the following illustration.
Note that if $ou want to "rotect an$ file named 9sers.1ml in an$ a""lication on the machine) add the :add; element in Ste" 2 to the :httpKandlers; element in machine.config rather than to &e#.config) and $ou should add the ma""ing of the .1ml e1tension to the ASP.NET 3SAP3 "rocess using the Master Pro"erties in 33S) and a""l$ the changes to all &e# sites when "rom"ted. >ee" in mind that there is some o%erhead in ha%ing ASP.NET "rocess all re(uests for .1ml files) so $ou should onl$ do this on a machine/wide #asis if $ou intend to use the .eg<ogin control across man$ a""lications or sites on a machine. IMPORTANT 3t+s worth reiterating at this "oint that although this e1am"le uses hashed "asswords) and $ou+%e added "rotection for the 9sers.1ml file) this e1am"le should #e used onl$ for "rotecting content from casual anon$mous #rowsing. 3f $ou ha%e content for which securit$ is critical) $ou should consider storing user credentials in a more secure location) such as a data#ase) and im"lementing SS. encr$"tion for the login "age to ensure that usernames and "asswords aren+t ca"tured in transit.
(&*o"ts .'ste&.4eb..ecu"it'
!. Switch #ac' to ProtectMe.as"1 and add a .a#el and a Button to the "age) and set the #utton+s Te$t "ro"ert$ to : g Out) as shown in the following illustration.
8. 0ou#le/clic' the #utton) and then add the following code to the 2utton>0=lick e%ent handler=
8. Fo"&s0ut+entication..i)n9ut23 6es*onse.6e!i"ect26e@uest.6a1="l3
This code will remo%e the authentication coo'ie) and then redirect the re(uest to the same "age) which will result in the user #eing redirected to the login "age. 6. Add the following code) which dis"la$s the username of the currentl$ logged/in user) to the Page0<oad e%ent handler=
Label1.Text = "Lo))e! in as " & =se".(!entit'.Na&e & "."
K. Sa%e and close #oth the code/#ehind module and the &e# Form. Now $ou+re finall$ read$ to create $our login "age. 3n this ne1t "rocedure) $ou+ll create a login "age) add the 7eg.ogin control to the Visual Studio .NET Tool#o1) add the control to the "age) and add the necessar$ e%ent handlers to handle the control+s e%ents.
K. Add a <abel control #elow the .eg<ogin control) and set its Disible "ro"ert$ to 1alse. .ea%e a little s"ace %erticall$ #etween the .eg<ogin control and the <abel control. D. 7ight/clic' in an em"t$ area of the "age and select View ,ode. C. Fust a#o%e the Page0<oad declaration) add a declaration for a Boolean named ,o.edirect. ?You+ll use this later when handling the /uthSuccess e%ent handler.A
%i& %o6e!i"ect 0s Boolean = False
2 . Select 7eg.ogin2 from the ,lass Name dro"/down list) and then select AuthSuccess from the Method Name dro"/down list. This will add an e%ent handler for the /uthSuccess e%ent) as shown in the following illustration.
This will signal that the "age should redirect users to the "age the$ originall$ re(uested. ?You+ll add the code for this in a few ste"s.A Because the .eg<ogin control automaticall$ sets the Forms authentication coo'ie when authentication succeeds) this re(uest will #e allowed. 28. 9sing the same techni(ue as in Ste" 2 ) add the /uth1ailure e%ent handler) and then add the following code to it=
18. Label1.Fo"e-olo" = .'ste&.%"a1in).-olo".6e! 1:. Label1.Text = 6e)Lo)in1..tatus7essa)e Label1.Visible = T"ue
2K. 9sing the same techni(ue as in Ste" 2 ) add the .egSuccess e%ent handler) and then add the following code to it=
1F. Label1.Fo"e-olo" = .'ste&.%"a1in).-olo".;"een 1G. Label1.Text = 6e)Lo)in1..tatus7essa)e Label1.Visible = T"ue
2 . 9sing the same techni(ue as in Ste" 2 ) add the .eg1ailure e%ent handler) and then add the following code to it=
$1. Label1.Fo"e-olo" = .'ste&.%"a1in).-olo".6e! $$. Label1.Text = 6e)Lo)in1..tatus7essa)e Label1.Visible = T"ue
2!. Select ?*%erridesA from the ,lass Name dro"/down list) and then select *nPre7ender from the Method Name dro"/down list. Add the following code) which redirects the user if ,o.edirect is True=
$4. (# %o6e!i"ect T+en < 6es*onse.6e!i"ect26e@uest.Nue"'.t"in)2"6etu"n="l"33
2Q. To "re%ent the .a#el2 te1t from #eing dis"la$ed when $ou switch to 7egister mode) add the following to the Page0<oad e%ent handler=
Label1.Visible = False
26. Sa%e the &e# Form and code/#ehind) and then #uild the ,ha"terO2 "ro;ect. Now that $ou+%e finished $our login "age) $ou+ll test it #$ attem"ting to access ProtectMe.as"1) which is "rotected from anon$mous access #$ the :location; section $ou added to &e#.config earlier.
2. &ithout entering a username or "assword) clic' the Su#mit #utton. The out"ut shown should loo' li'e the following illustration.
At this "oint) if it did not alread$ e1ist) the 9sers.1ml file has #een created #$ the control. !. ,lic' the 7egister lin'. The out"ut shown should loo' li'e the following illustration.
8. Enter NewUser for the 9sername and (assw rd ?case sensiti%eA for the Password and ,onfirm Password fields) and then clic' Su#mit. The out"ut shown should loo' li'e the following illustration.
Q. Enter (assw rd ?case sensiti%eA for the Password field) and then clic' Su#mit. You will #e redirected to ProtectMe.as"1) and the out"ut shown should loo' li'e the following illustration.
6. ,lic' the .og *ut #utton. You will #e redirected to .ogin.as"1. K. E1"eriment with the registration interface) such as entering an e1isting username or omitting the "asswords) and see how the control res"onds.
Maintaining State
3n the "re%ious e1am"les) data used #$ the controls has #een stored in local %aria#les. For man$ controls) this can wor' ;ust fine. But unless $ou e1"licitl$ retrie%e su#mitted %alues and re"o"ulate the mem#er controls with these %alues) as $ou did in the <oadPost,ata method of the "re%ious e1am"le) the mem#er controls will #e #lan' when the "age is "osted #ac' to the ser%er and the results are returned. 3n man$ cases) $ou might want to maintain the state of the constituent controls of $our custom ser%er control) without e1"licitl$ ha%ing to write code to test for new %alues and re"o"ulate the mem#er controls with each "ost#ac'. To sol%e this "ro#lem) ASP.NET "ro%ides a state/management facilit$ called DiewState. This is "ro%ided #$ an instance of the State2ag class of the System. eb.!" names"ace. You store data in DiewState as 'e$E%alue "airs) which ma'es wor'ing with it (uite similar to wor'ing with session state. To add a %alue to DiewState or modif$ an e1isting %alue) $ou can sim"l$ s"ecif$ the item+s 'e$ and assign a %alue as follows=
Vie1.tate2"7'[e'"3 = 7'Value
IMPORTANT For a control to use DiewState) it must #e contained within a :form; #loc' with the runat56ser%er7 attri#ute set. Note that $ou can also add items to DiewState using the /dd method of the State2ag class) and remo%e them using the .emo%e method. You can clear all DiewState %alues with the =lear method. 7etrie%ing %alues from DiewState is a #it more in%ol%ed. Since the "tem "ro"ert$ of the State2ag class returns an o#;ect) $ou will need to cast the o#;ect to the "ro"er t$"e #efore "erforming an$ t$"e/s"ecific actions on it or "assing it to another "rocedure that e1"ects a "articular t$"e. The s$nta1 for retrie%ing a string %alue is as follows=
%i& 7'.t"in) 0s .t"in)
The sim"lest wa$ to automate the "rocess of sa%ing control state to DiewState is to su#stitute DiewState items for the local mem#er %aria#les for storing the %alues of "ro"erties of the control. IMPORTANT 9sing DiewState has #oth "erformance and securit$ im"lications) #ecause all of the information stored in DiewState is round/tri""ed to the client as a #ase68 encoded string. The siGe of the DiewState hidden field can #ecome (uite large with controls that contain a lot of data) which can ha%e a negati%e im"act on "erformance. You might want to disa#le DiewState for these controls #$ setting their EnableDiewState "ro"ert$ to 1alse. Because the DiewState field is sent as a te1t string) $ou should ne%er use DiewState to store information such as connection strings) ser%er file "aths) credit card information) or other sensiti%e data. 7emem#er that once the DiewState has #een sent to the client) it would #e fairl$ sim"le for a hac'er to decode the string and retrie%e an$ data contained within. 0on+t count on #ase68 encoding to "rotect sensiti%e data sent to the client. The designers of ASP.NET added a cou"le of features to hel" "re%ent a malicious user from ca"turing the DiewState of a "age and attem"ting to use it to mount an attac' #$ either modif$ing the DiewState on the client and resu#mitting the "age) or #$ attem"ting to re"la$ a ca"tured re(uest ?2/clic' attac'sA. The EnableDiewState9ac attri#ute of the @ Page directi%e) which is set to True #$ default) runs a machine authentication chec' on the DiewState field when the "age is resu#mitted to ensure that its contents were not changed on the client. To "re%ent 2/clic' attac's) a new Page/le%el "ro"ert$ has #een introduced in %ersion 2.2 of the .NET Framewor' called DiewState!serLey. You can set the DiewState!serLey "ro"ert$ ?during Page0"nit) attem"ts to set this "ro"ert$ later will result in an errorA to a string %alue that uni(uel$ identifies the user to "re%ent these t$"es of attac's. This %alue can #e chec'ed when the "age is "osted #ac'. 3f it does not match the %alue $ou set) $ou should not "rocess the re(uest. Finall$) the DiewState of controls is sa%ed #etween the firing of the Pre.ender and .ender e%ents) so an$ changes to control state that $ou want to sa%e in DiewState must #e made during the Pre.ender e%ent. ,hanges made to control state after the Pre.ender e%ent will not #e sa%ed to DiewState.
user interface for the custom ser%er control. ,om"ositional controls should also im"lement the "Naming=ontainer interface) which "ro%ides a new naming sco"e for the constituent controls) to ensure that their names are uni(ue within the "age. Most often $ou+ll want to inherit from the =ontrol class for custom controls that use com"osition) rather than from a more functional class. Most of the functionalit$ in a com"ositional control is "ro%ided #$ its constituent controls) allowing $ou to e1"ose a minimum of functionalit$ from the #ase class. E1"osing less functionalit$ from the #ase class can hel" a%oid une1"ected #eha%ior in $our control from su"erfluous #ase class mem#ers. For e1am"le) a control that inherits from eb=ontrol e1"oses a num#er of 93/related mem#ers) such as 2ack=olor) 2order=olor) KeightP and idthWmem#ers that might not #e desira#le in $our custom control.
O&erriding CreateChildCo"trols
The =reate=hild=ontrols method is su#stituted for the .ender method in com"ositional controls. A sam"le =reate=hild=ontrols method loo's li'e this=
/"otecte! 9,e""i!es .ub -"eate-+il!-ont"ols23 %i& 7'Label 0s Ne1 Label23 7'Label.Text = "LabelJ " 7e.-ont"ols.0!!27'Label3 %i& 7'Text 0s Ne1 TextBox23 7e.-ont"ols.0!!27'Text3 %i& 7'Button 0s Ne1 Button23 7'Button.Text = ".ub&it" 7e.-ont"ols.0!!27'Button3 n! .ub
3t is not necessar$ in a com"ositional ser%er control to call the 7ender method) #ecause all of the indi%idual controls added to the ,ontrols collection will ta'e care of rendering themsel%es during the 7ender stage of "age "rocessing. 3f $ou want to mani"ulate controls after the$+%e #een added to the =ontrols collection) $ou can access them either #$ numeric inde1) as shown in the following code sni""et) or #$ calling the 1ind=ontrol method of the =ontrol class and "assing in the 30 of the control $ou want to mani"ulate.
%i& 7'Text 0s TextBox = -ont"ols213
3m"lementing "Naming=ontainer
,om"ositional controls should alwa$s im"lement the "Naming=ontainer interface. This interface does not contain an$ "ro"ert$ or method declarations. 3t sim"l$ creates a new naming sco"e for the current control to ensure that the names of child controls are uni(ue within the "age. As with an$ interface in Visual Basic .NET) inheriting the "Naming=ontainer interface is done using the "mplements 'e$word) which a""ears as "art of the class definition) on the line immediatel$ following the "nherits statement for the class. 3f $ou include an "mports statement for the System. eb.!" names"ace) $ou can omit the names"ace in the "nherits and "mplements statements shown here=
/ublic -lass -o&*-ont"ol (n+e"its .'ste&.4eb.=(.-ont"ol (&*le&ents .'ste&.4eb.=(.(Na&in)-ontaine" 'class co!e n! -lass
3n the following code listing) which re"licates the functionalit$ of the Te$t2o$Plus control) $ou+ll see e1am"les of #oth o%erriding the =reate=hild=ontrols method and im"lementing "Naming=ontainer. The .%# file for this controlBas well as a &e# Form that uses the com"ositional %ersion of the controlBis a%aila#le in the "ractice files for this cha"ter.
TextBox/lus<-o&*.,b
(&*o"ts .'ste&.-o&*onent7o!el (&*o"ts .'ste&.4eb.=(
?%e#ault/"o*e"t'2"Text"3, < Toolbox%ata2"?YHZJTextBox/lus<-o&* "unat=se",e"A" & < "?BYHZJTextBox/lus<-o&*A"3A < /ublic -lass TextBox/lus<-o&* (n+e"its -ont"ol (&*le&ents (Na&in)-ontaine"
?Bin!able2T"ue3, -ate)o"'2"0**ea"ance"3, < %e#aultValue2"Label"3A < /"o*e"t' LabelText23 0s .t"in) ;et nsu"e-+il!-ont"ols23 6etu"n <label.Text n! ;et
?Bin!able2T"ue3, -ate)o"'2"0**ea"ance"3, < %e#aultValue2"/lainText"3A < /"o*e"t' TextT'*e23 0s TextT'*es ;et nsu"e-+il!-ont"ols23 6etu"n <textT'*e n! ;et
?Bin!able2T"ue3, -ate)o"'2"0**ea"ance"3, %e#aultValue2" "3A < /"o*e"t' Text23 0s .t"in) ;et nsu"e-+il!-ont"ols23 6etu"n <textBox.Text n! ;et
/"otecte! 9,e""i!es .ub -"eate-+il!-ont"ols23 <label = Ne1 Label23 7e.-ont"ols.0!!2<label3 <textBox = Ne1 TextBox23 7e.-ont"ols.0!!2<textBox3 n! .ub
/"otecte! 9,e""i!es .ub 9n/"e6en!e"2B'Val e 0s .'ste&. ,ent0")s3 (# /a)e.(s/ostBacC T+en (# <textT'*e ?A TextT'*es./lainText T+en Fo"&atText23 n! (# n! (# n! .ub
/"otecte! .ub Fo"&atText23 nsu"e-+il!-ont"ols23 .elect -ase <textT'*e -ase TextT'*es.-u""enc'Text 7e.Text = Fo"&at-u""enc'27e.Text3 -ase TextT'*es.%eci&alText 7e.Text = Fo"&at2-on,e"t.To(nt3$27e.Text3, "F"3 n! .elect n! .ub
n! -lass
0etermine when to use a &e# ser%ice. ,reate a &e# ser%ice. Ad%ertise and locate &e# ser%ices. ,onsume a &e# ser%ice.
Pre%ious cha"ters ha%e focused on the creation of ASP.NET &e# Forms) as well as the technologies that ma'e ASP.NET de%elo"ment "ossi#le and the technologies that ma'e it sim"le to (uic'l$ create ro#ust) feature/rich &e# a""lications. -M./#ased &e# ser%ices are another im"ortant and useful "art of ASP.NET. Toda$) &e# ser%ices are not a %er$ well/understood technolog$. This is "artl$ #ecause of inaccurate and su"erficial re"orting from the media) who descri#e &e# ser%ices as e%er$thing from su#scri"tion software to a "ro"rietar$ "lot #$ Microsoft to ta'e o%er the 3nternet. These stories might sound great in "rint) #ut the$ are #ased on misunderstanding and ignorance of this "otentiall$ re%olutionar$ technolog$.
Some of the solutions for these difficulties ha%e included creating custom &e# front ends for e1isting functionalit$) or using "ro"rietar$ communications andEor "ac'aging technologies to #ridge the ga" #etween s$stems. The former solution wor'ed well in some situations) #ut the organiGation hosting the a""lication had to create and maintain a 93 for the functionalit$ that the$ made a%aila#le) as well as creating a front end for an$ additional functionalit$ added later. Moreo%er) this 93 might or might not full$ meet the needs of their e1isting andEor future clients. The use of "ro"rietar$ communications or #ridging software t$"icall$ meant greater e1"ense) reliance on a single %endor) and de"endence on that %endor+s maintenance and u"grades. -M./ #ased &e# ser%ices address #oth of these issues s(uarel$) allowing "rogrammatic functionalit$ to #e e1"osed without the need for a custom &e#/#ased 93) and without the need for "ro"rietar$ #ridging software. &e# ser%ices are discrete units of "rogrammatic functionalit$ e1"osed to clients %ia standardiGed communication "rotocols and data formats) namel$ <TTP and -M.. These "rotocols and formats are #oth well understood and widel$ acce"ted. ?&hile -M. is still a relati%el$ immature technolog$) it has ra"idl$ gained acce"tance in the industr$ #ecause of its "romise as a #ridging technolog$.A B$ communicating o%er <TTP) &e# ser%ices o%ercome the "ro#lem of communicating across the 3nternet and across cor"orate firewalls without resorting to "ro"rietar$ solutions that re(uire additional communications "orts to #e o"ened to e1ternal access. Because &e# ser%ices use -M. for the formatting of re(uests and res"onses) the$ can #e e1"osed from and consumed #$ an$ "latform that can format and "arse an -M. message. This allows -M./ #ased &e# ser%ices to #ring together dis"arate "ieces of functionalit$Be1isting or new) internal or e1ternal to an organiGationBinto a coherent whole. The following illustration shows how -M./#ased &e# ser%ices can #ring together a %ariet$ of a""lications and "latforms. Note that #ecause -M./#ased &e# ser%ices can communicate o%er standard "rotocols such as <TTP) the$ can wor' o%er firewalls. 3n addition to the interactions shown here) ser%er/to/ser%er &e# ser%ices calls are also "ossi#le.
A client accesses &e# ser%ices #$ calling into a listener that is a#le to "ro%ide a contract to descri#e the &e# ser%ice and also "rocesses incoming re(uests or "asses them on to other a""lication logic and "asses an$ res"onses #ac' to the client. The following illustration shows how a &e# ser%ice a""lication can #e la$ered. You can also use &e# ser%ices to access #oth legac$ logic and new a""lication logic) or to wra" legac$ logic for access #$ a &e# ser%ice.
A contract that s"ecifies the "arameters and data t$"es it e1"ects) as well as the return t$"es ?if an$A that it sends to callers A facilit$ for locating the &e# ser%ice or a means of disco%ering &e# ser%ices offered #$ a gi%en ser%er or a""lication) and the descri"tions of those ser%ices
The ne1t se%eral sections will e1amine creating) ad%ertising) locating) and consuming &e# ser%ices from the stand"oint of an ASP.NET &e# de%elo"er.
=lassName is the name of the class that contains the &e# ser%ice methods. The s$nta1 for declaring a &e# ser%ice in which the code that defines the class and methods resides in a com"iled class is
?IM 4eb.e",ice -lass="Na&es*aceNa&e.-lassNa&e,0sse&bl'Na&e" IA
NamespaceName is the name of the names"ace in which the class for the &e# ser%ice resides) =lassName is the name of the class that contains the &e# ser%ice methods) and /ssemblyName is the name of the assem#l$ that contains the com"iled code for the &e# ser%ice. This assem#l$ should reside in the #in director$ of the &e# a""lication in which the .asm1 file resides. The NamespaceName "ortion of the =lass attri#ute is o"tional if $ou ha%e not s"ecified a names"ace for $our class) #ut it is good "ractice to alwa$s s"ecif$ a names"ace for $our classes. The /ssemblyName "ortion of the =lass attri#ute is also o"tional) since ASP.NET will search the #in director$ for the assem#l$ if no assem#l$ name is "ro%ided. <owe%er) $ou should alwa$s "ro%ide an assem#l$ name to a%oid the "erformance im"act of doing a search the first time the &e# ser%ice is accessed.
NOTE 9nli'e using code/#ehind with ASP.NET &e# Forms) $ou cannot use the src attri#ute with a &e# ser%ice. This means that $ou must "recom"ile the code/#ehind class that is to #e used as the #asis for the &e# ser%ice) either manuall$ using the command/line com"iler or #$ #uilding a Microsoft Visual Studio .NET &e# Ser%ice a""lication. IMPORTANT Visual Studio .NET "ro%ides a default framewor' for an$ &e# ser%ice $ou create inside its 30E. The following section descri#es the s"ecifics of creating a &e# ser%ice class. 3n the section that follows) $ou+ll create e1am"les using Visual Studio .NET) and therefore man$ of the tas's re(uired to get a #asic &e# ser%ice class will #e in "lace with the default class created in the 30E. Nonetheless) it is im"ortant to understand the #ase classes and attri#utes used to create a &e# ser%ice.
/ublic -lass -lassNa&e (n+e"its 4eb.e",ice '7et+o!s ex*ose! b' t+e 4eb se",ice n! -lass
Inheriting fr % ,e2Ser%ice
3n this s$nta1 e1am"le) an "mports statement im"orts the System. eb.Ser%ices names"ace. This names"ace contains the classes and attri#utes that "ro%ide ASP.NET+s #uilt/in su""ort for -M./ #ased &e# ser%ices. 3n this case) the class we care a#out is ebSer%ice) which is inherited in this e1am"le using the "nherits 'e$word. 3nheriting from the ebSer%ice class is not re(uired for a class to function as a &e# ser%ice) #ut the ebSer%ice class "ro%ides useful "lum#ing for &e# ser%ices. This includes access to /pplication) Session) and other ASP.NET o#;ects) including the =onte$t o#;ect) which "ro%ides access to information a#out the <TTP re(uest that in%o'es the &e# ser%ice. An$ &e# ser%ice $ou create using Visual Studio .NET will use the ebSer%ice class as the #ase class.
-M./#ased &e# ser%ices use -M. names"aces to uni(uel$ identif$ the end"oint or listener to which a client sends re(uests. B$ default) the -M. names"ace for a &e# ser%ice created with Visual Basic .NET ?within the Visual Studio .NET 30EA is set to http://tempuri.org/pro*ectname/classname. 3f $ou "lan to ma'e $our &e# ser%ice a%aila#le "u#licl$ o%er the 3nternet) $ou might want to change the default names"ace to a%oid "otential conflicts with other -M./#ased &e# ser%ices using the same names as $our &e# ser%ice) and which also might use the default names"ace. 9sing a domain name that $ou control can hel" ensure uni(ueness. You can modif$ the default names"ace for a &e# ser%ice class #$ adding the ebSer%ice metadata attri#ute to the class definition and setting its Namespace "ro"ert$ to the desired %alue for the new names"ace. This %alue can #e an$ uni(ue 973 that $ou control) such as $our organiGation+s domain name. The names"ace is used onl$ for identificationBthe 973 s"ecified is not used in an$ other wa$) and need not #e a %alid) accessi#le &e# site. 3n Microsoft Visual Basic .NET) metadata attri#utes use the s$nta1 :/ttributeNameEPropertyName:5%alueF; and are "laced on the same line as the entit$ ?class) method) and so onA that the$ modif$. For reada#ilit$+s sa'e) $ou can use the Visual Basic line/ continuation character to wra" the class definition onto the following line=
?4eb.e",ice2Na&es*aceJ="+tt*JBB111.as*netsbs.co&B1ebse",icesB"3A < /ublic -lass -lassNa&e
Metadata Attri#utes Prior to this cha"ter) the term attributes referred to the 'e$E%alue "airs added to <TM. or ASP.NET ser%er control tags to define s"ecific "ro"erties of those entities or controls. This cha"ter introduces the conce"t of metadata attri#utes. ASP.NET and the Microsoft .NET Framewor' ma'e e1tensi%e use of attri#utes to "ro%ide "rogrammatic "lum#ing for classes) as well as to add descri"ti%e information to managed assem#lies. You can also use $our own attri#utes ?#$ creating classes deri%ed from System./ttributeA to add $our own descri"ti%e information to $our classes. Attri#utes in ASP.NET &e# ser%ices) in addition to "ro%iding access to the -M. names"ace used for the &e# ser%ice) are used to tell ASP.NET that a gi%en method is to #e e1"osed as a eb9ethod. ASP.NET then "ro%ides all of the runtime functionalit$ necessar$ for clients of the &e# ser%ice to access the eb9ethod without re(uiring the "rogrammer to write additional code. You can set multi"le "ro"erties in an attri#ute declaration and se"arate them #$ commas. You can use the Visual Basic line continuation character to format the attri#ute declaration so that each "ro"ert$ is on a se"arate line. This can su#stantiall$ im"ro%e code reada#ilit$) "articularl$ if $ou are using man$ "ro"erties in an attri#ute declaration.
*nce $ou+%e declared the class that im"lements the &e# ser%ice) $ou will need to add one or more methods that "ro%ide functionalit$ for the &e# ser%ice. Each method will use the eb9ethod metadata attri#ute to declare the method as one for which ASP.NET should "ro%ide the necessar$ "lum#ing to e1"ose it to clients. To add the eb9ethod attri#ute to a Visual Basic .NET method) use the following s$nta1=
MethodName is the name of the method to #e e1"osed #$ the &e# ser%iceI 7eturnT$"e is the t$"e of the %alue ?if an$A to #e returned #$ the method. E%en if $our method does not return a %alue that is a result of a calculation or other action) it is usuall$ a good idea to at least return a %alue that indicates the success or failure of the method.
,escription
EnableSession
9essageName
eb9ethod Properties
allowing $ou to uni(uel$ identif$ each one. The default is the method name. Transaction+ption Allows adding su""ort for ,*ML transactions in a &e# ser%ice method. Allowa#le %alues are ,isabled) NotSupported) Supported) .e4uired) and .e4uiresNew. The default is ,isabled. Note that this "ro"ert$ re(uires the use of an @ /ssembly directi%e to load the System.EnterpriseSer%ices assem#l$ into the &e# ser%ice a""lication.
2. Switch to code %iew. You can clic' on the lin' "ro%ided in design %iew to switch to code %iew) or use the standard Visual Studio .NET 'e$) FK. <owe%er $ou switch to code %iew) the screen should loo' similar to the following illustration.
9nli'e &e# A""lications) in which a great deal of the wor' of #uilding the "age is done in design %iew) &e# ser%ices are generall$ modified using code directl$. !. Toward the #ottom of the file) locate a comment titled &EB SE7V3,E E-AMP.E. The code will loo' similar to the following=
4. ' 4 B . 6V(^07/L
8. ' T+e Hello4o"l!23 exa&*le se",ice "etu"ns t+e st"in) Hello 4o"l!. :. ' To buil!, unco&&ent t+e #ollo1in) lines t+en sa,e an! buil! E. ' t+e *"oLect. F. ' To test t+is 1eb se",ice, ensu"e t+at t+e .as&x #ile is t+e G. ' sta"t *a)e an! *"ess F8. 1H. '
11. '?4eb7et+o!23A /ublic Function Hello4o"l!23 0s .t"in) 1$. 'Hello4o"l! = "Hello 4o"l!" ' n! Function
2!. 7emo%e the comments from the #eginning of each line from : eb9ethodEF; to End 1unction. 7ather than lea%e this e1am"le e1actl$ as it is created #$ Visual Studio .NET) add a "arameter to Kello orld) and a""end the "arameter to the %alue returned. The finished method should loo' li'e the following code=
14. ?4eb7et+o!23A 18. /ublic Function Hello4o"l!2B'Val Na&e 0s .t"in)3 0s .t"in) 6etu"n "Hello 4o"l!, #"o& " & Na&e n! Function
26. Sa%e the file) and then #uild the "ro;ect. 2K. 7ight/clic' on Ser%ice2.asm1 in Solution E1"lorer. Select Browse &ith from the dro"/ down menu. Select Microsoft 3nternet E1"lorer from the #rowser list) and then clic' Browse. The resulting screen should loo' similar to the following illustration.
There are two lin's on this "age. The first is Ser%ice 0escri"tion. ,lic' this lin') and a screen similar to the following illustration will a""ear.
2D. You can scroll through the entire document and see the com"lete &e# Ser%ices 0escri"tion .anguage ?&S0.A contract for the &e# ser%ice method. ,lic' the Bac' #utton on the #rowser and select the other lin' on the "age) Kello orld. The screen should loo' similar to the following illustration.
2C. Enter $our name in the te1t #o1 "ro%ided for the name) and then clic' the 3n%o'e #utton. The resulting screen should loo' similar to the following illustration) which shows the -M. out"ut returned #$ the &e# ser%ice.
The com"lete source for the .asm1 file and the code/#ehind file can #e found in the "ractice files for the #oo'.
8. Scroll to the #ottom of the code file) and uncomment the commented Kello orld method. ,hange the name of the method to GetAuth rs) and the return t$"e of the method from String to 6ataSet. Modif$ the eb9ethod attri#ute ;ust #efore the -et/uthors method adding the descri"tion) so that it loo's li'e the following line=
?4eb7et+o!2%esc"i*tionJ="6etu"ns t+e /ubs 0ut+o"s table."3A
Q. Modif$ the -et/uthors method so that it loo's li'e the following code=
:. ?4eb7et+o!2%esc"i*tionJ="6etu"ns t+e /ubs 0ut+o"s table."3A < E. /ublic Function ;et0ut+o"s23 0s %ata.et F. G. 1H. 11. 1$. 13. 14. 18. 1:. 1E. 1F. 1G. $H. $1. 6etu"n !s0ut+o"s n! Function -onn.t"in) = "se",e"=2local3Q,s%otNetO!atabase=*ubsO" & < "T"uste!<-onnection='es" .NL = ". L -T U F697 0ut+o"s 96% 6 B> au<LNa&e,au<FNa&e" -onn.-onnection.t"in) = -onn.t"in) !a = Ne1 .@l%ata0!a*te"2.NL, -onn3 !a.Fill2!s0ut+o"s, "0ut+o"s"3 %i& !s0ut+o"s 0s Ne1 %ata.et23 %i& -onn 0s Ne1 .@l-onnection23 %i& !a 0s .@l%ata0!a*te" %i& -onn.t"in) 0s .t"in) %i& .NL 0s .t"in)
Much of the data#ase access code should loo' %er$ familiar from "re%ious e1am"les. Note that the connection is neither o"ened nor closed in this e1am"le. This is #ecause the S4l,ata/dapter class ta'es care of o"ening) and closing the connection automaticall$) using the connection o#;ect "assed to its constructor. 22. Sa%e the file and #uild the a""lication. 2!. Browse the &e# ser%ice with 3nternet E1"lorer. The screen should loo' similar to the following illustration. ?Note that the descri"tion s"ecified is the same as the ,escription "ro"ert$ of the eb9ethod attri#ute.A
28. ,lic' @etAuthors. The resulting "age will loo' similar to the last e1am"le "age that allowed $ou to in%o'e the &e# ser%ice) e1ce"t in this case) there will #e an 3n%o'e #utton) #ut no te1t #o1 ?#ecause there are no "arametersA. ,lic' 3n%o'e) and a window similar to the following illustration will a""ear.
2Q. The schema for the resulting data is at the to" of the result from in%o'ing the &e# ser%ice. Scroll down in the #rowser window) and $ou will see the actual data) as shown in the following illustration.
,ha"terO22.disco
?Px&l ,e"sion="1.H" enco!in)="ut#5F" PA ?!isco,e"' x&lns="+tt*JBBsc+e&as.x&lsoa*.o")B!iscoB"A
Note that for the sa'e of reada#ilit$) this listing contains relati%e 97.s. 0isco%er$ documents can contain either relati%e or a#solute 97.s. &hen relati%e 97.s are used) the$ are assumed to #e relati%e to the location of the 97. of the disco%er$ document. 3f $ou #rowse to the disco file) it will #e dis"la$ed ;ust as an$ other -M. file. You can add a .disco file to $our "ro;ect #$ right/ clic'ing the "ro;ect in Solution E1"lorer) then highlighting Add) then selecting Add New 3tem. 3n the Add New 3tem dialog #o1) select the Static 0isco%er$ File icon) and gi%e the file the desired name.
Another o"tion for authenticating users is a third/"art$ authentication mechanism such as Microsoft Pass"ort. 9nfortunatel$) the de%elo"er tool su""ort for Pass"ort is currentl$ "oor) and most a%aila#le tools focus on allowing the use of Pass"ort to authenticate users from &e# sites) rather than &e# ser%ices. &hile it is li'el$ that Pass"ort and other third/"art$ authentication mechanisms will add su""ort for sim"le im"lementation in &e# ser%ices e%entuall$) toda$ these mechanisms li'el$ will re(uire too much effort on the "art of $our clients. Finall$) $ou can 4roll $our own5 &e# ser%ices authentication #$ im"lementing a login function in one or all of $our &e# ser%ices) with the login method returning a uni(ue 'e$ ?which should #e hashed or encr$"tedA identif$ing the logged/in user. This 'e$ is then "assed as a "arameter of each &e# ser%ice re(uest) indicating that the user is an authenticated user. To "rotect the username and "assword) the login &e# ser%ice method should #e re(uested o%er an SS. connection. Su#se(uent re(uests can #e made o%er a standard <TTP connection) howe%er) so as to a%oid the "erformance o%erhead of SS. encr$"tion. To reduce the ris' of a user #eing im"ersonated #$ someone who has interce"ted the login 'e$) these 'e$s should #e stored in such a wa$ that the$ can #e easil$ e1"ired after a "redetermined timeout %alue ?in a #ac'/end data#ase) for e1am"leA. &hile this authentication method is more difficult to im"lement and maintain than some of the others) it+s the sim"lest for $our clients to use. *nce $ou ha%e gi%en a client his account information ?username and "asswordA) all he needs to do is ma'e the re(uest to the login &e# ser%ice ?o%er an SS. connectionA and store his login 'e$. &ith each su#se(uent re(uest) he "asses the 'e$ as one of the "arameters of the &e# ser%ice method he+s calling. 3f the timeout %alue e1"ires #etween one re(uest and the ne1t) the user must call the login method again to recei%e a new 'e$. Therefore) the timeout %alue should #e set to "ro%ide a #alance #etween securit$ and con%enience. 3n addition to the login method) $ou could also im"lement a logout method in $our &e# ser%ice to e1"licitl$ e1"ire the login 'e$. IMPORTANT 3n addition to controlling access to a &e# ser%ice with authentication) $ou should also use SS. to encr$"t communications if $ou are "assing sensiti%e data to or from the &e# ser%ice. This includes usernames and "asswords sent when authenticating users) as well as data such as "atient information in the healthcare industr$) where the re(uirement to "rotect "ersonal data is not onl$ common sense) it+s the lawH You can find more information on &e# ser%ices securit$) including information on the "ro"osed &S/Securit$ s"ecification) in the Microsoft -M. &e# Ser%ices 0e%elo"er ,enter at http://msdn.microsoft.com/webser%ices/ and at http://msdn.microsoft.com/wsCsecurity/.
.ocating a &e# ser%ice) using either a disco%er$ document or 9003 9sing the &S0..E-E utilit$ to create a "ro1$ class for the &e# ser%ice 9sing the "ro1$ class from an ASP.NET "age or console a""lication to access the &e# ser%ice
<ere) o"tions re"resents one or more command/line o"tions for the utilit$) and 97. re"resents the 97. to the disco%er$ document. Ta#le 22/2 shows o"tions for the disco.e1e utilit$.
Ta#le 443*. disco.e$e +ptions 1ptio" Ed=domain or Edomain=domain Enosa%e Enologo Eo=directory or Eout=directory Descriptio" Sets the domain to use when connecting to a site that re(uires authentication. Pre%ents disco.e1e from sa%ing files for the disco%ered &S0. and disco%er$ documents. Pre%ents the start/u" #anner from #eing dis"la$ed. Pro%ides the director$ name where out"ut should #e sa%ed.
E"=password or E"assword=password Sets the "assword to use when connecting to a site that re(uires authentication. E"ro1$=url E"d=domain or E"ro1$domain=domain E""=password or E"ro1$"assword=password E"u=username or E"ro1$username=username Eu=username or Eusername=username EU Sets the "ro1$ to use for <TTP re(uests. Sets the domain to use when connecting to a "ro1$ ser%er that re(uires authentication. Sets the "assword to use when connecting to a "ro1$ ser%er that re(uires authentication. Sets the username to use when connecting to a "ro1$ ser%er that re(uires authentication. Sets the username to use when connecting to a site that re(uires authentication. Pro%ides hel" for command/line o"tions.
*ne effecti%e techni(ue for searching for &e# ser%ices on the http://uddi.microsoft.com registr$ is to search #$ disco%er$ 97. and search for 97.s that contain 4wsdl.5 These 97.s are the most li'el$ to "oint to li%e &S0. contracts that $ou can use to access a%aila#le &e# ser%ices.
&S0. on different "latforms) since these im"lementations can #e #ased on different drafts of the "ro"osed standard. 9ntil S*AP and &S0. #ecome settled standards ?&!, 7ecommendationsA) $ou might need to twea' $our &S0. contracts to achie%e intero"era#ilit$ #etween different &e# ser%ices im"lementations. This shouldn+t #e an issue once these s"ecifications ha%e recei%ed a""ro%al as &!, 7ecommendations. 3n the meantime) $ou can read an interesting article on intero"era#ilit$ #etween %arious &e# ser%ices im"lementations on the MS0N .i#rar$ &e# site at http://msdn.microsoft.com/library/enC us/dn0%oices0webser%ice/html/ser%iceQV>)(QQ>.asp.
<ere) o"tions re"resents one or more command/line o"tions for the utilit$) and 97. re"resents the 97. to the &S0. contract. Alternati%el$) a file "ath to the &S0. contract can #e "assed as the "ath argument. Ta#le 22/! shows o"tions for the wsdl.e1e utilit$. Ta#le 4432. wsdl.e$e +ptions 1ptio" Ea""settingurl'e$=key or Eurl'e$=key Descriptio" Sets the 'e$ of the configuration setting from which to read the default 97. for generating code.
Ea""setting#aseurl=baseurl or Sets the #ase 97. to use for calculating relati%e 97.s when a 97. E#aseurl=baseurl fragment is s"ecified for the !.< argument. Ed=domain or Sets the domain to use when connecting to a site that
Ta#le 4432. wsdl.e$e +ptions 1ptio" Edomain=domain El=language or Elanguage=language Descriptio" re(uires authentication. Sets the language to use when generating the "ro1$ class. Valid %alues include =S) D2) \S) or the full$ (ualified name of an$ class that im"lements the System.=ode,om.=ompiler.=ode,omPro%ider class. 0efault is =S ?,JA. Sets the names"ace to #e used when generating the "ro1$ class. Pre%ents the start/u" #anner from #eing dis"la$ed. Sets the "assword to use when connecting to a site that re(uires authentication. Sets the "rotocol ?S*AP) Kttp-et) or KttpPostA to use for re(uests. 0efault is S*AP. Sets the "ro1$ to use for <TTP re(uests. Sets the domain to use when connecting to a "ro1$ ser%er that re(uires authentication. Sets the "assword to use when connecting to a "ro1$ ser%er that re(uires authentication. Sets the username to use when connecting to a "ro1$ ser%er that re(uires authentication. ,reates an a#stract #ase class with the same interfaces as s"ecified in the &S0. contract. Sets the username to use when connecting to a site that re(uires authentication. Pro%ides hel" for command/line o"tions.
En=namespace or Enames"ace=namespace Enologo E"=password or E"assword=password E"rotocol=protocol E"ro1$=url E"d=domain or E"ro1$domain=domain E""=password or E"ro1$"assword=password E"u=username or E"ro1$username=username Eser%er Eu=username or Eusername=username EU
Eo=filename or Eout=filename Pro%ides the file name ?and "athA to use for sa%ed out"ut.
Ta'e the following ste"s to create "ro1$ classes in Visual Basic .NET for the KelloSer%ice and /uthorsSer%ice e1am"le &e# ser%ices created earlier in this cha"ter.
2. *"en a command line and na%igate to the director$ where $ou would li'e the "ro1$ classes to #e generated. ?*r use the /o o"tion to s"ecif$ a "ath and filename for sa%ing the "ro1$ class.A 2. E1ecute the wsdl.e1e utilit$) using the /l o"tion to s"ecif$ Visual Basic .NET as the language and "assing the 97. to the <elloSer%ice.asm1 file) including the U&S0. "arameter) which tells ASP.NET to return the &S0. contract for the .asm1 file. ?Both of the following lines should form a single command.A The 97. $ou s"ecif$ should match the location of the .asm1 file on $our &e# ser%er) and it might differ from the following 97..
3. 1s!l BlJ,b BnJ0./N T.B. +tt*JBBlocal+ostB-+a*te"<11B.e",ice1.as&xP4.%L
8. E1ecute the wsdl.e1e utilit$ again for AuthorsSer%ice.asm1) using the same s$nta1 as shown in ste" 2 #ut modif$ing the 97. to "oint to AuthorsSer%ice.asm1. Q. *"tionall$) $ou can create a #atch file ?with the .#at e1tensionA containing #oth of the "receding commands. 3f $ou want to see the results of the #atch e1ecution #efore the command window closes) add a pause command at the end of the #atch file. A #atch file similar to this is included in the "ractice files for this cha"ter. *nce $ou+%e created $our "ro1$ class) $ou+ll need to com"ile the class using the command/line com"iler for the language $ou chose to generate ?in this e1am"le) Visual Basic .NETA. The following listing) Ma'eSer%ices.#at) shows the command/line com"iler s$nta1 to com"ile these classes and out"ut the resulting assem#l$ to the #in su#director$ of the director$ from which the command is run. For this e1am"le) this should #e the #in su#director$ of the ,ha"terO22 "ro;ect. Note that this listing re"resents a single command and has #een wra""ed to multi"le lines for reada#ilit$. A #atch file similar to this is included in the "ractice files for this cha"ter.
Ma'eSer%ices.#at
,bc BtJlib"a"' B"J.'ste&.4eb.!ll B"J.'ste&.!ll B"J.'ste&.4eb..e",ices.!ll B"J.'ste&.^&l.!ll B"J.'ste&.%ata.!ll BoutJbinQ.e",ices.!ll 0ut+o"s.e",ice.,b .e",ice1.,b
IMPORTANT B$ default) the .NET Framewor' and Visual Studio .NET setu" "rograms do not add the "aths to either wsdl.e1e or %#c.e1e to the PAT< en%ironment %aria#le. This means that to call these "rograms from the command line) $ou must either change directories to the location of the "rogram #efore calling it ?the techni(ue used in the #atch files contained in the "ractice files for the cha"terA) or $ou must add the "rogram+s "ath to the PAT< en%ironment %aria#le. 3nstructions for adding these "aths to the PAT< en%ironment %aria#le are found in A""endi1 ,.
2. *"en the "ro;ect for this cha"ter) ,ha"terO22) in Visual Studio .NET if it is not alread$ o"en. 2. 7ight/clic' on the root of the "ro;ect in the Solution E1"lorer) and select Add &e# 7eference from the dro"/down menu. The Add &e# 7eference dialog #o1 will a""ear) as shown in the following illustration.
!. T$"e the 97. to the AuthorsSer%ice.asm1 file ?if $ou followed the directions in this cha"ter) this should #e http://localhost/=hapter0>>//uthorsSer%ice.asm$A in the address te1t #o1) and clic' @o ?$ou can also clic' eb Ser%ices +n The <ocal 9achine to #rowse for all local &e# ser%ices) then select the AuthorsSer%ice ser%iceA. The result should loo' similar to the following illustration.
8. ,lic' the Add 7eference #utton at the #ottom right/hand corner of the Add &e# 7eference dialog #o1. &hen the Add &e# 7eference dialog #o1 closes) loo' in the Solution E1"lorer to find a new node named &e# 7eferences. 9nder &e# 7eferences) $ou+ll see a node added called localhost ?assuming the 97. entered in Ste" 2 was on the localhost domainA. E1"and that node ?$ou might need to clic' the Show All Files #utton in the Solution E1"lorer tool#ar firstA. The result should loo' similar to the following illustration.
Q. 7ight/clic' on localhost) and select 7ename from the dro"/down menu. 7ename localhost to Auth rs. &hen $ou add a &e# reference) Visual Studio .NET creates a folder with the same name as the &e# reference under the &e# 7eferences folder that is under the main "ro;ect folder. There are se%eral files created #$ Visual Studio .NET in this folder. Most interesting is 7eference.%# ?which is hidden #$ defaultA) which contains the "ro1$ code generated #$ Visual Studio for accessing the &e# ser%ice. 6. Add a new &e# Form. T$"e the name of the new &e# Form as Sh wAuth rs.as(0. K. ,lic' and drag a ,ata-rid control from the tool#o1 to the surface of the "age of ShowAuthors.as"1. D. Press FK to change to code %iew. Scroll down to the Page0<oad method) and then modif$ it so that it loo's li'e the following code=
G. /"i,ate .ub /a)e<Loa!2B'Val sen!e" 0s .'ste&.9bLect, < 1H. 11. 1$. 13. 14. 18. B'Val e 0s .'ste&. ,ent0")s3 Han!les 7'Base.Loa! %i& !s 0s %ata.et %i& s,c 0s Ne1 0ut+o"s.0ut+o"s.e",ice23 !s = s,c.;et0ut+o"s23 %ata;"i!1.%ata.ou"ce = !s.Tables2"0ut+o"s"3 %ataBin!23 n! .ub
26. Sa%e and #uild the "ro;ect. 2K. Browse ShowAuthors.as"1 using 3nternet E1"lorer. The out"ut should loo' similar to the following illustration.
*ne im"ortant thing to notice a#out this e1am"le is that while the ta#le we are dis"la$ing is a Microsoft S:. Ser%er ta#le) we do not reference System.,ata.S4l=lient. &e don+t ha%e to #ecause this a""lication is not directl$ connecting to a S:. Ser%er data#ase. 7ather) the a""lication connects to the &e# ser%ice created earlier ?which returns a generic ,ataSetA) and from there the &e# ser%ice itself connects to S:. Ser%er. Because the "ro;ect alread$ contains a reference to the System.,ata names"ace ?which is added #$ default to all new "ro;ectsA) we don+t need to add an$ additional names"ace references to use the dataset returned from the &e# ser%ice.
Additional 7esources
&e# Ser%ices are a useful tool) "articularl$ for "ro%iding intero"era#ilit$ #etween functionalit$ "ro%ided #$ different a""lications) and e%en on different "latforms. But the technolog$ and
s"ecifications #ehind &e# Ser%ices are still in de%elo"ment. For this reason) it+s #est to chec' for the latest information at sites such as the following=
http://www.wA.org/ The &orld &ide &e# consortium) home of the S*AP) &S0.) -S0) and other s"ecifications
,hange the default Add or modif$ the ebSer%ice attri#ute) adding a Namespace56:new names"ace of a !.<;7 "arameter. &e# ser%ice Ad%ertise a &e# ser%ice Either create a disco%er$ document for $our &e# ser%ices and "u#lish the document to a "u#lic location) such as $our organiGation+s &e# site) or register $our &e# ser%ices in one of the "u#licl$ a%aila#le 9003 #usiness registries) ma'ing sure to "ro%ide the 97. to the &S0. contract for each &e# ser%ice $ou register. 9se the wsdl.e1e utilit$ to create a "ro1$ class #ased on the &S0. contract for the &e# ser%ice) com"ile the "ro1$ class) and instantiate the "ro1$ class from $our client a""lication as $ou would an$ other .NET class. Alternati%el$) sim"l$ right/clic' on the "ro;ect root in Visual Studio .NET) clic' Add &e# 7eference on the dro"/down menu) and then enter a 97.. 3f the 97. is recogniGed and the methods a%aila#le are dis"la$ed) clic' Add 7eference.
Ta'e ad%antage of out"ut caching for &e# Forms "ages and user controls. Ta'e ad%antage of caching for data retrie%ed with A0*.NET. 9se the ,ache AP3s to get fine/grained control o%er the e1"iration) de"endencies) and other "ro"erties of cached items.
The good news a#out ASP.NET is that its im"ro%ementsBfrom the use of com"iled languages rather than inter"reted languages to the com"lete rewrite of the ASP.NET e1ecution engineB ma'e it eas$ for $ou to o#tain the "erformance that man$ of $our a""lications need. &ell/ designed a""lications written in ASP.NET will almost alwa$s #e faster than the e(ui%alent a""lications written in classic ASP. <owe%er) for one class of a""lications these "erformance im"ro%ements alone will not #e sufficient. These can include a""lications whose "ages are com"utationall$ intensi%e ?such as "ages that use recursi%e "roceduresA or access large amounts of data) and a""lications that need to scale to large num#ers of concurrent users. ASP.NET offers new features for this class of a""lications) including a sim"le AP3 for out"ut caching and a rich and ro#ust caching engine and AP3.
Understanding 'aching
=aching is the "rocess of tem"oraril$ storing e1"ensi%e resources in memor$. These resources might #e e1"ensi%e #ecause of the amount of "rocessor time necessar$ to render them) #ecause the$ reside on dis') or #ecause the$ reside in a #ac'/end data#ase on another machine. Pages that are e1"ensi%e to render can consume so much "rocessor time that the &e# ser%er #ecomes una#le to fulfill re(uests in a timel$ fashion. 7etrie%ing "ages and other content from dis' is much slower than ser%ing them from memor$) and this "erformance difference is magnified when the ser%er needs to fulfill man$ re(uests simultaneousl$. 7e(uests for large amounts of data from a #ac'/end data#ase often encounter #oth dis'/#ased and networ'/#ased "erformance dela$s. ?Thus) calls from one ser%er to another can #e su#stantiall$ more e1"ensi%e than fulfilling a re(uest on the same machine.A For these reasons) &e# a""lications that need high "erformance ha%e long used caching to mitigate the "erformance costs of e1"ensi%e o"erations. The out"ut from recent re(uests) or re(uested data) is cached in memor$. Su#se(uent re(uests are ser%ed from this in/memor$ cache) rather than rendering a "age or (uer$ing a data#ase again. This can su#stantiall$ im"ro%e the "erformance and scala#ilit$ of an a""lication. 3n the "ast) unfortunatel$) this im"ro%ement has come at a cost. 0e%elo"ers using classic ASP were limited to either using the intrinsic Session and /pplication o#;ects for caching or rolling their own caching engines.
ASP.NET now offers a rich) ro#ust framewor' for caching #oth "age out"ut and ar#itrar$ data that de%elo"ers can access easil$ using #oth declarati%e and "rogrammatic means. ASP.NET out"ut caching allows de%elo"ers to declarati%el$ cache "age and user control out"ut to a%oid wasting resources #$ re"eatedl$ rendering content that does not need to change from re(uest to re(uest. The cache AP3 "ro%ides a num#er of methods that allow de%elo"ers to add items to the cache) remo%e items from the cache) and set "ro"erties that determine the lifetime of items stored in the cache.
&e# ser%er fulfilling the re(uest. Ser%er ,ontent is cached on the &e# ser%er. None
No caching. You can use the <ocation attri#ute with &e# Forms "ages only. Shared New in ASP.NET 2.2) this attri#ute s"ecifies whether a cached user control can #e shared across multi"le "ages. 3f set to True) a single cached co"$ of the user control is shared among multi"le "ages within the a""lication. 3f set to 1alse) a se"arate co"$ of the user control will #e cached for each "age that uses the control. The default is 1alse. This attri#ute is %alid for user controls onl$.
Dary2y=ontrol Sets the names of "ro"erties of a user control #$ which to %ar$ the caching of the user control out"ut. Multi"le "ro"erties are se"arated #$ semicolons. You can use this attri#ute with user controls only. Dary2y=ustom Allows %ar$ing of cached content #$ #rowser user agent) #rowser ca"a#ilities) or custom logic. &hen set to an$ %alue other than browser) this attri#ute re(uires that the Kttp/pplication.-etDary2y=ustomString #e o%erridden in @lo#al.asa1 to im"lement the custom logic. Dary2yKeader Allows %ar$ing of cached content #ased on the %alue of one or more <TTP re(uest headers. Multi"le "ro"erties are se"arated #$ semicolons. You can use this attri#ute with &e# Forms "ages only. Dary2yParam Allows %ar$ing of cached content #ased on the %alue of one or more (uer$string %alues sent with a -ET re(uest) or form fields sent with a P+ST re(uest. Multi"le 'e$ or field names are se"arated #$ semicolons. You can also set the %alue of this attri#ute to ? to %ar$ #$ all "arameters) or to None to use the same cached "age regardless of -ET/P+ST "arameters. This attri#ute is re(uired. The Dary2yX attri#utes are among the most im"ortant features of the @ +utput=ache directi%e. These attri#utes ma'e it "ossi#le to cache "ages and user controls e%en when those "ages are d$namicall$ generated #ased on (uer$string %alues) form field %alues) <TTP header %alues) or e%en #rowser ca"a#ilities. The ,uration attri#ute lets $ou limit the length of time that out"ut is cached. For "ages that are u"dated "eriodicall$) #ut not as fre(uentl$ as e%er$ re(uest) the ,uration attri#ute allows $ou to fine/tune the out"ut caching so that $ou can ma1imiGe the #enefit gained #$ caching while #eing reasona#l$ sure that users will not get stale content. For e1am"le) if $ou had a "age that) on
a%erage) was u"dated e%er$ two hours) $ou could set the ,uration attri#ute of the @ +utput=ache directi%e to RQQ. This would cache the out"ut of the "age for C seconds ?2Q minutesA from the last time the "age was re(uested ?su#;ect to the Dary2y attri#utesA. This would ensure that the "age would need to #e rendered onl$ once e%er$ 2Q minutes) regardless of how man$ re(uests were recei%ed for the "age) and that there would #e onl$ a 2Q/minute window in which users could get a cached "age rather than u"dated data. The Shared attri#ute allows $ou to conser%e memor$ #$ ma'ing a single cached co"$ of a user control a%aila#le to multi"le "ages within $our a""lication. &ithout setting this attri#ute to True) a se"arate co"$ of the user control is cached for each "age that uses the user control. Finall$) the <ocation attri#ute determines where the out"ut cache is located. Setting certain %alues for the <ocation attri#ute causes ASP.NET to set the "fC9odifiedCSince <TTP header to allow caching of "age or control out"ut.
8. Select View) and then select ,ode) or "ress FK to mo%e to the code window. Q. Scroll down to the Page0<oad e%ent handler and add the following code=
7essa)e.Text = %ateTi&e.No1.To.t"in)23
6. Sa%e the file and "ro;ect) and then #uild the "ro;ect. K. Browse the "age) and then "ress FQ to refresh the "age in the #rowser. Each time $ou refresh the #rowser ?as long as $our refresh re(uests are at least one second a"artA) the time dis"la$ed #$ the first la#el will change. D. @o #ac' to *ut"ut,ache.as"1 and switch to <TM. %iew. Add an @ +utput=ache directi%e at the to" of the "age) with the ,uration attri#ute set to 4/ and the Dary2yParam attri#ute set to N ne. This directi%e should a""ear on the line directl$ #elow the @ Page directi%e. The com"lete directi%e should loo' li'e this=
?IM 9ut*ut-ac+e %u"ation="1H" Va"'B'/a"a&="None" IA
C. Sa%e *ut"ut,ache.as"1. Because $ou+%e changed onl$ the .as"1 file) $ou don+t need to #uild the "ro;ectBthe changed "age will #e d$namicall$ com"iled the ne1t time it+s re(uested. 2 . Browse the "age using Microsoft 3nternet E1"lorer) and again refresh the #rowser. The time dis"la$ed should change onl$ a#out once e%er$ 2 seconds. The screen should loo' similar to the following illustration=
NOTE &hen $ou loo' at the "receding illustration) $ou+ll notice that e%en though we renamed the form from &e#Form2.as"1 to *ut"ut,ache.as"1) the title ?shown in the title #arA remains &e#Form2. Microsoft Visual Studio .NET gi%es the filename as the default title when the form is created) #ut does not u"date that when the file is renamed. You can u"date the title $ourself in the "ro"erties of the ,+=!9ENT o#;ect for the "age) or $ou can edit the <TM. :title; tag directl$.
de%elo" user controls "rogrammaticall$) using the code/#ehind file e1clusi%el$ ?while the .asc1 file merel$ has an @=ontrol directi%e "ointing to the code/#ehind fileA. &ith this techni(ue) $ou can still cache the out"ut of the user control #$ adding the Partial=aching attri#ute ?new in ASP.NET 2.2A to the class definition for the control) as shown in the following code e1am"le=
?/a"tial-ac+in)23H3A < /ublic -lass F"a)&ent-ac+e (n+e"its .'ste&.4eb.=(.=se"-ont"ol
/"i,ate .ub /a)e<Loa!2B'Val sen!e" 0s .'ste&.9bLect, < B'Val e 0s .'ste&. ,ent0")s3 Han!les 7'Base.Loa! 7essa)e.Text = %ateTi&e.No1.To.t"in)23 n! .ub
n! -lass
8. Select View) and then select ,ode) or "ress FK to mo%e into the code window. Q. Scroll down to the Page0<oad e%ent handler and add the following code=
7essa)e.Text = %ateTi&e.No1.To.t"in)23
6. Sa%e Fragment,ache.asc1 and its code/#ehind file. K. 3n the same "ro;ect) add a &e# Form and t$"e its name as $rag%ent'ache.as(0.
D. Add two la#els to the form a#out midwa$ down the "age) lea%ing an e(ual amount of s"ace at the to" of the "age as that ta'en u" #$ the two la#els. 9sing the "ro"ert$ window) change the name of the first la#el from .a#el2 to Message. ,hange the te1t in the second la#el to The te0t a# &e was rendered fr % the !e# $ r%s (age. C. Select View) and then select ,ode) or "ress FK to mo%e to the code window. Scroll down to the Page0<oad e%ent handler and add the following code=
7essa)e.Text = %ateTi&e.No1.To.t"in)23
2 . Switch #ac' to Fragment,ache.as"1 #$ clic'ing its ta# at the to" of the editor window. You should #e in 0esign mode. 3f not) switch to 0esign mode. 22. Find Fragment,ache.asc1 in the Solution E1"lorer. 0rag it onto the form. No matter where $ou "lace it) it will end u" in the u""er left hand corner of the design window. 22. Sa%e Fragment,ache.as"1 ?and an$ other unsa%ed filesA) and #uild the "ro;ect. 2!. Browse the "age using 3nternet E1"lorer) and refresh the #rowser. The screen will loo' similar to the following illustration.
&hen $ou first #rowse the "age) #oth timestam"s will #e the same. 3f $ou clic' the #rowser+s 7efresh #utton se%eral times) $ou+ll notice that the time dis"la$ed #$ the "age is u"dated with each "age re(uest) while the time dis"la$ed #$ the user control is u"dated onl$ once e%er$ 2 seconds.
TIP As mentioned earlier in this cha"ter) if $ou+re using a user control from numerous "ages within $our a""lication and want to conser%e memor$) $ou can add the Shared attri#ute to the @+utput=ache directi%e) which will allow a single cached %ersion of the control to #e shared across all of the "ages within $our a""lication that use the control=
?IM 9ut*ut-ac+e %u"ation="1H" Va"'B'/a"a&="None" .+a"e!="t"ue" IA
*f course) if the user control relies on in"ut from each indi%idual "age) using the Shared attri#ute might not #e a""ro"riate. But in cases in which the out"ut of the control will #e the same for all "ages) it+s a hand$ wa$ to a%oid eating u" memor$ unnecessaril$.
!. Switch to <TM. %iew and add an @ +utput=ache directi%e to the "age) s"ecif$ing the duration as ! seconds and the "arameter to %ar$ #$ as the name of the Te$t2o$ control=
?IM 9ut*ut-ac+e %u"ation="3H" Va"'B'/a"a&="Na&e" IA
8. Select View) and then select ,ode) or "ress FK to mo%e to the code window. Q. Scroll down to the Page0<oad e%ent handler and add the following code=
:. (# (s/ostBacC T+en E. F. G. 1H. 11. Na&e.Visible = False Label$.Visible = T"ue Label1.Text = "T+is *a)e 1as cac+e! #o" " & Na&e.Text Label1.Text &= ". T+e cu""ent !ate an! ti&e is " Label1.Text &= %ateTi&e.No1.To.t"in)23 n! (#
22. Sa%e Var$B$Param.as"1 and its code/#ehind file) and then #uild the "ro;ect.
2!. Browse Var$B$Param.as"1 using 3nternet E1"lorer. The initial out"ut will loo' similar to the following illustration.
28. T$"e $our name and "ress Enter. The out"ut will loo' similar to the following illustration.
3f $ou clic' the #rowser+s 7efresh #utton ?and clic' 7etr$ or *> to re"ost the formA) the "age will refresh from the cache. 3f $ou clic' Bac' and enter a different name) $ou will get a fresh %ersion of the "age. Tr$ entering different names) refreshing) and then going #ac' and entering the same names as earlier re(uests. You should see that all re(uests with the same name are cached for ! seconds.
Using 0espo"se.Cache
3n addition to using the @ +utput=ache directi%e) $ou can also ena#le out"ut caching for a "age #$ using the methods of the Kttp=achePolicy class) which is e1"osed #$ the .esponse.=ache "ro"ert$.
The code re(uired to "erform the same out"ut caching as shown in the *ut"ut,ache.as"1 e1am"le is shown here. Place this code in the Page0<oad e%ent handler=
7essa)e.Text = %ateTi&e.No1.To.t"in)23 6es*onse.-ac+e..et x*i"es2%ateTi&e.No1.0!!.econ!s21H33 6es*onse.-ac+e..etcac+eabilit'2Htt*-ac+eabilit'./ublic3
This code is e(ui%alent to an ] *ut"ut,ache directi%e with a duration of 2 and a location of An$ ?or no location attri#uteA. To set the cache location to client) $ou would use the <tt",achea#ilit$.Pri%ate enumeration mem#er instead of <tt",achea#ilit$.Pu#lic. To turn off caching entirel$) $ou would use <tt",achea#ilit$.No,ache. 3n addition to the SetE$pires and Set=acheability methods shown in the "receding code) $ou can also use the SetNoSer%er=aching method in com#ination with the code from 7es"onse,ache.as"1 to "ro%ide the e(ui%alent of an @ +utput=ache directi%e with a duration of >Q and a location of ,ownstream.
An im"ortant difference is that unli'e the /pplication and Session collection o#;ects) which $ou can access #$ either 'e$ or numeric inde1) $ou can access cache items onl$ #$ their 'e$. You can also use this techni(ue to store more than ;ust strings. For instance) the code in the following e1am"le) ,acheAuthors.as"1) chec's the cache to see if a dataset alread$ e1ists. 3f not) it calls a method that creates a dataset containing data from the Authors ta#le of the Pu#s sam"le Microsoft S:. Ser%er data#ase) and then it sa%es that dataset to the cache #efore setting the ,ataSource "ro"ert$ of an ASP.NET ,ata-rid control to the default %iew of the first ta#le in the dataset ? A. 3n this e1am"le) rather than adding controls %ia the designer) $ou will add controls in <TM. %iew and then see the results in design mode. Visual Studio .NET is a true two/wa$ design tool.
,ache a ,ataSet
2. 3n the same "ro;ect as the "re%ious e1ercise) add a new &e# Form and t$"e its name as 'acheAuth rs.as(0. 2. ,hange the page<ayout "ro"ert$ of the "age to $l w:a) ut. !. Switch to <TM. %iew #$ clic'ing on the ta# control at the #ottom of the design window. Between the #eginning and ending :form; tags) add the following code=
4. ?as*Jlabel i!="title" text="%ata.et -ac+in) 8. xa&*le"
:. ?as*J!ata)"i! i!="7';"i!" bo"!e"colo"="blacC" E. F. G. 1H. bo"!e"1i!t+="$" cell*a!!in)="3" "unat="se",e""A ?+ea!e"st'le bacCcolo"="sil,e"" #ont5bol!="t"ue"BA ?ite&st'le bacCcolo"="blacC" #o"ecolo"="1+ite"BA ?alte"natin)ite&st'le bacCcolo"="1+ite" #o"ecolo"="blacC"BA
22. Switch to 0esign %iew #$ clic'ing on the ta# control at the #ottom of the design window. The resulting screen should loo' similar to the following illustration.
2!. Select View) and then select ,ode) or "ress FK to mo%e to the code window. 28. Add the following "mports statements at the to" of the code/#ehind file=
18. (&*o"ts .'ste&.%ata (&*o"ts .'ste&.%ata..@l-lient
26. Scroll down to the Page0<oad e%ent handler and add the following code=
1E. %i& %. 0s %ata.et = -ac+e2"&'%."3 1F. (# Not %. (s Not+in) T+en 1G. $H. $1. $$. $3. $4. 7essa)e.Text = "%ataset "et"ie,e! #"o& cac+e" lse %. = ;et%ata23 -ac+e2"&'%."3 = %. 7essa)e.Text = "%ataset "et"ie,e! #"o& !atabase" n! (#
7';"i!.%ataBin!23
26. Add the following function definition #elow the Page0<oad e%ent handler ?#ut a#o%e the End =lass statementA=
$E. /"i,ate Function ;et%ata23 0s %ata.et $F. $G. 3H. 31. 3$. 33. 34. 38. 3:. 3E. %i& &'%. 0s Ne1 %ata.et23 %i& -onn.t" 0s .t"in) -onn.t" = "se",e"=2local3QV.%otN TO" -onn.t" &= "!atabase=*ubsOT"uste!<-onnection='es" %i& .NL.elect 0s .t"in) .NL.elect = ". L -T au<i!, au<lna&e, au<#na&e, " .NL.elect &= "Di* F697 0ut+o"s 4H 6 Di* = 'G4:HG'"
!D. Sa%e the ,acheAuthors.as"1 and its code/#ehind file) and then #uild the "ro;ect. !C. Browse the "age using 3nternet E1"lorer. The out"ut should loo' similar to the following illustration. Note that the data was retrie%ed from the data#ase.
8 . 7efresh the #rowser) and the out"ut will loo' similar to the following illustration. Note that now the data was retrie%ed from the cache. This data will remain in the cache until the a"" domain containing the a""lication is rec$cled) or until the data is sca%enged from the cache #ecause of memor$ "ressure. You+ll learn how to "rogrammaticall$ remo%e data from the cache later in this cha"ter.
NOTE To use a trusted connection to connect to S:. Ser%er ?as shown in the "receding listingA) $ou will need to either ena#le &indows authentication and im"ersonation or set u" the ASPNET wor'er "rocess account as a S:. Ser%er login) as descri#ed in ,ha"ter C.
This would clear the dataset from the cache and force the "age to #e rendered again using fresh data. ?Note that #ecause the Page0<oad e%ent fires #efore the =lick e%ent for the #utton) $ou might need to clic' the #utton twice #efore the datagrid and the la#el are u"dated.A
ASP.NET decides which items to remo%e from the cache and when it does so) $ou need to "ro%ide ASP.NET with that information when $ou add an item to the cache. You can do this #$ using the /dd or "nsert methods of the =ache class. Both methods let $ou "ass "arameters that tell ASP.NET when and on what #asis to e1"ire $our cached content) as well as the "riorit$ $our cached content should ha%e when ASP.NET sca%enges the cache for items that can #e remo%ed to free memor$. ASP.NET determines the order in which items are sca%enged from the cache #ased on their "riorit$. *%er time) if an item is not accessed) ASP.NET will reduce its "riorit$ "eriodicall$. &hen its "riorit$ reaches a "redetermined "oint) it can #e sca%enged. You can set the "riorit$ of an item #$ "assing one of the %alues of the =ache"temPriority enumeration when calling the /dd or "nsert method. The following code is an e1am"le of the "nsert method=
-ac+e.(nse"t2"&'%.", &'%., Not+in), %ateTi&e.No1.0!!7inutes2$3, < Ti&e.*an.Ke"o, -ac+e(te&/"io"it'.Hi)+, Not+in)3
3nserts a dataset stored in the my,S o#;ect %aria#le into the cache with the 'e$ 6my,S7 Passes Nothing as the =ache,ependency "arameter Sets the e1"iration for two minutes from the time when the item is added to the cache Sets the SlidingE$piration "arameter to TimeSpan.]ero ?no sliding e1"irationA Sets the cache "riorit$ for the item to Kigh Sets the call#ac' function for the item to Nothing ?no call#ac' functionA NOTE The /dd and "nsert methods of the =ache class "ro%ide essentiall$ the same functionalit$) with two differences. The first difference is that all "arameters of the /dd method are re(uired) so e%en if $ou are not using a "articular "arameter) $ou must still "ass a "laceholder "arameter. The "nsert method is o%erloaded) which ma'es it the easier method to use when $ou want to "ass onl$ some of the "ossi#le "arameters. The second difference is that the /dd method returns an o#;ect that re"resents the item ;ust added to the cache) while the "nsert method doesn+t return a %alue.
You can also call the "nsert method "assing ;ust the Ley EStringF and "tem E+b*ectF "arameters) "assing the Ley) "tem) and =ache,ependency "arameters) or "assing the Ley) "tem) =ache,ependency) /bsoluteE$piration E,ateTimeF) SlidingE$piration) and ETimeSpanF "arameters.
Note that to set u" a 'e$ de"endenc$ without an$ file de"endencies) $ou must create an arra$ of 'e$s ?e%en if there is onl$ one 'e$A) "ass Nothing as the first argument to the constructor) and "ass the arra$ of 'e$s as the second=
%i& [e's2H3 0s .t"in) [e's2H3 = "&'[e'Na&e" &'%e*en!enc' = Ne1 -ac+e%e*en!enc'2Not+in), [e's3
*nce $ou create the instance of =ache,ependency) it can #e "assed as a "arameter to the /dd or "nsert method of the =ache class=
-ac+e.(nse"t2"&'%.", &'%., &'%e*en!enc'3
/dd1ile,ependency) and /dd1ile,ependencies. Each hel"er method ta'es either a string or an /rray<ist of strings as an argument. The s$nta1 for the /dd=ache"tem,ependency method) which ta'es a String argument that s"ecifies the 'e$ on which the cached out"ut de"ends) is
6es*onse.0!!-ac+e(te&%e*en!enc'2"&'-ac+e[e'"3
The s$nta1 for the /dd=ache"tem,ependencies method) which ta'es an /rray<ist argument containing strings that s"ecif$ the 'e$s on which the cached out"ut de"ends) is
%i& al[e's 0s Ne1 0""a'List23 al[e's.0!!2"&'Fi"st-ac+e[e'"3 al[e's.0!!2"&'.econ!-ac+e[e'"3 6es*onse.0!!-ac+e(te&%e*en!encies2al[e's3
The s$nta1 for the /dd1ile,ependency method) which ta'es a String argument that s"ecifies the "ath to the file on which the cached out"ut de"ends) is
6es*onse.0!!File%e*en!enc'2"cJQ&'#ile.txt"3
The s$nta1 for the /dd1ile,ependencies method) which ta'es an /rray<ist argument containing strings that s"ecif$ the files on which the cached out"ut de"ends) is
%i& alFiles 0s Ne1 0""a'List23 alFiles.0!!2"cJQ&'#ile.txt "3 alFiles.0!!2"cJQ&'#ile$.txt "3 6es*onse.0!!File%e*en!encies2alFiles3
the Authors ta#le that uses the S:. Ser%er &e# Assistant to write a new <TM. file when the data in the ta#le changes. NOTE Because MS0E) the des'to" %ersion of S:. Ser%er) does not su""ort the S:. Ser%er &e# Assistant) the following e1am"le re(uires the use of the full %ersion of S:. Ser%er. 3f $ou do not own a co"$) $ou can download or order a trial %ersion of S:. Ser%er at http://www.microsoft.com/s4l/e%aluation/trial/default.asp.
The second "art of the "rocess is to create the "age that will use the cache #$ consuming the cached data.
8. ,hange the name of the class in AuthorsTrigger.as"1 from ,acheAuthors to Auth rsTrigger. Q. 3n the Page0<oad e%ent handler) re"lace the line that reads =acheE6my,S7F5,S with the following code) which adds a file de"endenc$ on the file created #$ the S:. &e# Assistant=
:. -ac+e.(nse"t2"&'%.", %., < Ne1 -ac+e%e*en!enc'2.e",e".7a*/at+2"aut+o"s.+t&"333
K. 3n the -et,ata function) modif$ the connection string in the file to "oint to the S:. Ser%er instance where $ou created the trigger. D. Sa%e AuthorsTrigger.as"1 ?and its code/#ehind moduleA and #uild the "ro;ect. C. Browse the "age using 3nternet E1"lorer. The out"ut should loo' similar to the following illustration. Note that the data was retrie%ed from the data#ase.
2 . 3f $ou clic' the 7efresh #utton in the #rowser) the data will #e ser%ed from the cache and the out"ut will loo' similar to the following illustration.
To ma'e sure this "rocedure was successful) o"en the Authors ta#le in S:. Enter"rise Manager ?#$ right/clic'ing the Authors ta#le and selecting *"en Ta#le) 7eturn All 7owsA and change one of the %alues in a row in the ta#le that matches the (uer$ criteria for AuthorsTrigger.as"1 ?Gi"MC86 CA. ?Mo%e the cursor off the row #eing u"dated to ma'e sure the u"date occurs.A Now refresh the #rowser. E1ce"t for an$ data that $ou+%e changed) the out"ut should loo' li'e the illustration that follows ste" D. IMPORTANT &hile the "receding e1am"le is effecti%e in "urging the cached data when the underl$ing data#ase ta#le changes) there is a ca%eat to its use. Because this techni(ue relies on the u"date of a file in the file s$stem) it is "ossi#le that a "ro#lem with that file ?such as incorrect "ermissionsA could "re%ent the trigger from u"dating the file) which could lead to a #loc'ing situation. Since what $ou+re after with caching is im"ro%ed "erformance and scala#ilit$) clearl$ #loc'ing would #e a #ad thing. So if $ou+re considering using a techni(ue li'e this in $our a""lication) ta'e care to minimiGe as much as "ossi#le the things that could go wrong) and ma'e sure to test the a""lication thoroughl$) "articularl$ under loads similar to what $ou e1"ect the a""lication to #ear.
Store a""lication/s"ecific configuration settings for eas$ de"lo$ment. Set u" a target 33S a""lication. ,o"$ content) &e# Forms "ages) &e# ser%ices) and assem#lies. 0e"lo$ an a""lication using Visual Studio .NET.
0e"lo$ing a""lications has #een a long/standing #ane of man$ a classic ASP de%elo"er+s e1istence) and for good reason. &hile it was eas$ enough to de"lo$ or re"lace static content and the ASP files themsel%es) other "ortions of the a""lications) such as com"onents and a""lication/ s"ecific configuration settings) re(uired greater effort to de"lo$ and often necessitated a shutdown of the a""lication to re"lace. 0e"lo$ment is another area in which the im"ro%ements in ASP.NET trul$ shine. ASP.NET eliminates man$ of the de"lo$ment shortcomings in classic ASP) ma'ing it "ossi#le for the first time to de"lo$ an ASP.NET a""lication sim"l$ #$ co"$ing all of the necessar$ files to the 33S a""lication director$ where the a""lication will #e de"lo$ed. This cha"ter will discuss the ste"s for de"lo$ing ASP.NET &e# a""lications) #oth manuall$ and through Microsoft Visual Studio .NET.
IMPORTANT Microsoft &indows -P offers multi"le %iews of the ,ontrol Panel. The default %iew is called category %iew and the o"tional %iew is called the classic %iew. For this cha"ter) all instructions will #e for the classic %iew. To switch from categor$ %iew to classic %iew) clic' on Switch To ,lassic View on the left side of the ,ontrol Panel. To determine if a director$ in 33S has #een configured as an a""lication) com"lete the following ste"s.
!. 3f the director$ is not configured as an a""lication) $ou can create an a""lication root at this le%el. 7ight/clic' the director$) select Pro"erties) and then clic' the ,reate #utton in the 0irector$ ta# ?or Virtual 0irector$ ta#A of the Pro"erties dialog #o1. The Pro"erties dialog #o1 for the ,ha"terO2! director$ is shown in the following illustration. ?Note that the dialog for 33S 6. is slightl$ different in the o"tions it "resents.A
8. ,lic' *> to u"date the director$ with the new setting. The director$ should now show the icon for an a""lication root) as shown in the following illustration. This ste" should not #e necessar$ for directories that are the root of a Visual Studio .NET &e# A""lication "ro;ect) since Visual Studio .NET configures the root director$ of this "ro;ect t$"e as an A""lication in 33S automaticall$.
As $ou can see in these figures) 33S a""lication roots can #e nested one #eneath the other. <owe%er) each a""lication root defines its own a""lication #oundar$. *ne ad%antage of this is that it allows $ou to "artition $our a""lication as necessar$. For e1am"le) $ou can "ro%ide customiGed configuration settings or use different %ersions of a "ri%ate assem#l$ with different "arts of $our a""lication. The most im"ortant thing to remem#er) howe%er) is that the a""lication root is where the #in director$ and @lo#al.asa1 and &e#.config files should #e located.
howe%er) that if the "h$sical director$ contains ASP.NET/s"ecific configuration and start/u" files ?&e#.config and @lo#al.asa1A) #oth 33S a""lications will share the settings in these files. *ne im"ortant ca%eat regarding this sharing is that when a su#folder containing a &e#.config file or a @lo#al.asa1 file is defined as an a""lication root in one of the 33S a""lications) it+s not configured as an a""lication root in the second 33S a""lication. 3n the first case) shown in the following illustration) re(uests to the ,ha"terO2! su#folder of the as"nets#s folder will use the @lo#al.asa1 file contained in the ,ha"terO2! folder for start/u" code.
3n the second case) shown in the following illustration) the @lo#al.asa1 file contained within this su#folder will #e ignored) since the folder is not configured as an a""lication in 33S.
You should also note that certain settings in the &e#.config file are a""lica#le onl$ at the a""lication root le%el. For e1am"le) if the &e#.config file contained in the ,ha"terO2! folder shown in the "receding illustration contains an :authentication; section) a configuration error will result #ecause this section can #e defined onl$ at the machine ?machine.configA or a""lication root le%el. The 97. for a s"ecific a""lication root in 33S is a "roduct of the domain name ?if an$A associated with the 3P address that is assigned to the 33S &e# site) "lus the folder hierarch$ #etween the 33S &e# site and the a""lication root. Thus) in the "re%ious illustration) where the as"nets#s a""lication root resides under the default &e# site) the 97. to reach the ,ha"terO2! director$ would #e either http://localhost/aspnetsbs/=hapter0>A/ or http://ser%ername/aspnetsbs/=hapter0>A/. This wor's if $ou re(uest the 97. from the ser%er containing the a""lication) #ecause re(uests for localhost or ser%ername ?where ser%ername re"resents the name of the &e# ser%er containing the a""licationA are automaticall$ directed to the default &e# site. 3f $ou wanted to ma'e the content of the ,ha"terO2! a""lication root a%aila#le on the 3nternet) $ou+d need to create a new 33S &e# site) assign a "u#licl$ a%aila#le 3P address on the machine to the &e# site) and then create ?or ha%e a 0NS "ro%ider createA a 0NS entr$ that ma"s $our chosen domain name ?for e1am"le) www.aspnetsbs.comA to that 3P address. Then $ou would create a new a""lication root under the new &e# site that ma"s to the ,ha"terO2! director$ in the file s$stem. You could access this a""lication from the 3nternet using the 97. http://www.aspnetsbs.com/=hapter0>A/. Note that if $ou ha%e director$ #rowsing disa#led ?the defaultA) $ou will need to set a default document in the 0ocuments ta# of the Pro"erties dialog #o1 for the director$) in case the user does not enter a document name. The name of the default document should match the name of a "age that e1ists in the director$. This will allow access to content using a 97. that does not contain a document name) such as the "receding 97.s. *therwise) the name of the desired file must #e a""ended) or an error will occur.
&hen $our a""lication starts u") ASP.NET caches the %alues of the appSettings section in a string collection called =onfigurationSettings./ppSettings. You can access these settings #$ "assing the desired 'e$ to this collection) as shown here=
Label1.Text = -on#i)u"ation.ettin)s.0**.ettin)s2"&'-on#i)[e'"3
3n addition to automaticall$ loading and caching these %alues for $ou at a""lication start/u") ASP.NET monitors the &e#.config file?sA for changes and d$namicall$ reloads the contents of the appSettings configuration section if changes are detected.
The "ractice files for this cha"ter include an e1am"le of using the appSettings configuration section to store and dis"la$ a sim"le te1t %alue. See the &e#.config file for an e1am"le of storing the %alueI see the A""Settings.as"1 file for an e1am"le of retrie%ing and dis"la$ing the %alue. IMPORTANT &hile appSettings "ro%ides a storage location for a""lication/ s"ecific configuration settings that is almost ideal in its ease of use and "erformance) note that since the %alues are stored as "lain te1t in a file in the &e# s"ace) some securit$ ris' is associated with this a""roach. 3f a %ulnera#ilit$ in the &e# ser%er allowed access to the &e#.config file) an$ sensiti%e information stored in appSettings could #e com"romised. For this reason) ne%er store sensiti%e information) such as usernames) "asswords) or credit card or account num#ers) in the appSettings section of &e#.config. For items of medium sensiti%it$) one solution is to add the items to the appSettings of the machine.config file) which is not located within the &e# s"ace and thus harder to com"romise. >ee" in mind) howe%er) that the appSettings stored in Machine.config are a%aila#le to e%er$ a""lication on the ser%er) unless the$ are loc'ed down using the :location; tag. ?See ,ha"ter Q for more information on loc'ing down configuration settings.A For more information on storing sensiti%e information in &e# a""lications) see the 4Storing Secrets5 section of the following securit$ article on the MS0N &e# site= http://msdn.microsoft.com/library/enCus/dnnetsec/html/SecNetchQV.asp.
*nce $ou+%e set u" the target director$ in 33S ?ma""ed to a "h$sical folder on the host machineA) $ou+re read$ to co"$ all the necessar$ files to the target director$. You can do this #$ using an$ num#er of commonl$ a%aila#le tools) from the -,*PY command to &e#0AV. You can e%en drag/and/dro" files to and from a networ' share using Microsoft &indows E1"lorer. 3f $ou+re using code/#ehind in $our &e# Forms "ages or user controls) $ou+ll need to decide whether to de"lo$ the code/#ehind class files containing $our source code to the target ser%er. 3f $ou+re using the Src attri#ute of the @ Page or @ =ontrol directi%e to ha%e ASP.NET d$namicall$ com"ile $our code/#ehind classes) $ou ha%e to de"lo$ the class files) or the a""lication will not function. 3f $ou want to a%oid de"lo$ing the code/#ehind class files) $ou can use the "nherits attri#ute of the @ Page or @ =ontrol directi%e instead of the Src attri#ute. 9sing the "nherits attri#ute re(uires $ou to manuall$ com"ile $our code/#ehind classes and "ut the resulting assem#lies in the a""lication+s #in su#director$. Pro;ects created with Visual Studio .NET will #e created using the "nherits attri#ute of the @ Page or @ =ontroldirecti%e. As a result) $ou must #uild the "ro;ect #efore de"lo$ing it) whether $ou de"lo$ the "ro;ect manuall$ or #$ using Visual Studio+s de"lo$ment tools.
/E s"ecifies that all su#directories are to #e co"ied) whether em"t$ or not. /L s"ecifies that file and director$ attri#utes on the destination should #e set to match the source. /+ s"ecifies that ownershi" and A,. information should #e co"ied to the destination. This is useful when using domain accounts to set A,.s.
You can find out a#out all of the command/line "arameters a%aila#le with -,*PY #$ e1ecuting -,*PY EU.
difficult to do remotel$. Additionall$) registering a com"onent made that com"onent a%aila#le to an$ a""lication on the ser%er) which is not allowed in a shared ser%er en%ironment. Because .NET assem#lies are self/descri#ing and assem#lies are "ri%ate to an a""lication #$ default) $ou can sim"l$ co"$ an assem#l$ to the #in su#director$ of an a""lication and it will #e a%aila#le for use #$ the a""lication automaticall$. Pri%ate assem#lies do not need to #e registered to #e used) and the$ are a%aila#le onl$ to the a""lication in whose #in director$ the$ reside.
Gl #al Asse%#lies
The e1ce"tion to the rule of -,*PY de"lo$ment a""lies to assem#lies that $ou want to ma'e a%aila#le to more than one a""lication on the ser%er without ha%ing multi"le co"ies of the assem#l$ ?one for each a""licationA. These assem#lies need to #e installed in the @A,. 7emem#er that assem#lies installed in the @A, must #e strongl$ named. You can do this #$ using the al.e1e command/line tool. *nce $ou ha%e a strongl$ named assem#l$) $ou can install it into the @A, in se%eral wa$s=
Microsoft &indows 3nstaller 2. This is the "referred method for installing assem#lies into the @A, #ecause it "erforms reference counting and "ro%ides transactional installation) neither of which are a%aila#le with the other o"tions. See the &indows 3nstaller documentation for more information on "ac'aging and installing a""lications with &indows 3nstaller 2. .
gacutil.e1e This command/line utilit$ lets $ou add assem#lies to the @A,) remo%e assem#lies from the @A,) and list the contents of the @A,.
&indows E1"lorer The .NET Framewor' installs a shell e1tension that lets $ou sim"l$ drag/and/dro" strongl$ named assem#lies into the @A, from an$ &indows folder. The @A, is located at Z&in0irZNassem#l$.
U(dating Asse%#lies
3n addition to the "ro#lems of registering ,*M com"onents) 33S loc'ed an$ ,*M com"onent as soon as it was called. Because of this) re"lacing or u"dating a ,*M com"onent often re(uired sto""ing the 33S &e# ser%ice) unregistering the old com"onent) co"$ing o%er the new com"onent) registering the new com"onent) and restarting the &e# ser%ice. For man$ a""lications) this meant an unacce"ta#le amount of downtime. &ith "ri%ate assem#lies) this is no longer a "ro#lem #ecause of the wa$ ASP.NET loads assem#lies. 9nli'e 33S under classic ASP) which loaded a com"onent into memor$ and loc'ed it on dis' until the &e# a""lication ?or 33SA was shut down) ASP.NET first ma'es a shadow co"$ of each assem#l$ file and then loads and loc's the shadow file instead of the original. ASP.NET then monitors the original files for changes. 3f changes are detected) ASP.NET fulfills an$ e1isting re(uests with the current co"$ of the assem#l$) and then it loads the new assem#l$ and fulfills new re(uests using the u"dated assem#l$) discarding the old assem#l$. This allows $ou to easil$ u"date an$ "ri%ate assem#l$ used #$ $our a""lication without needing to shut down the &e# ser%er) e%en tem"oraril$.
9sing ,o"$ Pro;ect is sim"le and straightforward) #ut it offers onl$ limited control o%er which "ro;ect files are co"ied and how the$+re co"ied. NOTE The following section descri#es a feature a%aila#le onl$ in Visual Studio .NET Professional) Enter"rise 0e%elo"er) or Enter"rise Architect editions. This functionalit$ is not a%aila#le with the Standard edition of Visual Basic .NET.
A &e# Setu" "ro;ect allows $ou to s"ecif$ a %ariet$ of o"tions a#out how the a""lication will #e de"lo$ed) ranging from which files to include to the name of the de"lo$ed a""lication and the location of the de"lo$ed files. &hen #uilt) the &e# Setu" "ro;ect creates a &indows 3nstaller .msi file that can #e co"ied to the target machine and e1ecuted to de"lo$ the a""lication.
6. Select #oth the Primar$ *ut"ut and ,ontent Files items from the list. 9se the ,trl 'e$ to select multi"le items. ,lic' *>. K. Select the &e# A""lication Folder node in the File S$stem editor. Then locate the Virtual0irector$ entr$ in the Pro"erties window and change it to the name of a target director$ on the de"lo$ment target. This director$ does not need to e1istBit will #e created. S"ecif$ onl$ a relati%e "ath to the %irtual director$Bdo not use dri%e letters or a#solute 97.s. D. Also in the Pro"erties window) set the ,efault,ocument "ro"ert$ to the name of the default document for the &e# a""lication o"ened in Ste" 2. C. 7ight/clic' the solution containing the &e#Setu"2 "ro;ect) and select ,onfiguration Manager. 2 . 3n the ,onfiguration Manager dialog #o1) ensure that the Build chec' #o1 for &e#Setu"2 is chec'ed. 3f it is not) chec' it) and then clic' ,lose. 22. Build the solution #$ clic'ing Build) and then selecting Build Solution. 22. .ocate the set/u" "ac'age created #$ the &e# Setu" "ro;ect. 3t should #e located in the 0e#ug or 7elease su#director$ of the director$ containing the &e# Setu" "ro;ect) and will #e called &e#Setu"2.msi if $ou used the default "ro;ect name of &e#Setu"2. ,o"$ the file to the target ser%er and e1ecute it. The following illustration shows the initial screen of the installation "rogram.
2!. &hen $ou+%e com"leted the Setu" &iGard) #rowse the newl$ de"lo$ed a""lication using the 97. http://machinename/%dirname/) where machinename is the name of the machine where $ou installed the set/u" "ac'age and %dirname is the name that $ou s"ecified for the Dirtual,irectory "ro"ert$ in Ste" K. 3f the de"lo$ment wor'ed correctl$) $ou should see the default "age for the &e# a""lication.
IMPORTANT The installation created #$ Visual Studio .NET does not install the .NET Framewor'. You can run the "rogram dotnetf$.e$e in the dotNet1ramework folder of the Visual Studio .NET Prere(uisites ,0 #efore e1ecuting the installation "ac'age to allow the "ro;ect to install) if the target machine does not alread$ ha%e the .NET Framewor' installed.3n addition to "ro%iding fine/grained control o%er the files and out"uts included in the installation "ac'age) this method allows $ou to automaticall$ install shared assem#lies in the @A,. 3t also allows $ou to uninstall a &e# a""lication with a single command) either #$ right/clic'ing the installation "ac'age and selecting 9ninstall or #$ locating the a""lication+s entr$ in the &indows AddE7emo%e Programs a""let) which $ou can access from the ,ontrol Panel.
To
Do this
,reate an installation "ac'age Add a &e# Setu" "ro;ect to the solution for the &e# a""lication with fine/grained control of to #e "ac'aged) and set its "ro"erties and out"uts as desired. installation items nd uninstall a#ilit$
9se tracing to learn how $our a""lication is running. 0e#ug ASP.NET a""lications. 9se the Visual Studio .NET de#ugger.
This #oo' has co%ered a wide %ariet$ of to"ics related to ASP.NET de%elo"ment. 3 ho"e $ou+ll #e a#le to a%oid most "ro#lems while de%elo"ing $our ASP.NET &e# a""lications. 3ne%ita#l$) howe%er) there will #e times when $our code doesn+t do what $ou e1"ect it to) or $ou+ll run into errors or "ro#lems that "re%ent $our a""lication from wor'ing. This final cha"ter will loo' at what to do when that ha""ens. 3t+s not intended to ma'e $ou an e1"ert de#ugger) #ut rather to gi%e $ou an o%er%iew of the tools a%aila#le for de#ugging in ASP.NET. To sa$ that classic ASP did not offer de%elo"ers much su""ort for de#ugging their a""lications would #e a colossal understatement. 0es"ite #eing a %er$ sim"le and "roducti%e de%elo"ment en%ironment) classic ASP left a lot to #e desired in terms of de#ugging and error messages. For e1am"le) in classic ASP $ou had no con%enient wa$ to access the state of the current <TTP re(uest or of the other collections) such as the #ueryString or 1orms collections. ASP.NET addresses this issue through a new feature called tracing) which 3+ll discuss in the first "art of this cha"ter. Additionall$) classic ASP error messages were often cr$"tic at #est. 3f $ou were luc'$) the$ told $ou the line of the ASP "age on which the error occurred. 9nfortunatel$) this information could #e misleading. The error might ha%e occurred in a function called #$ that "age) #ut $ou wouldn+t 'now that from the error message. ASP.NET "ro%ides much richer error re"orting) including a stac' trace of the functions that led u" to an error condition) ma'ing it much easier to locate the root cause of the error. The Microsoft .NET Framewor' S0> shi"s with its own de#ugger) so de%elo"ers who are not using Microsoft Visual Studio .NET can attach it to the "rocess of their ASP.NET a""lication and ste" through their code to find and fi1 "ro#lems. Most often) howe%er) using the de#ugger in Visual Studio .NET can #e the most efficient wa$ to de#ug $our a""lication. 3+ll discuss the im"ro%ed error re"orting and the S0> de#ugger in the second half of this cha"ter.
Tracing
As mentioned) one wea'ness of classic ASP was the lac' of an eas$ wa$ to get information a#out the current re(uest. You should create reusa#le include files to write out the contents of the %arious collections of the re(uest o#;ect) #ut there was no sim"le method of ma'ing this information a%aila#le. ASP.NET "ro%ides a solution in the form of tracing) which "ro%ides a su#stantial amount of information a#out re(uests that ha%e #een e1ecuted) either at the "age le%el or the a""lication le%el) as well as a wa$ to get $our own custom de#ug information without e1"osing it to the users of $our a""lication.
!. Add a la#el to the "age #$ dragging a la#el from the tool#o1 onto the form. 3n Flow.a$out) the la#el will mo%e to the u""er left of the form no matter where $ou "lace it. ,hange the Te$t "ro"ert$ to Trace is ena#led f r this (age. 8. ,lic' in an em"t$ area of the "age to select the ,+=!9ENT o#;ect) locate the trace "ro"ert$ in the Pro"erties window) and set its %alue to True. Q. Sa%e Sim"leTrace.as"1 and the "ro;ect) and then #uild the "ro;ect. 6. Browse Sim"leTrace.as"1 using Microsoft 3nternet E1"lorer. The resulting screen should loo' similar to the following illustration.
The trace out"ut includes such information as the contents of the cookies) forms) and 4uerystring collections. Therefore) "age/le%el tracing using the Trace attri#ute of the @ Page directi%e should #e restricted to non"roduction s$stems #ecause the out"ut is %isi#le to an$ client re(uesting that "age. Although $ou can use one of the configuration o"tions detailed in the ne1t section to configure ASP.NET to "ro%ide "age/le%el trace out"ut onl$ for re(uests from the local s$stem) $ou+re #est off stic'ing to a""lication/le%el tracing on "u#licl$ a%aila#le a""lications.
IMPORTANT Tracing has an im"act on a""lication "erformance) and the information that it "ro%ides could "otentiall$ #e used #$ malicious users to attac' $our a""lication) so for #oth "erformance and securit$ reasons $ou should use tracing onl$ in de%elo"ment en%ironmentsI disa#le tracing #efore de"lo$ing an a""lication to a "roduction ?"u#lic/facingA en%ironment.
C. Sa%e the changes to &e#.config. To allow access to the logged trace out"ut) ASP.NET "ro%ides an KttpKandler that is ma""ed to a s"ecial 97. called trace.a$d. A""ending trace.a$d to the #ase 97. for the a""lication will dis"la$ the list of currentl$ a%aila#le traces) as shown in the following illustration. ,lic'ing View
0etails for a "articular trace dis"la$s its out"ut. ,lic'ing ,lear ,urrent Trace clears all current entries from the trace log and allows more re(uests to #e logged.
"age/le%el tracing $ou should alwa$s dou#le/chec' $our "ages #efore "u#lishing them to a "u#lic ser%er to ensure that the trace attri#ute for each "age has #een remo%ed or set to 1alse. ASP.NET+s trace functionalit$ minimiGes this "ro#lem #$ allowing de%elo"ers to write to the trace out"ut instead of writing to the "age out"ut. Assuming that "age/le%el trace out"ut has not #een ena#led) this "re%ents end/users from seeing the trace statements written #$ the de%elo"er. IMPORTANT As noted earlier) ena#ling tracing for a "age or for an a""lication does carr$ some "erformance o%erhead. E%en though the ASP.NET trace functionalit$ allows $ou to lea%e tracing ena#led without trace out"ut #eing %iewed #$ end/users) when "erformance is im"ortant) it is a good idea to disa#le tracing for an a""lication at #oth the "age and a""lication le%el. The trace out"ut is e1"osed to de%elo"ers %ia the Trace=onte$t class) which is a%aila#le from the Page.Trace "ro"ert$ ?which can #e referred to within a "age sim"l$ as Trace) since the Page o#;ect is assumedA. There are two methods for writing to the trace out"ut) Trace. rite and Trace. arn.
message is a string containing the message to #e written to the trace out"ut. category is a string containing a descri"tion of the message ?%aria#le) statement) or whate%er the de%elo"er wants as a categor$A. error"nfo is an e1ce"tion o#;ect) which allows e1ce"tions to #e logged to the trace out"ut.
The categor$ and error3nfo "arameters allow de%elo"ers to set u" so"histicated a""lication/wide tracing #$ defining s"ecific categories of logged information and using them consistentl$ across an a""lication. The following e1am"le shows how to create a "age that tests if tracing is ena#led for the "age) and then writes a sim"le message to the trace out"ut.
K. ,hange to the code %iew #$ "ressing FK. Scroll down to the Page0<oad e%ent handler and add the following code=
F. (# 2T"ace.(s nable!3 T+en G. 1H. Label1.Text = "4"itin) 'Hello #"o& /a)e!' to T"ace Lo)..." T"ace.4"ite2"Hello #"o& /a)e!"3 n! (#
22. Sa%e Trace&rite.as"1) its code/#ehind file) and the "ro;ect) and then #uild the "ro;ect. 22. Browse Trace&rite.as"1 using 3nternet E1"lorer. The resulting screen should loo' similar to the following illustration. ?Notice the hello message on the first line under the Trace 3nformation heading.A
Ta#le 4834. Trace +utput Sections Sectio" ,ollection Ser%er Varia#les Descriptio" -ET re(uest. 0is"la$s a list of the ser%er %aria#les for the re(uest.
6e#ugging
3n an ideal world) all "rogrammers would #e so s'illed and attenti%e to detail that the$ would write #ug/free code. 9nfortunatel$) we do not li%e in an ideal world. As such) de#ugging) or trac'ing down the source of errors and erroneous results) is an im"ortant tas' that all de%elo"ers need to "erform #efore the$ allow end/users to use their a""lications. This section will discuss some techni(ues for reducing the num#er of #ugs in $our code u" front. &e+ll also loo' at the tools and techni(ues in ASP.NET and the .NET "latform used for de#ugging a""lications.
S)nta0 err rs These errors occur when code #rea's the rules of the language $ou+re using) such as a Visual Basic Sub statement without a closing End Sub) or a forgotten closing curl$ #race ?`A in ,J. These errors are the easiest to locate. The language com"iler or 30E will alert $ou to them and will not allow $ou to com"ile $our "rogram until $ou correct them.
Se%antic err rs These errors occur in code that is correct according to the rules of the com"iler) #ut that causes une1"ected "ro#lems such as crashes or hanging on e1ecution. A good e1am"le is code that e1ecutes in a loo" #ut ne%er e1its the loo") either #ecause the loo" de"ends on a %aria#le whose %alue was e1"ected to #e something different than it actuall$ was or #ecause the "rogrammer forgot to increment the loo" counter. Another categor$ of errors in this area includes re(uesting a field from a dataset. 9nless $ou are using a t$"ed dataset) $ou ha%e no wa$ to tell if the field actuall$ e1ists at com"ile time. These #ugs are harder to detect and are one t$"e of runtime error.
: gic err rs .i'e semantic errors) logic errors are runtime errors. That is) the$ occur while the "rogram is running. But unli'e semantic errors) logic errors do not cause the a""lication to crash or hang. 3nstead) logic errors result in une1"ected %alues or out"ut. This can #e a result of something as sim"le as a mist$"ed %aria#le name that ha""ens to match another declared %aria#le in the "rogram ?an argument for descri"ti%e %aria#le names rather than sim"le onesA. This t$"e of error can #e e1tremel$ difficult to trac' down and eliminate) "articularl$ since in com"le1 "rograms it can #e difficult ?if not im"ossi#leA to re"roduce a logic error re"orted #$ a user.
Pre&enting Bugs
Before we get into the discussion of how to de#ug the %arious errors $ou+re a"t to run into in $our a""lications) let+s ta'e some time to loo' at strategies for "re%enting #ugs in the first "lace. Pre%enting #ugs is a much more efficient and much less e1"ensi%e wa$ to "roduce #ug/free software. The following list contains a few strategies that will hel". This is not a com"rehensi%e list #$ an$ means) #ut a""l$ing these strategies consistentl$ will hel" $ou s"end less time de#ugging $our code and more time en;o$ing its rewards.
!rite reada#le c de ,hoose ?or de%elo"A and ma'e consistent use of naming and coding standards. 3t+s not that im"ortant which standard $ou use) such as <ungarian notation ?t$t1irstNameA or Pascal ,asing ?1irstNameA or another naming con%ention) as long as $ou use one. You should also stri%e for consistenc$ in $our comments and encourage li#eral commenting of code. An$thing that ma'es code more reada#le and easier to understand will hel" eliminate #ugs from the get/go.
'reate effecti&e test (lans The onl$ effecti%e wa$ to eliminate logic errors is to test e%er$ "ath of $our a""lication with e%er$ "ossi#le data %alue ?or re"resentati%e range of dataA that a user could enter. This is difficult to manage without effecti%e "lanning. You should create $our test "lans at the same time $ou+re designing the a""lication) and $ou should u"date these "lans as $ou modif$ the a""lication design. To #e effecti%e) the test "lans need to descri#e how to test each "iece of functionalit$ in the a""lication. Test "lans and other design documents can also hel" highlight design "ro#lems #efore the$ are im"lemented) "re%enting a wide arra$ of #ugs.
Use a rich I6E You don+t necessaril$ need to use Visual Studio .NET to de%elo" $our &e# a""licationsB ASP.NET does not re(uire itB#ut $ou should consider de%elo"ing in an 30E that "ro%ides s$nta1 chec'ing as $ou t$"e. 3f $ou de%elo" with Note"ad) it is too eas$ to amass a num#er of s$nta1 errors that go unnoticed until $ou tr$ to run the "age. Then $ou get to s"end the ne1t half hour or more eliminating the errors) one at a time) until $ou finall$ get the code to run. This is not an efficient wa$ to write code.
Get an ther (air f e)es &hether $ou+re wor'ing on a team or #uilding an a""lication on $our own) it is im"ortant to ha%e someone else re%iew $our code ?and test it) if "ossi#leA. 0e%elo"ers are sim"l$ too close to their own code to catch e%er$ #ug #efore ?and sometimes e%en afterA testing. A re%iew #$ a different "air of e$es can hel" $ou catch what $ou+%e missed.
As mentioned in the introduction to this cha"ter) ASP.NET "ro%ides a great deal of information to de%elo"ers when a #ug or error halts e1ecution of an a""lication #$ throwing an e1ce"tion. Some of this information) such as the stac' trace) is a%aila#le regardless of the mode that the code was com"iled in. The following e1am"le shows what ha""ens #$ default when a "ro;ect created in Visual Studio .NET di%ides #$ Gero in code to force an e1ce"tion to #e thrown.
to the to" of the code/#ehind file) #efore the class definition. 8. Scroll down to the Page0<oad e%ent handler and add the following code=
8. %i& 9ne 0s (nte)e" = 1 :. %i& Ke"o 0s (nte)e" = H E. %i& 6esult 0s (nte)e" F. %ebu).0sse"t2Ke"o ?A H, < G. "Value o# Ke"o 1ill "esult in exce*tion."3
22. Sa%e 0i%B$Pero.as"1) its code/#ehind file) and the "ro;ect) and then #uild the "ro;ect. 22. Browse 0i%B$Pero.as"1 using 3nternet E1"lorer. The resulting screen should loo' similar to the following illustration.
The "re%ious illustration shows the information a%aila#le when the a""lication is com"iled in 0e#ug mode) the default when $ou create an a""lication using Visual Studio .NET. 3nformation such as the code with the error shown in conte1t) as well as a stac' trace) is a%aila#le onl$ in 0e#ug mode. The following e1am"le shows the out"ut when an error occurs and de#ugging is not ena#led.
Q. Browse 0i%B$Pero.as"1 again using 3nternet E1"lorer. The resulting screen should loo' similar to the following illustration.
6. 7e%erse these ste"s to re/ena#le de#ugging for the ,ha"terO28 "ro;ect. The error message dis"la$ed this time is less informati%e) #ut this is "otentiall$ a good thing. For instance) none of the actual code is re"roduced) and the stac' trace is minimal. Thus) turning off de#ugging can reduce the ris' of e1"osing sensiti%e information in $our code #$ the occurrence of an e1ce"tion. *f course) it+s #est to a%oid ha%ing sensiti%e information in $our code in the first "lace) #ut ma'ing sure that de#ugging is disa#led for "u#lic/facing s$stems can "rotect #oth $our code and an$ sensiti%e information therein. IMPORTANT Because e%en the error "age returned when de#ugging is disa#led could "ro%ide useful information to a malicious user ?such as the %ersion information for the %ersion of the .NET Framewor' $ou are runningA) $ou should) in addition to disa#ling de#ugging) "ro%ide custom error/handling "ages where%er "ossi#le) as e1"lained in ,ha"ter Q. At a minimum) $ou should
set the mode attri#ute of the :customErrors; element to On) so that no information other than the fact that an error has occurred is returned to the user+s #rowser.
!. 7ight/clic' 0i%B$Pero.as"1 in Solution E1"lorer and select Set As Start Page. This sets 0i%B$Pero.as"1 to #e the "age that is loaded when the "ro;ect is run or de#ugged. 8. &hile it+s o#%ious what the "ro#lem is in this e1am"le) su""ose $ou needed to determine e1actl$ wh$ the di%ide #$ Gero e1ce"tion was ha""ening. *ne wa$ to find out is to ste" through the code and chec' the %alues of $our %aria#les as each line e1ecutes. Start #$ scrolling down to the Page0<oad e%ent handler. Along the left side of the code window is a gra$ #ar. ,lic' on the gra$ #ar to the left of the line with the 0e#ug.Assert. A red dot indicating a #rea'"oint will a""ear on the gra$ #ar) and the line will #e highlighted. The following illustration shows the #rea'"oint set in Visual Studio .NET.
The "resence of a #rea'"oint ?or #rea'"ointsA will cause the a""lication to sto" e1ecuting and dis"la$ the de#ugging interface in the 30E when $ou run the a""lication using the de#ug feature of Visual Studio. You can then e1amine the %alue of %aria#les) ste" through the code line #$ line) and ta'e other actions to determine wh$ $our code isn+t wor'ing as $ou e1"ect.
Q. 7un the a""lication #$ selecting Start from the 0e#ug menu ?or #$ "ressing FQA. Since the #rea'"oint set in the "re%ious ste" is in the Page0<oad e%ent handler) it will #e reached immediatel$. The screen will loo' something li'e the following illustration.
There are se%eral wa$s to determine the %alues of %aria#les while in the de#ugger. The first is to sim"l$ mo%e $our mouse o%er a %aria#le and lea%e it there. A mouse hint a""ears telling $ou the name and %alue of the %aria#le. Also) note that there is a &atch ta# in the window at the #ottom left of the screen ;ust shown. 6. ,lic' the &atch ta#) and then clic' on the first line in the &atch window. You will #e a#le to enter a %aria#le name in the Name column. T$"e 7er ) and then "ress Enter. The &atch window will loo' li'e the following illustration. ?3f $ou don+t see a &atch ta#) $ou can summon the &atch window %ia the 0e#ug menu. Select 0e#ug) then &indows) and then &atch. Select the first &atch window in the menu.A
K. An easier wa$ to see the %alue of a local %aria#le is to loo' at the .ocals window) #$ clic'ing in the .ocals ta#. This window shows all local %aria#les) as shown in the following illustration. ?3f $ou don+t see a .ocals ta#) $ou can summon the .ocals window through the 0e#ug menu as descri#ed in the "re%ious ste".A
D. Press F2 to single/ste" through the code. 3n this case) $ou should mo%e to the line with the actual di%ision. The screen should loo' li'e the following illustration.
C. 3f the *ut"ut window is not %isi#le) ma'e it %isi#le #$ selecting View) then *ther &indows) and then *ut"ut. The out"ut window will ha%e the assert failure shown) as the following illustration shows. ?You might need to scroll u" in the *ut"ut window to see the message.A
2 . Seeing that the %aria#le Pero is indeed e(ual to ) we could ;ust sto" de#ugging. &e could also change the %alue of the %aria#le Pero. <ighlight the line with Pero on it in the .ocals window) and then clic' in the Value column. &e can now edit the %alue. ,hange the %alue #$ t$"ing 4 and "ress Enter. The %alue changes to 2 and a""ears in red. ?7ed is the default) #ut in an$ e%ent) the %alue a""ears in a color defined as indicating the %alue has changed.A 22. Press F2 again to single/ste" to the ne1t statement. 3f a line calls a method that is com"iled for de#ugging and $ou ha%e access to the source) $ou can "ress F22 to ste" into the code. Press FQ to continue. The #rowser screen should a""ear) with the message 4@ot "ast the error.5 dis"la$ed. 22. ,lose the #rowser. 2!. 7ight/clic' on the line with the #rea'"oint) and select Brea'"oint Pro"erties. The form shown in the following illustration will a""ear.
28. ,lic' the ,ondition #utton. 3n the dialog #o1 that a""ears) lea%e ,ondition chec'ed) and enter 7er JL / in the te1t #o1. The dialog #o1 should loo' something li'e the following illustration. &hen it does) clic' *>.
2Q. ,lic' the <it ,ount #utton. ,hange the %alue of the dro"/down list la#eled hen the breakpoint is hit to #rea' when the hit count is e(ual to. A te1t #o1 should a""ear. .ea%e it set to 2. &hen the dialog #o1 is set as shown in the following illustration) clic' *>. ,lic' *> again to close the Brea'"oint Pro"erties dialog #o1. 26. 7un the a""lication. 3t will run without #rea'ing for the e1ce"tion) and dis"la$ a screen similar to the error screen $ou saw in the earlier 0i%B$Pero.as"1 e1am"le.
2K. ,hange the "ro"erties of the #rea'"oint as shown earlier) setting the condition to 7er P /. 7un the a""lication. This time) the #rea'"oint will #e reached with a condition that is true) and $ou will #e #rought to the de#ugger. 9se F2 to single/ste" through the code) and $ou will see e1actl$ how the e1ce"tion is thrown. Seeing how the code runs #$ single/ste""ing through it can often #e a huge hel". NOTE The techni(ue used to start de#ugging in this e1am"le ?selecting 0e#ug) then Start or FQA causes all "ro;ects in the solution to #e #uilt "rior to de#ugging. You can de#ug a single "ro;ect and s'i" the #uild of other "ro;ects in the solution #$ right/clic'ing the "ro;ect in Solution E1"lorer) highlighting 0e#ug) and then selecting Start New 3nstance or Ste" 3nto New 3nstance.
9sing ,ebug./ssert
As shown in the "re%ious e1am"les) $ou can add ,ebug./ssert messages to $our code to test certain conditions. The /ssert method is o%erloaded and su""orts the following forms=
%ebu).0sse"t2con!ition 0s Boolean3 %ebu).0sse"t2con!ition 0s Boolean, &essa)e 0s .t"in)3 %ebu).0sse"t2con!ition 0s Boolean, &essa)e 0s .t"in), < !etail7essa)e as .t"in)3
condition is an e1"ression that e%aluates to true or false. message is a string containing a #rief message to dis"la$ when condition returns false. detail9essage is a string containing a detailed message to dis"la$ when condition returns false.
To call the 0e#ug class without e1"licitl$ including the names"ace) $ou need to im"ort the S$stem.0iagnostics names"ace using the 3m"orts directi%e) as descri#ed in the "receding e1am"les.
To
Do this
information or "re"are for ,ebug attri#ute to the @ Page directi%e with a %alue of True or using the runtime adding the :compilation; section to the &e#.config file and setting de#ugger its debug attri#ute to True. 3n%o'e the runtime de#ugger 0e#ug a "age using the Visual Studio .NET de#ugger Ma'e a #rea'"oint conditional .ocate the file 0#g,.7.e1e and e1ecute it. Ensure that the "age is set to com"ile in de#ug mode) which is the default in Visual Studio .NET. Set #rea'"oints #$ clic'ing on the gra$ #ar on the left side of the code window. Set a #rea'"oint as descri#ed earlier in the cha"ter) and then right/ clic' on the line and select Brea'"oint Pro"erties from the conte1t menu. Set a condition ?to #rea' onl$ when a condition is metA or a hit count ?to #rea' onl$ after some num#er of "asses through the line where the #rea'"oint isA. 3n &e#.,onfig) in the :compilation; tag) set debug to 1alse. 3n the Build menu) select ,onfiguration) change the configuration for the "ro;ect in%ol%ed to .elease) and then re#uild the a""lication.
Part V A""endi1es
A((endi0 A Migrating fr % ASP t ASP.NET
3n this cha"ter) $ou will learn how to=
7ecogniGe issues common to the migration "rocess. Migrate a "age that accesses data using A0*. 9se "rogramming "ractices with classic ASP that will ma'e migration easier.
Migrating classic ASP code to ASP.NET will #e a relati%el$ "ainless "rocess in man$ cases) "articularl$ if good "rogramming "ractices were followed in writing the code) such as se"arating the code into "rocedures where%er "ossi#le. Because of the changes to #oth the ASP.NET o#;ect model and the Microsoft Visual Basic language) which is used in ASP.NET in "lace of Visual Basic Scri"ting Edition) $ou will li'el$ ha%e to ma'e some changes to most ?if not allA of $our classic ASP "ages to ma'e them run in ASP.NET.
9trace:
The :trace; element allows $ou to ena#le or disa#le a""lication/wide tracing ?see ,ha"ter 28 for more information on this useful featureA) as well as set the "arameters for the tracing functionalit$. &hen tracing is ena#led) $ou can re%iew information a#out re(uests recei%ed #$
the &e# ser%er with the s"ecial 97. http://:ser%ername;/:appname;/trace.a$d. The :trace; element has the following s$nta1=
?t"ace enable!="t"ueV#alse" local9nl'="t"ueV#alse" *a)e9ut*ut="t"ueV#alse" "e@uestLi&it="inte)e"" t"ace7o!e=".o"tB'Ti&eV.o"tB'-ate)o"'" BA
Ta#le B/2 descri#es the :trace; element attri#utes in more detail. $ttri2ute Enabled Descriptio" 0etermines whether a""lication/ le%el tracing is ena#led for the a""lication. 0etermines whether trace information is %iewa#le #$ com"uters other than the local &e# ser%er. 1ptio"s true= Turns on a""lication/le%el tracing. false= Turns off a""lication/le%el tracing. The default is false. true= Trace out"ut can #e %iewed onl$ from the local &e# ser%er. false= Trace out"ut is %iewa#le from an$ machine. The default is true.
local+nly
page+utput 0etermines whether trace out"ut is true= Trace out"ut is a""ended to each "age a""ended to each ASP.NET "age within the sco"e of the configuration file. in the a""lication or is a%aila#le false= Trace out"ut is a%aila#le onl$ #$ #rowsing onl$ through trace.a1d. the s"ecial trace.a1d 97.. The default is false. re4uest<imit 0etermines the num#er of re(uests The default is 2 ) #ut the higher this num#er) the that are stored for re%iew through more o%erhead is in%ol%ed in tracing. Set this the trace.a1d 97.. *nce this limit num#er as small as is feasi#le. has #een reached) the current trace must #e cleared #$ #rowsing trace.a1d to collect information on additional re(uests. trace9ode 0etermines the sort order of the re(uests stored. Sort2yTime= Sorts trace information #$ the order in which e%ents are "rocessed. Sort2y=ategory= Sorts trace information al"ha#eticall$ #$ categor$. &hen used with the Trace. rite method) Sort2y=ategory can #e useful for grou"ing Trace. rite statements using the same categor$ argument. The default is Sort2yTime.
93lo2alizatio":
The :globali3ation; element controls glo#aliGation settings for ASP.NET a""lications. This includes the encoding used for re(uests) res"onses) and files) as well as settings for s"ecif$ing the culture to #e associated with &e# re(uests and local searches. The :globali3ation; element has the following s$nta1=
?)lobaliDation cultu"e="an' ,ali! cultu"e st"in)" #ile nco!in)="an' ,ali! enco!in) st"in)" "e@uest nco!in)="an' ,ali! enco!in) st"in)" "es*onse nco!in)="an' ,ali! enco!in) st"in)" ui-ultu"e="an' ,ali! cultu"e st"in)" BA
Ta#le B/2 descri#es the :globali3ation; element attri#utes in more detail. Ta#le B3*. :globali3ation; Element /ttributes $ttri2ute culture Descriptio" 0etermines the culture ?such as language defaultsA used to "rocess incoming &e# re(uests. 0etermines the t$"e of character encoding used for "arsing ASP.NET a""lication files ?.as"1) .asm1) and .asa1A. 0etermines the t$"e of character encoding used to "rocess incoming &e# re(uests. 1ptio"s This attri#ute must #e set to a %alid culture string. For a list of %alid culture strings) see the Microsoft .NET Framewor' documentation entr$ for the System.-lobali3ation.=ulture"nfo class. This attri#ute must #e set to a %alid encoding string. 3f this attri#ute is not included in either Machine.config or &e#.config) encoding is #ased on the machine+s 7egional *"tions setting in ,ontrol Panel.
fileEncoding
re4uestEncoding
This attri#ute must #e set to a %alid encoding string. 3f this attri#ute is not included in either Machine.config or &e#.config) encoding is #ased on the machine+s 7egional *"tions setting in ,ontrol Panel. The default is utfCV. This attri#ute must #e set to a %alid encoding string. 3f this attri#ute is not included in either Machine.config or &e#.config) encoding is #ased on the machine+s 7egional *"tions setting in ,ontrol Panel. The default is utfCV.
responseEncoding 0etermines the t$"e of character encoding used to encode outgoing res"onses.
Ta#le B3*. :globali3ation; Element /ttributes $ttri2ute ui=ulture Descriptio" 0etermines the culture ?such as language defaultsA used to "rocess searches that are culture/ or locale/ s"ecific. 1ptio"s This attri#ute must #e set to a %alid culture string. For a list of %alid culture strings) see the .NET Framewor' documentation entr$ for the System.-lobali3ation.=ulture"nfo class.
9http0u"ti#e:
The :http.untime; element controls se%eral as"ects of the ASP.NET <TTP runtime engine. The :http.untime; element has the following s$nta1=
?+tt*6unti&e a**6e@uestNueueLi&it="nu&be" o# "e@uests" enable[e"nel9ut*ut-ac+e="t"ueV#alse" enableVe"sionHea!e"="st"in)" executionTi&eout="secon!s" &ax6e@uestLen)t+="Cb'tes" &inLocal6e@uestF"eeT+"ea!s="nu&be" o# t+"ea!s" &inF"eeT+"ea!s="nu&be" o# t+"ea!s" useFull'Nuali#ie!6e!i"ect="l="t"ueV#alse" BA
Full$ :ualified %s. 7elati%e 97.s There are two #asic t$"es of 97.s used for creating h$"erlin's in &e# "ages= full$ (ualified 97.s and relati%e 97.s. Full$ (ualified 97.s) also 'nown as a#solute 97.s) contain all of the information necessar$ for the #rowser ?or other client "rogramA to locate the resource named in the 97.. This includes the "rotocol moni'er #eing used ?ftp://) http://) https://) and so onA) the ser%er+s domain name or 3P address ?on local &indows networ's) the machine name can also #e usedA) and the "ath to the resource. A t$"ical full$ (ualified 97. would loo' li'e this= http://localhost/4uickstart/aspplus/default.asp$ 7elati%e 97.s "ro%ide onl$ the information necessar$ to locate a resource relati%e to the current document ?'nown as document relati%eA or current ser%er or domain ?'nown as root relati%eA. A document/relati%e 97. used to lin' to the "re%iousl$ referenced "age from another "age in the same %irtual director$ would loo' li'e this= default.asp$
A root/relati%e 97. would loo' li'e this= /4uickstart/aspplus/default.asp$ Because some controls or a""lications might not 'now how to use relati%e 97.s) at times $ou+ll need to use a full$ (ualified 97.. Ta#le B/! descri#es the :http.untime; element attri#utes in more detail. Ta#le B32. :http.untime; Element /ttributes $ttri2ute app.e4uest#ueue<imit Descriptio" S"ecifies the num#er of re(uests that ASP.NET will (ueue when no threads are a%aila#le to "rocess them) #efore returning a 4Q !TSer%er Too Bus$5 error message. 1ptio"s 3ncreasing this %alue can result in unacce"ta#l$ long wait times for users) so use caution and test carefull$ when ma'ing ad;ustments to this %alue. The default is 2 .
enableLernel+utput=ache
S"ecifies whether the htt".s$s cache is >ernel out"ut caching can ena#led for 33S 6. and higher. New significantl$ im"ro%e for %ersion >.>. "erformance. The default is true. S"ecifies whether the -/As"Net/ Version header is out"ut with each re(uest. New for %ersion >.>. The default is true.
enableDersionKeader
e$ecutionTimeout
0etermines amount of time) in This attri#ute) which is seconds) that an ASP.NET re(uest can similar to classic ASP+s continue e1ecuting #efore #eing shut Ser%er. ScriptTimeout down. "ro"ert$) can #e used to "re%ent hung or long/ running re(uests from consuming more resources than necessar$. This attri#ute should #e set somewhere higher than the a%erage time it ta'es to "rocess re(uests) #ut not so high as to allow "rocessor o%erutiliGation #$ errant or inefficient "ages. The default is C seconds. 0etermines ma1imum siGe of This attri#ute is designed
ma$.e4uest<ength
Ta#le B32. :http.untime; Element /ttributes $ttri2ute Descriptio" incoming file u"loads) in 'ilo#$tes. 1ptio"s to hel" "re%ent denial of ser%ice attac's mounted #$ u"loading large files to a ser%er. Set it to the smallest siGe feasi#le for files $ou e1"ect $our users to u"load. The default is 8) C6 '#$tes. The default is D.
min1reeThreads
,onfigures the minimum num#er of threads ASP.NET will 'ee" free for "rocessing new re(uests.
min<ocal.e4uest1reeThreads ,onfigures the minimum The default is 8. 1reeThreads num#er of threads ASP.NET will 'ee" free for "rocessing re(uests coming from the local machine. Maintaining these free threads can hel" "re%ent deadloc's in multithreaded "rocessing. Note that this is incorrectl$ identified in the current .NET Framewor' documentation as min1reeC <ocal.e4uest1reeThreads. use1ully#ualified.edirect!.< 0etermines whether relati%e or full$ (ualified 97.s are used for client/ side redirects. This attri#ute allows de%elo"ers to su""ort certain mo#ile controls that re(uire full$ (ualified 97.s for client/side redirects. true= ,lient/side redirects are full$ (ualified. false= ,lient/side redirects are relati%e. The default is true.
9co#pilatio":
&ith 2 attri#utes and two child elements) the :compilation; element is one of the more e1tensi%e ASP.NET configuration elements and contains settings that determine how ASP.NET com"iles code in $our &e# a""lications and &e# Ser%ices. The settings $ou+ll see most fre(uentl$ are the debug and default<anguage attri#utes) which are "laced in $our a""lication+s &e#.config file #$ default when $ou+re using Microsoft Visual Studio .NET. *ther settings) such as the :assemblies; and :namespaces; child elements) are e(uall$ im"ortant #ut usuall$ are inherited from the settings in Machine.config) unless o%erridden #$ a de%elo"er. The :compilation; element has the following s$nta1=
?co&*ilation batc+="t"ueV#alse" batc+Ti&eout="secon!s" !ebu)="t"ueV#alse" !e#aultLan)ua)e="lan)ua)e" ex*licit="t"ueV#alse" &axBatc+.iDe="nu&be" o# *a)es" &axBatc+;ene"ate!File.iDe="Cb'tes" nu&6eco&*ilesBe#o"e0**6esta"t="nu&be"" st"ict="t"ueV#alse" te&*!i"ecto"'="!i"ecto"'" A ?co&*ile"sA ?co&*ile" extension="#ile extension" lan)ua)e="lan)ua)e" co&*ile"9*tions="co&*ile" o*tions" t'*e=".N T t'*e" 1a"nin)Le,el="nu&be"" BA ?Bco&*ile"sA
?asse&bliesA ?a!! asse&bl'="asse&bl' na&e" BA ?"e&o,e asse&bl'="asse&bl' na&e" BA ?clea" BA ?Basse&bliesA ?Bco&*ilationA
Ta#le B38. :compilation; Element /ttributes Ele#e"t :compilation; $ttri2ute Descriptio" 0etermines com"iler o"tions for the a""lication. Su""orts the :compilers; and :assemblies; child elements. 2atch 0etermines whether the a""lication su""orts #atch com"ilation of ASP.NET "ages. &hen #atch com"ilation is ena#led) ASP.NET will attem"t to com"ile all ASP.NET "ages within the a""lication director$ on the first re(uest. This "re%ents later "age re(uests from ha%ing to #e com"iled on re(uest. true= Batch com"ilation is su""orted. false= Pages will #e com"iled one #$ one as the$ are re(uested. The default is true. 1ptio"s
2atchTimeout
0etermines the amount of This setting will %ar$ time) in seconds) #efore de"ending on the siGe of an timeout of #atch com"ilation. a""lication and the amount of 3f the timeout is e1ceeded) the time $ou are willing to allow com"iler will switch to "er/ for #atch com"ilation. re(uest com"ilation mode. The default is 2Q seconds. 0etermines whether de#ug true= Assem#lies are information is included in com"iled with de#ug info. com"iled assem#lies for false= Assem#lies are ASP.NET "ages and &e# com"iled without de#ug info. Ser%ices. This attri#ute should The default is false. alwa$s #e set to false in a "roduction a""lication #ecause de#ug assem#lies are larger and don+t "erform as well as release/t$"e assem#lies. 0etermines the language?sA to This attri#ute is the name of a #e used during d$namic language) as s"ecified #$ one com"ilation. of the :compiler; child elements. The default is %b. 0etermines whether ASP.NET com"iles "ages true= Ena#led. false= 0isa#led.
,ebug
,efault<anguage
E$plicit
Ta#le B38. :compilation; Element /ttributes Ele#e"t $ttri2ute Descriptio" 1ptio"s written in Microsoft Visual The default is true. Basic .NET using the Visual Basic *"tion E1"licit com"iler o"tion ?which forces e1"licit declaration of %aria#lesA. Ena#ling this setting ma'es it easier to locate and fi1 common "ro#lems) such as miss"elled %aria#le names) that otherwise wouldn+t #e disco%ered until runtime. ma$2atchSi3e 0etermines the ma1imum num#er of "ages for #atch com"ilation. The default is 2) .
ma$2atchC -enerated1ileSi3e
0etermines the ma1imum The default is !) com#ined siGe) in >B) of the generated source files in #atch com"ilation. 0etermines how man$ times The default is 2Q. a""lication resources can #e d$namicall$ recom"iled #efore the a""lication is automaticall$ restarted. This setting can #e configured at #oth the a""lication le%el and the glo#al le%el through Machine.config.
num.ecompilesC 2efore/pp.estart
strict
0etermines whether true= Ena#led. ASP.NET com"iles "ages false= 0isa#led. 3t+s a good written in Visual Basic .NET "ractice to turn this on) using the Visual Basic *"tion through either Strict com"iler o"tion ?which Machine.config or "re%ents t$"e con%ersions that &e#.config) through the would result in data loss) late Visual Studio .NET #inding) and other error/"rone "ro"erties dialog #o1 for the coding ha#itsA to $our .as"1 "ro;ect ?choose Build under files #efore com"ilation. ,ommon Pro"ertiesA) or #$ adding *"tion Strict to the "age or module $ou+re wor'ing on. This ma'es it
Ta#le B38. :compilation; Element /ttributes Ele#e"t $ttri2ute Descriptio" 1ptio"s easier to fi1 common "ro#lems) such as o%erflows or rounding errors) that otherwise wouldn+t #e disco%ered until runtime. The default is false. temp,irectory 0etermines the director$ in An$ %alid director$. which the tem"orar$ ASP.NET files resulting from d$namic com"ilation will reside. ,hild element containing indi%idual :compiler; child elements. 0etermines o"tions for s"ecific language com"ilers. *ne or more of these child elements can #e contained within the :compilers; element. e$tension 0etermines the file e1tension used #$ d$namicall$ com"iled code/#ehind modules for a s"ecific com"iler. The e1tensions for the three most commonl$ used ASP.NET languages ?Visual Basic .NET) Microsoft ,J) and Microsoft FScri"t .NETA are included in Machine.config) so $ou don+t need to set them $ourself unless $ou want to add additional e1tensions for one of these languages. String re"resenting the file e1tension ?.%#) .cs) and so onA. 9se semicolons to delimit multi"le e1tensions. This setting should match the language s"ecified in the language attri#ute. This attri#ute is re(uired.
:compilers;
:compiler;
language
0etermines the list of String re"resenting the language names to #e handled language name #$ a s"ecific com"iler. The ?%#I%isual#asicI %#scri"tA. names for the three most 9se semicolons to delimit commonl$ used ASP.NET multi"le names. This setting
Ta#le B38. :compilation; Element /ttributes Ele#e"t $ttri2ute Descriptio" 1ptio"s languages ?Visual Basic.NET) should match the language ,J) and FScri"t .NETA are s"ecified in the e1tension included in Machine.config) attri#ute. This attri#ute is so $ou don+t need to set them re(uired. $ourself unless $ou want to add additional names for one of these languages. compiler+ptions 0etermines an$ com"iler/ ,onsult the .NET Framewor' s"ecific o"tions to #e "assed S0> documentation to along during com"ilation. determine a%aila#le o"tions. 0etermines which .NET class This attri#ute is a comma/ or assem#l$ is used to delimited list that can include com"ile resources using the the class name) assem#l$ language s"ecified in the name) and %ersion language attri#ute) or with the information. The e1tension in the e1tension Machine.config file contains attri#ute. The t$"es for the good e1am"les of the s$nta1 three most commonl$ used for this attri#ute. This ASP.NET languages ?Visual attri#ute is re(uired. Basic .NET) ,J) and FScri"t .NETA are included in Machine.config) so $ou don+t need to set them $ourself unless $ou want to modif$ the t$"e for one of these languages ?not recommendedA. 0etermines the com"iler warning le%els) which determine the t$"es of warning messages ?and the se%erit$A that are emitted #$ the com"iler. The %alue for this attri#ute de"ends on the language com"iler #eing configured. The default for ,J is 2.
Type
warning<e%el
:assemblies;
,hild element containing one The child elements of the or more of the :add/;) :assemblies; element are :remo%e/;) or :clear/; child used to add references to elements. assem#lies to #e used during com"ilation. ASP.NET automaticall$ lin's in the assem#lies s"ecified here during d$namic com"ilation.
Ta#le B38. :compilation; Element /ttributes Ele#e"t $ttri2ute :clear; Descriptio" 1ptio"s S"ecifies that all current or inherited assem#l$ references should #e remo%ed. S"ecifies an assem#l$) #$ its assem#l$ name) to #e referenced during d$namic com"ilation. This setting should #e the assem#l$ name) not the 0.. name) of the desired assem#l$. You can also use the wildcard V to add all assem#lies from the a""lication+s "ri%ate assem#l$ cache ?#$ default) in the #in su#director$A. The assem#l$ name used must match e1actl$ the name of an assem#l$ added #$ a "re%ious add directi%e ?for e1am"le) from a "arent &e#.configA. You cannot use wildcards for this attri#ute.
:add;
assembly
:remo%e;
assembly
S"ecifies an assem#l$) #$ its assem#l$ name) to #e remo%ed from use during d$namic com"ilation.
9pa3es:
The :pages; element allows $ou to set the defaults for the "age/le%el attri#utes that are more commonl$ associated with the attri#utes of the @ Page ASP.NET directi%e. The settings in this element a""l$ to all "ages for which s"ecific attri#utes of the @ Page directi%e do not a""ear. 3f these attri#utes do a""ear in an ASP.NET "age) their settings will o%erride those in either the Machine.config or &e#.config configuration files. As such) the :pages; element "ro%ides a hand$ wa$ of configuring the SessionState) DiewState) and other settings at an a""lication or su#folder le%el) gi%ing $ou a great deal of control o%er $our a""lication. The :pages; element has the following s$nta1=
?*a)es auto ,ent4i"eu*="t"ueV#alse" bu##e"="t"ueV#alse" enable.ession.tate="t"ueV#alseV6ea!9nl'" enableVie1.tate="t"ueV#alse" enableVie1.tate7ac="t"ueV#alse"
Ta#le B/Q descri#es the :pages; element attri#utes in more detail. Ta#le B3>. :pages; Element /ttributes $ttri2ute autoE%ent ireup Descriptio" 1ptio"s 0etermines whether su""ort for "age true= E%ent su""ort is "ro%ided e%ents ?Page0<oad and so onA is automaticall$. automaticall$ "ro%ided in an false= E%ent su""ort is not "ro%ided. a""lication+s ASP.NET "ages. E%ent handlers must #e manuall$ wired #$ de%elo"ers. The default is true. Pages created in Visual Studio .NET will ha%e autoE%ent ireup set to false #$ default. 0etermines whether res"onses are #uffered #efore #eing sent to the client. This setting is analogous to the classic ASP .esponse.2uffer "ro"ert$. true= Buffering is ena#led. Page out"ut will #e #uffered until the "age is com"letel$ "rocessed) or until either the End or 1lush method of the KTTP.esponse class is called. false= Buffering is not ena#led. Buffering is to the client as it is rendered. The default is true. You can use this attri#ute to "ro%ide a class deri%ed from the Page class if $ou want to "ro%ide additional functionalit$ not included in the #ase Page class. This is a sim"le $et "owerful wa$ to e1tend ASP.NET a""lications.
2uffer
Page2aseType
Pro%ides the t$"e or assem#l$ name of a class from which ASP.NET "ages should inherit. 3n the a#sence of this attri#ute) the default is to inherit from the Page class of the System. eb.!" names"ace.
smartNa%igation
0etermines whether the The default is false. SmartNa%igation feature) which uses "1rame elements to minimiGe "age 4flash5 on "ost#ac's) is ena#led #$ default.
user=ontrol2aseType Pro%ides the t$"e or assem#l$ name of a class from which ASP.NET
Ta#le B3>. :pages; Element /ttributes $ttri2ute Descriptio" 9ser ,ontrols ?.asc1 filesA should inherit. 3n the a#sence of this attri#ute) the default is to inherit from the !ser=ontrol class of the System. eb.!" names"ace. enableSessionState 0etermines whether a new session is true= 3f the user does not ha%e a created #$ default for the current current session when he or she user #$ an ASP.NET "age. Note that re(uests a "age) a new session will #e if the user alread$ has a session from created. a "rior "age in which this attri#ute is false= 3f the user does not ha%e a set to false) this attri#ute will not current session) one will not #e affect that session. <owe%er) setting created. 3f the user does ha%e a the attri#ute to .ead+nly will session) it will not #e affected) #ut its "re%ent the "age from modif$ing %alues cannot #e accessed from "ages %alues set in "re%ious "ages. where this attri#ute is false. .ead+nly= 3f the user does not ha%e a current session) one will not #e created. 3f the user does ha%e a session) its %alues can #e read from within a "age where this attri#ute has #een set to .ead+nly) #ut the$ cannot #e modified. The default is true. 0etermines whether DiewState ?the method #$ which ASP.NET Ser%er ,ontrols store their state #etween "age re(uestsA is ena#led. true= DiewState is ena#led. Ser%er ,ontrols will maintain their %alues from one re(uest to the ne1t. false= DiewState is not ena#led. Ser%er control state will #e reset with each re(uest. true= MA, is ena#led for DiewState. false= MA, is not ena#led for DiewState. The default is true. 1ptio"s
enableDiewState
enableDiewState9ac 0etermines whether a Machine Authentication ,hec' ?MA,A is "erformed on DiewState data when a &e# Form is "osted #ac' to the ser%er. The MA, can hel" identif$ client/side tam"ering with the DiewState hidden field. %alidate.e4uest S"ecifies whether re(uest %alidation is ena#led for "ages affected #$ the configuration file. New for %ersion >.>.
Since the 7e(uest Validation feature can hel" "re%ent a %ariet$ of scri"t in;ection attac's) it is recommended that $ou lea%e this set to true ?the defaultA) unless $ou are certain that
Ta#le B3>. :pages; Element /ttributes $ttri2ute Descriptio" 1ptio"s $our a""lication "ro"erl$ filters and %alidates all user in"ut.
9custo#Errors:
The :customErrors; element allows $ou to customiGe how $our ASP.NET a""lication res"onds to error conditions. 3n this element) $ou can s"ecif$ whether the raw error messages generated #$ ASP.NET should #e %isi#le to local or remote clients) or whether to redirect the client to either a custom error "age or a "age s"ecific to the error that occurred ?#ased on the status code of the errorA. The :customErrors; element su""orts one child element) :error;) and has the following s$nta1=
?custo& ""o"s !e#ault6e!i"ect="u"l" &o!e="onVo##V6e&ote9nl'"A ?e""o" "e!i"ect="u"l" status-o!e="status co!e"BA ?Bcusto& ""o"sA
Ta#le B/6 descri#es the :customErrors; element attri#utes in more detail. Ta#le B3?. :customErrors; Element /ttributes Ele#e"t :customErrors; $ttri2ute Descriptio" 0etermines how ASP.NET errors are handled. default.edirect 0etermines the "age to which a user is redirected if an error occurs. mode 0etermines whether raw ASP.NET error messages are sent to the client. The "age to which this 97. "oints can #e either an .as"1 "age) in which $ou attem"t to clean u" or reco%er from the error) or a static <TM. "age) to inform the user of the error and offer guidance. +n= ,ustom errors are ena#led. &hen an error occurs) the client) whether on the local &e# ser%er or remote) will #e redirected to the custom error "age 1ptio"s
Ta#le B3?. :customErrors; Element /ttributes Ele#e"t $ttri2ute Descriptio" 1ptio"s s"ecified #$ the default.edirect attri#ute ?or to a "age s"ecified in an :error; child elementA. +ff= ,ustom errors are not ena#led. &hen an error occurs) the client will see the error "age generated #$ ASP.NET. Note that de"ending on how $our a""lication is designed) this can e1"ose "ro"rietar$ information to clients) so $ou should rarel$ use this setting. .emote+nly= ,ustom errors are ena#led for remote clients. &hen an error occurs) remote clients will #e redirected to a custom error "age) while clients on the local &e# ser%er will see the error "age generated #$ ASP.NET. This allows de%elo"ers to trac' down errors without allowing clients to see raw error "ages. .emote+nly is the default. :error; 0etermines redirect Adding :error; tags "ro%ides finer/ "age for a s"ecific grained control o%er error handling. error t$"e) #ased on the <TTP status code for the error. redirect 0etermines the "age to which a user is redirected if an error of the t$"e s"ecified in the status=ode attri#ute occurs. 0etermines the <TTP status code ?8 8TNot Found) and so onA that is handled #$ this :error; child element.
status=ode
9authe"ticatio":
The :authentication; element controls configuration of authentication in ASP.NET. You can choose from one of three authentication methods) and $ou can set a""ro"riate "arameters for the method $ou choose or $ou can choose no authentication at all. The :authentication; element su""orts two child elements= :forms; and :passport;. Additionall$) the :forms; element su""orts one child element) :credentials;) which in turn su""orts one child element) :user;) as shown in the following e1am"le=
?aut+entication &o!e="4in!o1sVFo"&sV/ass*o"tVNone"A ?#o"&s lo)in="l="u"l" na&e="na&e" *at+="B" *"otection="0llVNoneV nc"'*tionVVali!ation"
"e@ui"e..L="t"ueV#alse"
sli!in) x*i"ation="t"ueV#alse" ti&eout="nu&be""A ?c"e!entials *ass1o"!Fo"&at="-lea"V7%8V.H01"A ?use" na&e="use"na&e" *ass1o"!="*ass1o"!" BA ?Bc"e!entialsA ?B#o"&sA ?*ass*o"t "e!i"ect="l="u"l" BA ?Baut+enticationA
Ta#le B3B. :authentication; Element /ttributes Ele#e"t :authentication; mode $ttri2ute Descriptio" 0etermines how ASP.NET authentication is handled. 0etermines the authentication mode to #e used. Authentication is discussed in greater detail in ,ha"ter 6. indows= ASP.NET will use &indows authentication #$ default. &or's with 33S+s Basic) 0igest) NT.M) or ,ertificate/ #ased authentication methods. 1orms= ASP.NET will use Forms/#ased authentication) which "ro%ides #asic su""ort for 4roll/$our/own5 securit$ scenarios) #$ default. Passport= ASP.NET will use Microsoft Pass"ort as the default authentication method. None= No authentication will #e "erformed #$ ASP.NET. 1ptio"s
:forms;
0etermines the "arameters associated with Forms/#ased authentication. login!rl 0etermines the 97. to which a user is redirected if he doesn+t ha%e a %alid authentication coo'ie. 0etermines the name of the coo'ie used for authenticating a user. This can #e an$ "age in $our ASP.NET a""lication that allows a user to log in. The default is login.as"1. 0efault is .ASP-A9T<.
name
path
0etermines the "ath to set for 0efault is E. This is to "re%ent the authentication coo'ie. the "ossi#ilit$ of missing coo'ies #ecause of #rowser case sensiti%it$ with res"ect to 97. "aths and coo'ies. 0etermines the methods used /ll ?defaultA= Both encr$"tion to "rotect the authentication and data %alidation will #e coo'ie from #eing used to "rotect the coo'ie. com"romised. Your choice of This is the recommended which method to use) or setting. whether to use an$ at all) will Encryption= The
protection
Ta#le B3B. :authentication; Element /ttributes Ele#e"t $ttri2ute Descriptio" de"end on $our securit$ needs %s. the amount of resources $ou+re willing to de%ote to securit$. @enerall$) the higher the le%el of securit$) the greater the "erformance o%erhead. 1ptio"s authentication coo'ie will #e encr$"ted) #ut will not #e %alidated. This lea%es the coo'ie %ulnera#le to certain t$"es of attac's. Dalidation= The authentication coo'ie+s contents will #e %alidated to ensure that the$ ha%en+t #een changed #etween the #rowser and the ser%er. None= Neither encr$"tion nor %alidation is used. Not recommended. 3f set to true) the forms authentication coo'ie will not #e sent o%er a non/SS. connection. The default is false. The default is false.
re4uireSS<
0etermines whether the authentication coo'ie will #e sent with re(uests that do not use SS.. New for %ersion 2.2.
slidingE$piration 0etermines whether each re(uest in a gi%en session resets the e1"iration of the authentication coo'ie. New for %ersion 2.2. Timeout 0etermines the amount of time) in minutes) until the authentication coo'ie e1"ires.
0efault is ! . You should set this %alue to the minimum amount that will allow users to use $our site effecti%el$. 3f $ou use "ersistent coo'ies with forms authentication) the$ will not time out.
:credentials;
3n con;unction with the 3f $ou use this method to :user; child element) allows store credentials in a $ou to define credentials to &e#.config file within $our authenticate against within a a""lication sco"e) and $our configuration file. a""lication is com"romised) it might #e "ossi#le for intruders to gain the "asswords stored there) e%en if the$+re encr$"ted. 7emem#er that no encr$"tion
Ta#le B3B. :authentication; Element /ttributes Ele#e"t $ttri2ute Descriptio" 1ptio"s method is "erfect. Password1ormat 0etermines the encr$"tion used for stored "asswords. =lear= No encr$"tion is used. Not recommended. 9,)= Passwords are encr$"ted using the M0Q hash algorithm. SK/>= Passwords are encr$"ted using the S<A2 hash algorithm.
:user;
0etermines the username and "assword of a single user. 9se one :user; child element for each set of credentials $ou want to store in the configuration file. name password S"ecifies the username of the user to authenticate against. S"ecifies the "assword of the This %alue should #e an user to authenticate against. encr$"ted %ersion of the "assword created with the hash algorithm s"ecified #$ the password1ormat attri#ute of the :credentials; tag. ,hild element used to set the "arameters for Microsoft Pass"ortT#ased authentication. redirect!rl 0etermines the 97. where the user will #e redirected if he or she has not #een authenticated.
:passport;
9ide"tity:
B$ default) re(uests made #$ ASP.NET a""lications for resources re(uiring authentication) such as files secured #$ NT Access ,ontrols .ists ?A,.sA) are made in the conte1t of either the 39S7OMA,<3NENAME or 3&AMOMA,<3NENAME accounts) de"ending on whether the a""lication is configured to run in/"rocess or out/of/"rocess relati%e to 33S. The :identity; element allows ASP.NET a""lications to use im"ersonation) in which an a""lication ta'es on the
securit$ conte1t of the user ma'ing a re(uest) or of a s"ecified account. The :identity; element has the following s$nta1=
?i!entit' i&*e"sonate="t"ueV#alse" use"Na&e="use"na&e" *ass1o"!="*ass1o"!" BA
Ta#le B/D descri#es the :identity; element attri#utes in more detail. Ta#le B3G. :identity; Element /ttributes $ttri2ute Descriptio" 1ptio"s impersonate 0etermines whether true= Ena#les im"ersonation of securit$ accounts #$ ASP.NET a""lications ASP.NET a""lications. will use im"ersonation. false= 0isa#les im"ersonation of securit$ accounts #$ ASP.NET a""lications. userName S"ecifies a user account that the affected ASP.NET a""lication will im"ersonate. An$ %alid user account. You should ensure that the account that $ou choose has access to onl$ the desired resources. For e1am"le) as a rule) it is not a good idea to ha%e an ASP.NET a""lication im"ersonate an account in the Administrators grou". 3f omitted) ASP.NET will im"ersonate the account of the logged on user ?as "ro%ided #$ 33SA.
password
S"ecifies the "assword for the account named in the userName attri#ute.
9authorizatio":
The :authori3ation; element lets $ou s"ecif$ which accounts or roles ?grou"sA are authoriGed to access resources within the sco"e of the configuration file. The :authori3ation; element su""orts two child elements) :allow; and :deny;) #oth of which ha%e three attri#utes. The :authori3ation; element has the following s$nta1=
?aut+o"iDationA ?allo1 use"s="use"list" "oles=""olelist" ,e"bs=",e"blist" BA
Ta#le B/C descri#es the :authori3ation; element attri#utes in more detail. Ta#le B3H. :authori3ation; Element /ttributes Ele#e"t :authori3ation; $ttri2ute Descriptio" 0etermines authoriGation settings for an a""lication or director$. ,ontains one or more :allow; or :deny; child elements. Allows access to resources #ased on user account) grou" mem#ershi") or <TTP re(uest method. users .ist of users ?NT user accountsA This attri#ute ta'es a comma/ granted access to the delimited list. Access to anon$mous resource?sA. users is allowed using the U wildcard) and access to e%er$one is allowed using the V wildcard. .ist of roles ?NT grou"sA granted access to the resource?sA. .ist of <TTP %er#s ?@ET) P*ST) etc.A granted access to the resource?sA. 0enies access to resources #ased on user account) grou" mem#ershi") or <TTP re(uest method. users .ist of users ?NT user accountsA This attri#ute ta'es a comma/ denied access to the resource?sA. delimited list. Access to anon$mous users is denied using the U wildcard) and access to e%er$one is denied using the V wildcard. This attri#ute ta'es a comma/ delimited list. This attri#ute ta'es a comma/ delimited list. Ver#s a%aila#le are @ET) <EA0) P*ST) and 0EB9@. 1ptio"s
:allow;
roles
%erbs
:deny;
Ta#le B3H. :authori3ation; Element /ttributes Ele#e"t $ttri2ute Descriptio" roles %erbs 1ptio"s .ist of roles ?NT grou"sA This attri#ute ta'es a comma/ denied access to the resource?sA. delimited list. .ist of <TTP %er#s ?@ET) This attri#ute ta'es a comma/ P*ST) etc.A denied access to the delimited list. Ver#s a%aila#le are resource?sA. @ET) <EA0) P*ST) and 0EB9@.
9#achi"e6ey:
The :machineLey; element allows $ou to s"ecif$ the 'e$s used for encr$"tion and decr$"tion of coo'ie data in Forms/#ased authentication. This element can #e used at the machine le%el through Machine.config) as well as at the site and a""lication le%els through &e#.config files) #ut it cannot #e used at the su#director$ le%el. The :machineLey; element has the following s$nta1=
?&ac+ine[e' !ec"'*tion[e'="0uto;ene"ateV,alueS,(solate0**sT " ,ali!ation="0uto;ene"ateV,alueS,(solate0**sT " ,ali!ation[e'="3% .V7%8V.H01" BA
Ta#le B/2 descri#es the :machineLey; element attri#utes in more detail. Ta#le B34/. :machineLey; Element /ttributes $ttri2ute Descriptio" 1ptio"s /uto-enerate ?defaultA= ASP.NET will generate a random 'e$ for decr$"tion. New for %ersion >.>. 3n %ersion 2.2) the "solate/pps modifier is added) which ensures that each a""lication will ha%e a uni(ue 'e$ generated) #ased on the a""lication 30. %alue= This re"resents a string of characters ?minimum 8 ) ma1imum 22DA to #e used as a decr$"tion 'e$. Note that 22D characters is the recommended length. For shorter/length 'e$s) $ou should ensure that the 'e$ is randoml$ generated. This setting is necessar$ in &e# farms to ensure that all ser%ers are using the same 'e$s) "ro%iding trans"arent user access while still ta'ing ad%antage of encr$"tion. A,ES= 0ata is encr$"ted using Tri"le/0ES ?!0ESA encr$"tion. decryptionLey 0etermines whether the decr$"tion 'e$ to #e used is autogenerated or s"ecifies a 'e$ %alue to #e used.
%alidation
Ta#le B34/. :machineLey; Element /ttributes $ttri2ute Descriptio" ASP.NET. 1ptio"s 9,)= 0ata is encr$"ted using the M0Q hash algorithm. SK/> ?defaultA= 0ata is encr$"ted using the S<A2 hash algorithm. /uto-enerate ?defaultA= ASP.NET will generate a random 'e$ for %alidation. New for %ersion >.>. 3n %ersion 2.2) the "solate/pps modifier is added) which ensures that each a""lication will ha%e a uni(ue 'e$ generated) #ased on the a""lication 30. %alue= This re"resents a string of characters ?minimum 8 ) ma1imum 22DA to #e used as a %alidation 'e$. Note that 22D characters is the recommended length. For shorter/length 'e$s) it is recommended to ensure that the 'e$ is randoml$ generated. This setting is necessar$ in &e# farms to ensure that all ser%ers are using the same 'e$s) "ro%iding trans"arent user access while still ta'ing ad%antage of encr$"tion.
%alidationLey 0etermines whether the %alidation 'e$ to #e used is autogenerated or s"ecifies a 'e$ %alue to #e used.
9security olicy:
The :securityPolicy; element allows $ou to s"ecif$ one of se%eral named securit$ "olicies) or a custom "olic$) for code/access securit$ #ased on the name and policy1ile attri#utes of its :trust<e%el; child element. The :trust; element) descri#ed in the ne1t section) s"ecifies which of the named "olicies is im"lemented for a gi%en site or a""lication. The :securityPolicy; element su""orts one child element) :trust<e%el;) with two attri#utes) and has the following s$nta1=
?secu"it'/olic'A ?t"ustLe,el na&e=",alue" *olic'File=",alue" BA ?Bsecu"it'/olic'A
Ta#le B/22 descri#es the :securityPolicy; element attri#utes in more detail. Ta#le B344. :securityPolicy; Element /ttributes Ele#e"t :securityPolicy; $ttri2ute Descriptio" 0etermines the a%aila#le named 1ptio"s
Ta#le B344. :securityPolicy; Element /ttributes Ele#e"t $ttri2ute Descriptio" securit$ "olicies for sites andEor a""lications. :trust<e%el; Each :trust<e%el; child element sets u" an a%aila#le named "olic$ #ased on its name and policy1ile attri#utes. name S"ecifies the name to use for the The name s"ecified #$ this "olic$. attri#ute is also used #$ the :trust; element to im"lement the named "olic$. 1ptio"s
policy1ile S"ecifies the file name of the file The file name s"ecified #$ this that contains the code/access attri#ute is relati%e to the location securit$ settings to #e used under of the Machine.config file. the named "olic$.
9trust:
The :trust; element is used to im"lement one of the named securit$ "olicies created #$ the :securityPolicy; element. This element can #e used at the machine le%el through Machine.config) as well as at the site and a""lication le%els through &e#.config files. <owe%er) it can+t #e used at the su#director$ le%el. The :trust; element has the following s$nta1=
?t"ust le,el="FullVHi)+VLo1VNoneVcusto& na&e" o"i)in="l="u"l" BA
Ta#le B/22 descri#es the :trust; element attri#utes in more detail. Ta#le B34*. :trust; Element /ttributes $ttri2ute Descriptio" le%el 1ptio"s 0etermines the a""lica#le 1ull= ,ode/access securit$ is #ased on the Full named trust le%el) #ased on a named "olic$ set u" #$ default in Machine.config. securit$ "olic$. Kigh= ,ode/access securit$ is #ased on the Kigh named "olic$ set u" #$ default in Machine.config. <ow= ,ode/access securit$ is #ased on the <ow named "olic$ set u" #$ default in Machine.config. None= ,ode/ access securit$ is #ased on the None named "olic$ set u" #$ default in Machine.config.
Ta#le B34*. :trust; Element /ttributes $ttri2ute Descriptio" 1ptio"s custom name= ,ode/access securit$ is #ased on a custom named "olic$ set u" in either Machine.config or a &e#.config file at the site or a""lication le%el. origin!rl S"ecifies the origin 97. for +ptional= This attri#ute can #e used to su""ort an a""lication. "ermissions for Socket and eb.e4uest re(uests that allow connecti%it$ to the origin host.
9sessio"State:
The :sessionState; element is used to configure the Session State Kttp9odule) including the t$"e of state management to #e used ?in/"rocess) out/of/"rocess) or Microsoft S:. Ser%erA) the default session timeout) and whether to use coo'ies for associating re(uests with user sessions. The :sessionState; element has the following s$nta1=
?session.tate state-onnection.t"in)="(/ a!!"essJ*o"t nu&be"" cooCieless="t"ueV#alse" &o!e="9##V(n*"ocV.tate.e",e"V.NL.e",e"" s@l-onnection.t"in)="s@l connection st"in)" ti&eout="nu&be" o# &inutes" BA
Ta#le B/2! descri#es the :sessionState; element attri#utes in more detail. Ta#le B342. :sessionState; Element /ttributes $ttri2ute Descriptio" 1ptio"s state=onnectionString S"ecifies the ser%er and This attri#ute is re(uired when the mode is set "ort num#er to connect to to StateSer%er. The default is when the mode attri#ute is tc"i"M22K. . .2=82828. set to StateSer%er. =ookieless 0etermines whether user sessions are ma""ed to re(uests #$ using coo'ies or #$ adding a user+s Session", to the 97. string for re(uests #$ that user. true= Session30s are added to re(uest 97.s) and coo'ies are not used. false= ,oo'ies are used to ma" user re(uests to sessions. The default is false.
Ta#le B342. :sessionState; Element /ttributes $ttri2ute 9ode Descriptio" 0etermines the t$"e of session state management that a""lications will use. 1ptio"s +ff= Session state is disa#led. "nproc= Session state is stored in/"rocess with the a""lication) as in classic ASP. StateSer%er= Session state is managed #$ an out/of/"rocess NT Ser%ice) allowing multi"le ser%ers in a &e# farm to share a single state store. S#<Ser%er= Session state is managed #$ S:. Ser%er data#ase) allowing multi"le ser%ers in a &e# farm to share a single state store. This mode has the added ad%antage of "ro%iding "ersistent state storage in the e%ent of a &e# ser%er crash. The default is "nProc.
s4l=onnectionString
S"ecifies the connection This attri#ute is re(uired when the mode is set string used to connect to a to S#<Ser%er. S:. Ser%er data#ase where state information is stored. S"ecifies the amount of .i'e the classic ASP Session.Timeout time) in minutes) #efore the "ro"ert$) this attri#ute uses sliding e1"iration. user+s session e1"ires. Each re(uest #$ the user resets the amount of time #efore his session e1"ires. The default is 2 minutes.
Timeout
9http5a"dlers:
The :httpKandlers; element allows $ou to assign re(uests of certain t$"es or for certain resources to s"ecific handler classes. For e1am"le) in Machine.config) the handling of ASP.NET "ages ?re(uests with the .as"1 e1tensionA is assigned to the System. eb.!".PageKandler1actory class. The :httpKandlers; element can also #e used to "re%ent <TTP access to certain t$"es of files #$ assigning them to the System. eb.Kttp1orbiddenKandler class) as is done #$ default for configuration files ?V.configA and source files ?V.%# and V.cs) for e1am"leA. The :httpKandlers; element su""orts three child elements) :add;) :remo%e;) and :clear;) and has the following s$nta1=
?+tt*Han!le"sA ?a!! *at+="*at+"
t'*e="t'*e, asse&bl' na&e" ,ali!ate="t"ueV#alse" ,e"b=",e"blist" BA ?"e&o,e *at+="*at+" ,e"b=",e"blist" BA ?clea" BA ?B+tt*Han!le"sA
Ta#le B/28 descri#es the :httpKandlers; element attri#utes in more detail. Ta#le B348. :httpKandlers; Element /ttribute Ele#e"t :httpKandlers; $ttri2ute Descriptio" 0etermines the assignment of re(uests to httpKandlers for ASP.NET a""lications. Each :add; child element ma"s a s"ecific t$"e of re(uest to a gi%en httpKandler. path S"ecifies the 97. "ath this httpKandler will handle. This can #e a single 97.) as in the case of the default ma""ing of the trace.a1d 97. to System. eb.Kandlers.TraceKandler) or can use a wildcard to s"ecif$ that the httpKandler should handle all re(uests of a gi%en t$"e ?such as V.as"1 or V.asm1A. true= The ASP.NET runtime will attem"t to load the class when the associated a""lication is started u". false= The ASP.NET runtime will load the class onl$ when the actual re(uest is recei%ed. This can im"ro%e start/u" time) #ut will dela$ the a""earance of the error if the class does not e1ist. This attri#ute is o"tional. 1ptio"s
:add;
%alidate
0etermines whether the ASP.NET runtime should attem"t to load the class #efore the actual re(uest is recei%ed) in order to ensure that it e1ists.
Ta#le B348. :httpKandlers; Element /ttribute Ele#e"t $ttri2ute Descriptio" type 1ptio"s S"ecifies the .NET This is a string containing a comma/ se"arated class that should list with the class name and other information) handle the re(uests such as %ersion and "u#lic 'e$) that ena#les s"ecified #$ the "ath ASP.NET to locate the class in either the and %er# attri#utes. a""lication+s #in director$ or the glo#al assem#l$ cache. S"ecifies the <TTP ,omma/se"arated list of %er#s ?@ET) P*STA or %er#s for which the a wildcard ?such as V) which s"ecifies that all httpKandler will %er#s should #e handledA. handle re(uests. 7emo%es an httpKandler ma""ing) #ased on the "ath and %er# attri#utes s"ecified. path S"ecifies "ath of the This attri#ute must e1actl$ match the "ath httpKandler to #e attri#ute of an httpKandler added #$ a "re%ious remo%ed. :add; child element. S"ecifies %er#?sA of This attri#ute must e1actl$ match the %er# the httpKandler to attri#ute of an httpKandler added #$ a "re%ious #e remo%ed. :add; child element. 7emo%es all httpKandler ma""ings) either those configured #$ the current file or those inherited from "arent configuration files.
%erb
:remo%e;
%erb
:clear;
9httpModules:
Kttp9odules are classes that im"lement the "Kttp9odule interface and are used to "ro%ide functionalit$ to ASP.NET a""lications. For e1am"le) #$ default) the Machine.config file adds Kttp9odules for out"ut caching) session/state management) authentication) and authoriGation. The :http9odules; element allows $ou to add Kttp9odules to ASP.NET a""lications. The :http9odules; element su""orts three child elements) :add;) :remo%e;) and :clear;) and has the following s$nta1=
Ta#le B/2Q descri#es the :http9odules; element attri#utes in more detail. Ta#le B34>. :http9odules; Element /ttributes Ele#e"t :http9odules; $ttri2ute Descriptio" 0etermines the http9odules a%aila#le for ASP.NET a""lications within the sco"e of the configuration file. Each :add; child element adds a s"ecified http9odule. name S"ecifies a name that can #e used #$ ASP.NET a""lications to refer to the module identified #$ the t$"e attri#ute. S"ecifies the .NET class This is a string containing a comma/ that im"lements the desired se"arated list with the class name and http9odule. other information) such as %ersion and "u#lic 'e$) that ena#les ASP.NET to locate the class in either the a""lication+s #in director$ or the glo#al assem#l$ cache. 7emo%es an http9odule) #ased on the name and t$"e attri#utes s"ecified. name S"ecifies the name of the http9odule to remo%e. This attri#ute must e1actl$ match the name attri#ute of an http9odule added #$ 1ptio"s
:add;
type
:remo%e;
Ta#le B34>. :http9odules; Element /ttributes Ele#e"t :clear; $ttri2ute Descriptio" 7emo%es all http9odules) either those configured #$ the current file or those inherited from "arent configuration files. 1ptio"s a "re%ious :add; child element.
9processModel:
The :process9odel; element configures settings related to how ASP.NET a""lications run) and it "ro%ides access to a num#er of features geared towards im"ro%ing the a%aila#ilit$ of a""lications. These include automatic restart ?which can #e configured #ased on ela"sed time or num#er of re(uestsA) allowed memor$ siGe) and &e# garden) in which a""lications can #e associated with s"ecific "rocessors in a multi"rocessor machine. Note that when ASP.NET is running under 33S 6. in nati%e mode) the settings in the :process9odel; element are ignored in fa%or of the settings configured #$ the 33S administrati%e 93. The :process9odel; element has the following s$nta1=
?*"ocess7o!el client-onnecte!-+ecC="ti&e in ++J&&Jss #o"&at" co&0ut+enticationLe,el="%e#aultVNoneV-onnectV-allV/CtV /Ct(nte)"it'V/Ct/"i,ac'" co&(&*e"sonationLe,el="%e#aultV0non'&ousV(!enti#'V(&*e"sonateV %ele)ate" c*u7asC="nu&be"" enable="t"ueV#alse" i!leTi&eout="ti&e" lo)Le,el="0llVNoneV ""o"s" &ax(oT+"ea!s="nu&be"" &ax4o"Ce"T+"ea!s="nu&be"" &e&o"'Li&it="*e"cent" *in)F"e@uenc'="++J&&Jss" *in)Ti&eout="++J&&Jss"
"e@uestLi&it="nu&be"" "e@uestNueueLi&it="(n#initeVnu&be"" "es*onse%ea!locC(nte",al="(n#initeV++J&&Jss" "es*onse6esta"t%ea!locC(nte",al="(n#initeV++J&&Jss" "esta"tNueueLi&it="(n#initeVnu&be"" se",e" ""o"7essa)eFile="#ilena&e" s+ut!o1nTi&eout="ti&e" ti&eout="ti&e" 1eb;a"!en="t"ueV#alse" use"na&e="use" na&e" *ass1o"!="*ass1o"!" BA
Ta#le B/26 descri#es the :process9odel; element attri#utes in more detail. Ta#le B34?. :process9odel; Element /ttributes $ttri2ute client=onnected=heck Descriptio" 1ptio"s 0etermines the fre(uenc$ with which This attri#ute ta'es a time ASP.NET chec's if the client is still %alue in the format hh=mm=ss. connected while a re(uest is (ueued. The default is = = Q. This attri#ute can #e useful for "re%enting "rocessor resources from #eing wasted on (ueued re(uests for which the client has disconnected. S"ecifies the 0,*M authentication le%el. ,efault= 0,*M will determine authentication le%el #ased on its normal securit$ negotiation algorithm. None= No authentication. =onnect=all= 0,*M authenticates the credentials of the client with each remote "rocedure call. Pkt= 0,*M authenticates that all recei%ed data is coming from the e1"ected client. Pkt"ntegrity= Same as Pkt) #ut also %erifies that data has not
com/uthentication<e%el
Ta#le B34?. :process9odel; Element /ttributes $ttri2ute Descriptio" 1ptio"s #een modified in trans"ort. PktPri%acy= Same as Pkt"ntegrity) #ut adds encr$"tion. The default %alue is =onnect. com"mpersonation<e%el S"ecifies the ,*M authentication le%el. /nonymous= ,lient is anon$mous. Not su""orted in the current release. "dentify= Ser%er can o#tain the client+s identit$ and im"ersonate the client for A,. chec'ing) #ut cannot access s$stem o#;ects using the client+s identit$. "mpersonate= Allows the ser%er to im"ersonate the client and access s$stem resources using the client+s securit$ conte1t) #ut this conte1t can onl$ #e "assed across a single machine #oundar$. ,elegate= Same as "mpersonate) #ut the im"ersonation to'en can #e "assed across multi"le machine #oundaries.
cpu9ask
S"ecifies the "rocessors ?on a The default is 1ffffffff. multi"rocessor ser%erA that are allowed to run the ASP.NET a""lication. This attri#ute wor's with the web-arden attri#ute. &hen web-arden is set to true) cpu9ask determines the eligi#le "rocessors for the a""lication. Ena#les or disa#les the process9odel true= process9odel settings settings for ASP.NET a""lications. are ena#led. false= process9odel settings are disa#led. 0etermines the amount of time) in 0efault is "nfinite) in which minutes) #efore ASP.NET shuts down case the "rocess will not #e an inacti%e wor'er "rocess. shut down when idle.
Enable
idleTimeout
Ta#le B34?. :process9odel; Element /ttributes $ttri2ute log<e%el Descriptio" S"ecifies the t$"es of "rocess e%ents that will #e written to the e%ent log. 1ptio"s /ll= All "rocess e%ents are logged. Errors= *nl$ une1"ected shutdowns) memor$ limit shutdowns) and deadloc' shutdowns are logged. None= No e%ents are logged. The default is Errors.
S"ecifies the ma1imum num#er of 3* An$ %alue from Q to 2 is threads "er ,P9. %alid. The default is 2Q. S"ecifies the ma1imum num#er of wor'er threads "er ,P9. 0etermines the ma1imum allowa#le memor$ siGe for an ASP.NET a""lication. An$ %alue from Q to 2 is %alid. The default is 2Q. This attri#ute ta'es a num#er re"resenting the "ercentage of the total s$stem memor$ that the a""lication+s wor'er "rocesses can consume. 3f this %alue is e1ceeded) ASP.NET will launch a new "rocess) reassign e1isting re(uests to it) and then shut down the old "rocess.
ping1re4uency
0etermines how often the ASP.NET The format of this %alue is 3SAP3 e1tension "ings the wor'er hh=mm=ss. The default is ! "rocess to see if it is running. 3f the seconds. "rocess does not res"ond in the inter%al s"ecified #$ pingTimeout) the wor'er "rocess will #e restarted. 0etermines the time inter%al after The format of this %alue is which an unres"onsi%e wor'er "rocess hh=mm=ss. The default is Q is restarted. seconds.
pingTimeout
response,eadlock"nter%al 0etermines the time inter%al "nter%al The format of this %alue is after which the "rocess will #e hh=mm=ss. The default is ! restarted when there are (ueued minutes. re(uests) and no res"onses ha%e #een generated for this inter%al. response.estartC ,eadlock"nter%al 0etermines the time inter%al that must The format of this %alue is ela"se #efore a second restart to cure a hh=mm=ss. The default is C deadloc' ?as s"ecified #$ minutes.
Ta#le B34?. :process9odel; Element /ttributes $ttri2ute re4uest<imit Descriptio" response,eadlock"nter%alA can occur. 0etermines the num#er of re(uests an a""lication can fulfill #efore ASP.NET launches a new wor'er "rocess and shuts down the old one. 0efault is "nfinite) in which case the "rocess will not #e shut down) regardless of the num#er of re(uests. This setting can #e used to restart the a""lication after a gi%en num#er of re(uests) and it can hel" deal with "ro#lems such as memor$ lea's in legac$ ,*M com"onents used #$ an a""lication or #loc'ed "rocesses. 0efault is Q) . 1ptio"s
re4uest#ueue<imit
0etermines the num#er of re(uests that can #e (ueued #efore ASP.NET returns the 4Q !TSer%er Too Bus$5 status error.
restart#ueue<imit
S"ecifies the num#er of re(uests that 0efault is 2 . are 'e"t in the (ueue while the "rocess is restarting. Pro%ides custom message for Ser%er 9na%aila#le error condition. Path and file name to the desired file. 3f omitted) the default Ser%er 9na%aila#le message is used.
ser%erError9essage1ile
shutdownTimeout
0etermines the amount of time that an This attri#ute ta'es a time ASP.NET wor'er "rocess is gi%en to %alue in the format hh=mm=ss. shut itself down. 3f the time s"ecified #$ this attri#ute is e1ceeded) ASP.NET will force the shutdown of the wor'er "rocess. The default is = = Q. 0etermines the amount of time) in minutes) #efore ASP.NET launches a new wor'er "rocess and shuts down the old one. This setting can #e used to restart the a""lication after a gi%en "eriod of time) and it can hel" deal with "ro#lems such as memor$ lea's in legac$ ,*M com"onents used #$ an a""lication or #loc'ed "rocesses.
Timeout
Ta#le B34?. :process9odel; Element /ttributes $ttri2ute web-arden Descriptio" 1ptio"s 0etermines whether &e# gardening is true= &e# gardening is ena#led. ena#led. false= &e# gardening is disa#led. S"ecifies a "assword for the user account s"ecified in the username attri#ute. 0etermines the identit$ under which ASP.NET wor'er "rocesses are run. 0efault is autogenerate) which can #e used with either the SYSTEM or MA,<3NE s"ecial accounts. 0efault is MA,<3NE) which runs wor'er "rocesses as an un"ri%ileged ASP.NET ser%ice account called ASPNET. This "ro%ides a higher le%el of securit$ than the #eta releases of ASP.NET ?which used the more "ri%ileged SYSTEM accountA) #ut can ma'e certain techni(ues) such as using trusted connections with S:. Ser%er) more difficult #ecause the ASPNET account is not trusted. You can also use another s"ecial account) SYSTEM) to run the ASP.NET wor'er "rocesses) #ut for securit$ reasons) this is not recommended.
Password
username
9we2Co"trols:
The :web=ontrols; element allows $ou to s"ecif$ the location of scri"t files used #$ client/side im"lementations of ASP.NET Ser%er ,ontrols) such as the %alidation controls. The :web=ontrols; element has the following s$nta1=
?1eb-ont"ols client.c"i*tsLocation="*at+" BA
Ta#le B34B. :web=ontrols; Element /ttribute $ttri2ute Descriptio" 1ptio"s This attri#ute is relati%e to the root &e# of the &e# ser%er. clientScripts<ocation 0etermines where ASP.NET will loo' for client/side scri"ts for use with ASP.NET Ser%er ,ontrols.
:clientTarget;
The :clientTarget; element allows $ou to set u" aliases to #e used #$ the =lientTarget "ro"ert$ of the Page class. The :clientTarget; element su""orts one child element) :add;) and has the following s$nta1=
?clientTa")etA ?a!! alias="aliasna&e" use"0)ent="t"ueV#alse" BA ?clea" BA ?"e&o,e alias="aliasna&e" BA ?BclientTa")etA
Ta#le B/2D descri#es the :clientTarget; element attri#utes in more detail. Ta#le B34G. :clientTarget; Element /ttributes Ele#e"t :clientTarget; :add; alias :clear; :remo%e; alias $ttri2ute Descriptio" ,reates aliases for s"ecific #rowser user agents that can then #e s"ecified from the Page.=lientTarget "ro"ert$. Ma"s a s"ecific user agent string to an alias name. S"ecifies the name of the alias. 7emo%es all aliases added ?or inheritedA #$ the current &e#.config file. 7emo%es the s"ecified alias added ?or inheritedA #$ the current &e#.config file. user/gent S"ecifies the #rowser user agent that the alias loo's for.
92rowserCaps:
The :browser=apsS element contains settings used #$ ASP.NET to "ro%ide the functionalit$ of the #rowser ca"a#ilities com"onent ?accessi#le %ia the .e4uest.2rowser "ro"ert$A. 3t "ro%ides filtering "rocesses that allow the #rowser ca"a#ilities com"onent to "o"ulate its "ro"erties with information on the ca"a#ilities of a user+s #rowser) #ased on the information contained in the user agent string "assed #$ the #rowser. The :browser=aps; element su""orts three child elements) :resultS) :use;) and :filter;. The :filter; element su""orts one child element) :case;. The :browser=aps; element has the following s$nta1=
?b"o1se"-a*sA ?"esult t'*e=".'ste&.4eb.Htt*B"o1se"-a*abilities" BA ?use ,a"="HTT/<=. 6<0; NT" BA list o# !e#ault *"o*e"t' ,alues ?#ilte"A ?case &atc+="st"in)1Vst"in)$Vst"in)N"A *"o*e"t'=,alue ?BcaseA ?B#ilte"A ?Bb"o1se"-a*sA
Ta#le B/2C descri#es the :browser=aps; element attri#utes in more detail. Ta#le B34H. :browser=aps; Element /ttributes Ele#e"t :browser=aps; $ttri2ute Descriptio" Allows filtering and ma""ing of strings within the #rowser user agent string to "ro"erties of the #rowser ca"a#ilities com"onent. S"ecifies the result t$"e of the configuration element. type :use; .NET class used as the The default is result t$"e. System. eb.Kttp2rowser=apabilities. 0etermines the ser%er 1ptio"s
:result;
Ta#le B34H. :browser=aps; Element /ttributes Ele#e"t $ttri2ute Descriptio" %aria#les used while e%aluating :filter; and :case; elements. %ar Ser%er %aria#le used in The default is KTTP0!SE.0/-ENT. e%aluating :filter; and :case; elements. The :filter; contains one or more :case; child elements to search for s"ecific strings within the user agent string. Each :case; child element searches for a s"ecific string or strings within the user agent string. match S"ecifies the string or 3f a s"ecified string is found) the "ro"ert$ strings ?se"arated #$ a assignment enclosed #$ the :case;:/case; charactersA to loo' for tags is e1ecuted. in the code. 1ptio"s
:filter;
:case;
0etermine if $our o"erating s$stem su""orts #uilding and running ASP.NET a""lications. Ensure that 3nternet 3nformation Ser%ices is installed and running. 3nstall Microsoft .NET Framewor' and Microsoft Visual Studio .NET. 3nstall the Pu#s sam"le data#ase for access through MS0E. Edit the s$stem "ath for easier access to tools used in this #oo'.
To create ASP.NET a""lications using the Visual Studio .NET de%elo"ment en%ironment) $ou need to install #oth the .NET Framewor' and the Visual Studio .NET software on a su""orted "latform.