232 82 2MB
English Pages 315 Year 2002
New Riders - Debugging ASP.NET
D e bu ggin g ASP.N ET Jon a t h a n Goodye a r Br ia n Pe e k Br a d Fox Pu blish e r : Financial Tim es Prent ice Hall Fir st Edit ion Oct ober 19, 2001 I SBN : 0- 7357- 1141- 0, 376 pages
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Debugging ASP.NET Copyr igh t © 2 0 0 2 by N e w Ride r s Pu blish in g
FI RST EDI TI ON: Oct ober, 2001 All right s reserved. No part of t his book m ay be reproduced or t ransm it t ed in any form or by any m eans, elect ronic or m echanical, including phot ocopying, recording, or by any inform at ion st orage and ret rieval syst em , wit hout writ t en perm ission from t he publisher, except for t he inclusion of brief quot at ions in a review. Library of Congress Cat alog Card Num ber: 00- 110030 06 05 04 03 02 7 6 5 4 3 2 1 I nt erpret at ion of t he print ing code: The right m ost double- digit num ber is t he year of t he book’s print ing; t he right - m ost single- digit num ber is t he num ber of t he book’s print ing. For exam ple, t he print ing code 02- 1 shows t hat t he first print ing of t he book occurred in 2002. Print ed in t he Unit ed St at es of Am erica Tr a de m a r k s
All t erm s m ent ioned in t his book t hat are known t o be t radem arks or service m arks have been appropriat ely capit alized. New Riders Publishing cannot at t est t o t he accuracy of t his inform at ion. Use of a t erm in t his book should not be regarded as affect ing t he validit y of any t radem ark or service m ark. W a r n ing a n d D iscla im e r
This book is designed t o provide inform at ion about Debugging ASP.NET. Every effort has been m ade t o m ake t his book as com plet e and as accurat e as possible, but no warrant y or fit ness is im plied. The inform at ion is provided on an as- is basis. The aut hors and New Riders Publishing shall have neit her liabilit y nor responsibilit y t o any person or ent it y wit h respect t o any loss or dam ages arising from t he inform at ion cont ained in t his book or from t he use of t he discs or program s t hat m ay accom pany it .
New Riders - Debugging ASP.NET
Cr e dit s
Pu blish e r David Dwyer Associa t e Pu blish e r St ephanie Wall M a n a gin g Edit or Krist y Knoop Acqu isit ion s Edit or Deborah Hit t el- Shoaf D e ve lopm e n t Edit or Chris Zahn Pr odu ct M a r k e t in g M a n a ge r St ephanie Layt on Pu blicit y M a n a ge r Susan Nixon Copy Edit or Krist a Hansing I n de x e r Chris Morris M a n u fa ct u r ing Coor din a t or Jim Conway Book D e sign e r Louisa Klucznik Cove r D e sign e r
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Brainst orm Design, I nc. Com posit ion Jeff Bredenst einer To m y beaut iful, dedicat ed, and support ive wife, Joy. The only person who has ever left m e speechless. Jonat han Goodyear To Bunk, m y dog—keep fight ing. Brian Peek To m y Wonderful, Support ive and Beaut iful wife Wendy, who has helped m e becom e t he m an I am t oday and helped m e achieve m y goals in life. Thank you so m uch for being t here for m e, I know it was a difficult j ourney and you st ood by m e every st ep of t he way. Thank you! To m y sons, Brandon and Travis, I love you guys very m uch! And Finally, t hank you Mom and Dad for your support and inspirat ion. Brad Fox
New Riders - Debugging ASP.NET
Debugging ASP.NET About t he Aut hors About t he Technical Reviewers Acknowledgm ent s Jonat han Goodyear Brian Peek Brad Fox Tell Us What You Think I nt roduct ion Who Will Benefit from This Book? Who I s This Book Not For? Organizat ion of This Book Source Code and Errat a Convent ions I : ASP Debugging Basics 1. Concept ual Fram ework Underst anding Server- Side Event s New Language Opt ions Sum m ary 2. Tradit ional Approaches t o Debugging in ASP St ruct ure of Pre–ASP.NET Pages Problem s and Short com ings Old St rat egies That St ill Do t he Job Well An ASP Debug Obj ect Sum m ary 3. Debugging St rat egies Tier Sandboxes Divide and Conquer Sim ple Before Com plex Turt le Makes t he Wiser Sum m ary 4. Code St ruct ure That Eases Debugging Code Part it ioning Cont rol- of- Flow Guidelines
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
St ruct ured Except ion Handling Global Except ion Handling Sum m ary I I : ASP.NET Debugging Tools 5. Condit ional Com piling What I s Condit ional Com piling? Ot her Preprocessor Direct ives Sum m ary 6. Tracing Configurat ion Trace Out put Set t ing Trace Messages Trace Viewer Tracing via Com ponent s Tips for Using Trace I nform at ion Sum m ary 7. Visual St udio .NET Debugging Environm ent I nt roduct ion t o Feat ures At t aching t o Processes Set t ing I t All Up I nline Debugging of ASP.NET Pages I nline Debugging of Com ponent s Rem ot e Debugging Sum m ary 8. Leveraging t he Windows 2000 Event Log The Windows 2000 Event Log Defined Web Applicat ions Can Use t he Event Log The Syst em .Diagnost ics Event Log I nt erface Cust om Event Logs Handling Different Types Of Event s Access Event Log Dat a via t he Web Sum m ary I I I : Debugging t he New ASP.NET Feat ures 9. Debugging Server- Side Cont rols Creat ing t he Proj ect Debugging t he Cont rol Sum m ary
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
10. Debugging Dat a- Bound Cont rols Dat a- Bound Cont rols Debugging Tem plat es Nam espace I ssues XML Binding Sum m ary 11. Debugging User Cont rols User Cont rol Basics Adding Propert ies and Met hods Dynam ic User Cont rols Sum m ary 12. Caching I ssues and Debugging Out put Caching The Caching API Sum m ary I V: Debugging Relat ed Technologies 13. Debugging Web Services Web Services St um bling Blocks Error Messages Problem s Working wit h XMLSerializer Working wit h Errors in SOAP Error Ret urning Cert ain Types of Dat a Working wit h St ream s Tools Basic Web Services Debugging Problem s Deploying Your Web Service? Sum m ary 14. Debugging .NET Com ponent s and Ht t pHandlers The Com ponent I nt erfaces Ht t pHandlers St at e- Managem ent I ssues .NET Com ponent s Versus Regist ered COM Com ponent s Sum m ary 15. COM+ I ssues Role- Based Securit y Com ponent Services Microsoft Managem ent Console
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
Transact ion I ssues Sum m ary 16. Debugging ADO.NET Underst anding t he Syst em .Dat a Nam espace Cat ching SQL Errors New Connect ion Com ponent s I ssues wit h t he Dat aReader Class Working wit h Transact ions Error Codes and How t o Debug Them Com m on Pit falls SQL ADO.NET Obj ect s Versus OleDb ADO.NET Obj ect s Sum m ary A. I ssues t hat Arise When Migrat ing from ASP t o ASP.NET Moving from ASP t o ASP.NET Moving from VBScript t o Visual Basic Opt ing for C# Sum m ary
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Abou t t h e Au t h or s
Jon a t h a n Goodye a r began his career as a soft ware developer at Art hur Andersen aft er receiving a degree in account ing and inform at ion t echnology from St et son Universit y. He has also worked as a consult ant for Pricewat erhouseCoopers and as t he I nt ernet archit ect for t he Hom e Shopping Net work’s e- com m erce presence ( ht t p: / / www.hsn.com ) . Present ly, he works as an independent consult ant t hrough his consult ing pract ice, ASPSoft , focusing on developing web applicat ions wit h ASP.NET. Jonat han is a cont ribut ing edit or for Visual St udio Magazine ( ht t p: / / www.vbpj .com ) and is a chart er m em ber of t he Visual St udio 6 MCSD cert ificat ion. He is also t he founder and edit or of angryCoder ( ht t p: / / www.angrycoder.com ) , t he first eZine writ t en com plet ely in ASP.NET. When not hunched over a keyboard, Jonat han likes t o spend t im e going t o t hem e parks wit h his fam ily near his hom e in Orlando, Florida.
Br ia n Pe e k is a senior soft ware developer wit h Rapid Applicat ion Developers, I nc. ( ht t p: / / www.rapiddevelopers.com / ) locat ed in Troy, New York. He specializes in developing n- t iered applicat ions, web- based applicat ions, wireless applicat ions, and any ot her proj ect s t hat happen t o com e along. Addit ionally, he is t he owner and lead program m er of Ganksoft Ent ert ainm ent ( ht t p: / / www.ganksoft .com / ) , a sm all video gam e–developm ent com pany dedicat ed t o producing high- qualit y gam es for video gam e consoles using only freely available t ools and docum ent at ion. He holds a bachelor’s degree in com put er science from Union College in Schenect ady, New York, his hom et own. When not coding for work or coding gam es t hat he wishes
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
would be published com m ercially, he can oft en be found pract icing m agic, learning t o play piano, or playing his lat est favorit e video gam e. He can be reached at brian@ganksoft .com or [email protected] .
Br a d Fox st art ed program m ing in BASI C at t he age of 12. Since t hen, com put ers and t echnology have played an int egral part in his life. Brad j oined t he Arm y right out of high school and served in t he 82nd Airborne Division. Since t hen he has gone on t o becom e a Microsoft Cert ified Solut ion Developer. Current ly, Brad is CEO of Digit al I nt elligence, I nc., where he spends m ost of his t im e developing cut t ing- edge t echnology for t he financial indust ry.
Abou t t h e Te ch n ica l Re vie w e r s These reviewers cont ribut ed t heir considerable hands- on expert ise t o t he ent ire developm ent process for Debugging ASP.NET. As t he book was being writ t en, t hese dedicat ed professionals reviewed all t he m at erial for t echnical cont ent , organizat ion, and flow. Their feedback was crit ical t o ensuring t hat Debugging ASP.NET fit s our reader’s need for t he highest - qualit y t echnical inform at ion.
D ia n e St ot t le m ye r is present ly an online t eacher for Learning Tree, Capella Universit y, Connect ed Universit y, Franklin Universit y, CalCam pus, and Elem ent K. She enj oys t eaching online and feels t hat her diverse background enables her t o t each m any different courses and add variet y t o t hem . Diane feels t hat her biggest st rengt h as an online t eacher is her abilit y t o present t he st udent m at erials wit h life skills and t o help her st udent s underst and t he m at erial so t hat t hey can process it and use it . Diane is also an adj unct professor for Mary Baldwin College,
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Piedm ont Valley Com m unit y College, and Jam es Sprunt Com m unit y College. She t eaches several course on t est ing, m anagem ent , program m ing, and advanced com put er skills. She is an avid reader and keeps up on new t echnology, new soft ware, and new hardware. Diane is a professor of com put er science and a Cert ified Soft ware Test Engineer; she j ust com plet ed her doct orat e in com put er science. She received her undergraduat e degree from I ndiana Universit y and received m ast ers and Ph.D. degrees in com put er science from Lacrosse Universit y. She believes t hat educat ion is t he door t o fut ure opport unit ies and t hat you are never t oo young or old t o learn. Diane’s first book, ent it led Aut om at ed Web Test ing Toolkit : Expert Met hods for Test ing and Managing Web Applicat ions, will be released t his m ont h. She is excit ed about t he book and feels t hat it will be a great addit ion t o anyone’s library. She also j ust signed a cont ract for her second book on t est ing .NET applicat ions.
St e ve Pla t t has been around com put ers for t he last 17 years; he got in t hrough t he back door aft er st udying chem ist ry and chem ical engineering wit h Pilkingt on Brot hers, a well- known glass m anufact urer. While writ ing som e of t heir financial syst em s in CI CS/ COBOL and ot her obscure languages, such as Gener/ OL and FOCUS, he rose from j unior program m er t o Senior Analyst / Program m er. Deciding t hat cont ract ing was t he way t o go, he st art ed a career t hat brought him int o cont act wit h quit e a num ber of blue- chip com panies: Shell Chem icals, Am erican Express, Shell Oils, and Lloyds Bank. All t hese com panies were m ainfram e users, but t he proj ect s were varied, including a huge dat a t ransfer from legacy syst em s t o DB2, product ion support fire- fight ing, and som e dat a warehousing using Prism . St eve has spent t he last few years in t he I nt ernet arena, working wit h Vict oria Real ( who creat ed t he UK’s BigBrot her sit e) , on I celand online shopping and t he shopping port al Ready2Shop using UNI X, Perl, Oracle 8i, and JavaScript . More recent ly, he j oined RDF Consult ing, a Bright on- based organizat ion and Microsoft solut ion provider t hat specializes in t he e- com m erce needs of financial organizat ions such as Legal & General and Nort hern Rock. There, St eve uses his skills as a configurat ion/ build m anager and Oracle DBA.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
St eve has a wife and daught er, and he is int erest ed in fit ness and t he m art ial art s. He is passionat e about m ot orcycling and new t echnology, and he can be found on m any an evening coding int o t he early hours. He would dearly love t o em igrat e t o Aust ralia.
Ack n ow le dgm e n t s We would all like t o t hank t he following people at New Riders Publishing for t heir t ireless work t owards m aking t his book a realit y. •
•
Acquisit ions Edit or: Karen Wachs
•
Developm ent Edit or: Chris Zahn
•
Copy Edit or: Krist a Hansing
•
Com posit or: Jeff Bredenst einer
•
Acquisit ions Edit or: Deborah Hit t el- Shoaf
•
Managing Edit or: Krist y Knoop
•
I ndexer: Chris Morris Technical Reviewers: Diane St ot t lem eyer, St eve Plat t
Jon a t h a n Goodye a r Many people have helped lift m e t o where I am t oday. I would like t o t hank Darren Jensen, Paula St ana, and John Wagner at Art hur Andersen for pat ient ly m ent oring m e while I was a developm ent rookie. Wit hout your help, I would have becom e an em ploym ent casualt y early in m y career. I would like t o t hank Robert Teixeira for filling in t he gaps in m y knowledge while I was at Pricewat erhouseCoopers. You have an am azing gift for dist illing com plex concept s int o underst andable inform at ion. From The Hom e Shopping Net work, I would like t o t hank Nick Ruot olo for t aking a chance on a young, but am bit ious, kid. I would also like t o t hank Ken McNam ee for lending m e t he server t hat I used t o t est t his book’s code. At Visual St udio Magazine ( form erly Visual Basic Program m er’s Journal) , I would like t o t hank Susannah Pfalzer. Wit h your help, m y writ ing has im proved t enfold. I t has been a pleasure t o work wit h you and t he rest of t he VSM st aff ( part icularly Pat rick Meader and Elden Nelson) over t he past couple of years. My co- aut hors, Brian Peek and Brad Fox, deserve a special t hank- you for t heir help in bringing m y book idea t o life. You guys st epped in and did a fant ast ic j ob.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
On a personal level, I would like t o t hank som e of m y lifelong friends for everyt hing t hat t hey have done for m e t hroughout t he years. They are St ephen Ferrando, Pat rick Tehan, Jam ie Sm it h, Jam es Rowbot t om , and Dam ian Jee. You guys are t he best ! To m y wife, Joy, t hank you for your endless pat ience while I pursue m y career dream s. Wit hout you, none of t his would have been possible. I would like t o t hank m y 1- year- old son, CJ, for opening m y eyes t o t he wonders of fat herhood. Last ly, I would like t o t hank m y sist er- in- law, Cherie. Your relent less pursuit of your Olym pic dream s in gym nast ics has been an inspirat ion t o m e.
Br ia n Pe e k This book, and life in general, would not be possible wit hout t he help and support of quit e a few people. At t he very t op of t hat list would be Jonat han for giving m e t he opport unit y t o co- aut hor t his book wit h him . Thanks t o m y parent s for providing m e wit h daily encouragem ent while writ ing. A t hank you t o Jennifer Trot t s not only for com ing back, but for m aking m e cookies. I m issed you. Thank you t o Mark Zaugg, a great friend who has guided m e t hrough som e t ough t im es and who cont inues t o be highly m ellifluous ( and Canadian) . I would like t o t hank St acy Tam burrino for t eaching m e a great deal about m yself, and for m any wonderful t im es and m em ories t hat I will always t reasure. Thank you t o Mat t hew Kennedy for being a great friend and sharing m y cynicism t oward t he planet . I t hank Arden Rauch for giving m e confidence in m y abilit ies at an early age. Thanks t o Bob Thayer for put t ing up wit h m y anal ret ent iveness on graphic layout s. A big t hank- you t o m y grandparent s for put t ing m e t hrough college. And finally, a short hello and t hank you t o m y friends t hat have support ed m e in m y endeavors: Adina Konheim , Jason Sawyer, Danet t e Slevinski, David Wallim ann, Robert Sharlet , Michael Kilcullen, Girish Bhat ia, Chuck Snead, Just in Whit ing, Clare Mert z- Lee, Ed O’Brien, Jon Rodat , Dionne Ehrgood, Pat ricia Hoffm an, Andy Lippit t , and t he rest of t he RAD st aff.
Br a d Fox Every t im e you read t hese t hings, t hey seem so cliché, but what can you do? I will t ry t o m ake m ine int erest ing. First of all, I have t o t hank Jonat han Goodyear—yes, t he aut hor of t his book, for giving m e t he opport unit y t o co- aut hor wit h him . This has been a dream of m ine for half m y life, and he has helped m e t o accom plish it . Thank you, Jonat han. J
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Next , I would like t o t hank David Waddlet on for helping m e wit h Chapt er 13, “ Debugging Web Services.” I would also like t o t hank Shannon McCoy for his support and t he knowledge t hat I was able suck from his brain. Not t o m ent ion, he’s t he best friend anyone could have. I love ya, buddy. A few individuals at Microsoft t hat were inst rum ent al in m aking t his book a success. These include Scot t Gut hrie, Rob Howard, Susan Warren, Shaykat Chaudhuri, and Dm it ry Robsm an. Thanks t o all of you for your help on t his book.
Te ll Us W h a t You Th in k As t he reader of t his book, you are t he m ost im port ant crit ic and com m ent at or. We value your opinion and want t o know what we’re doing right , what we could do bet t er, what areas you’d like t o see us publish in, and any ot her words of wisdom you’re willing t o pass our way. As t he Associat e Publisher for New Riders Publishing, I welcom e your com m ent s. You can fax, em ail, or writ e m e direct ly t o let m e know what you did or didn’t like about t his book—as well as what we can do t o m ake our books st ronger. Please not e t hat I cannot help you wit h t echnical problem s relat ed t o t he t opic of t his book, and t hat due t o t he high volum e of m ail I receive, I m ight not be able t o reply t o every m essage. When you writ e, please be sure t o include t his book’s t it le and aut hor as well as your nam e and phone or fax num ber. I will carefully review your com m ent s and share t hem wit h t he aut hor and edit ors who worked on t he book. Fax:
317- 581- 4663
Em ail:
st [email protected]
Mail: St ephanie Wall Associat e Publisher New Riders Publishing 201 West 103 rd St reet I ndianapolis, I N 46290 USA
I n t r odu ct ion Over t he last year or so, an incredible am ount of indust ry at t ent ion has been paid t o Microsoft ’s new .NET Fram ework. I t is t he plat form t hat will drive Microsoft ’s
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t echnology direct ion for at least t he next five years. Wit h so m uch at st ake, developers have been clam oring t o get t heir hands on anyt hing and everyt hing .NET. The web port ion of t he m ult idim ensional .NET Fram ework is ASP.NET. ASP.NET is t he next generat ion of t he Act ive Server Pages web- developm ent plat form , and it represent s a quant um leap forward wit h respect t o it s feat ure set and scalabilit y. Wit h it s newfound power, however, com es increased com plexit y. This book is designed t o address m any of t he problem s and issues t hat developers will m ost assuredly face as t hey begin developing web applicat ions using ASP.NET. Specifically, it int roduces t ried- and- t rue web- developm ent st rat egies t hat reduce t he risk of bugs and also enable bugs t o be t racked down m ore easily when t hey do occur. This book also int roduces t he m yriad new debugging t ools t hat are available in ASP.NET and dem onst rat es how t o use t hem effect ively. Finally, t his book t ackles t he issues and problem s associat ed wit h each aspect of ASP.NET, showing pot ent ial error m essages and explaining how t o fix t heir causes. By no m eans is t his book a t roubleshoot ing com pendium . There is sim ply no way t o account for all possible errors and bugs t hat can be encount ered in an ASP.NET web applicat ion. I nst ead, t his book gives solid advice on how t o build bug- free web applicat ions, gives you a firm underst anding of t he debugging t ools t hat are at your disposal, and explains how t o handle som e of t he m ore com m on errors and bugs t hat occur. When you finish t his book, you should be confident enough t o find and elim inat e any bug t hat you encount er in your ASP.NET web applicat ion.
W h o W ill Be n e fit fr om Th is Book ? The int ended audience for t his book is int erm ediat e t o experienced developers and proj ect m anagers. The persons responsible for est ablishing proj ect coding st andards, m ent oring j unior- level developers, and debugging web applicat ions will get t he m ost benefit from t his book. The reader should be fam iliar wit h developing ASP.NET web applicat ions wit h eit her Visual Basic .NET or C# ( all code exam ples are provided in bot h languages) . Som e of t he key skills t hat t he reader will learn from t his book are list ed here: •
•
How t o writ e code t hat reduces t he chance of bugs
•
Solid st rat egies for debugging large web applicat ions
•
t racing, event logging, and condit ional com piling
•
User Cont rols, caching, ADO.NET, and web services
How t o leverage t he m any debugging t ools available in ASP.NET, such as How t o t rack down bugs associat ed wit h specific part s of ASP.NET, such as Som e of t he caveat s and issues com m on t o m igrat ing t radit ional ASP web applicat ions t o ASP.NET
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
W h o I s Th is Book N ot For ? This book is not for j unior- level developers or for developers who are not relat ively com fort able developing web applicat ions wit h ASP.NET. I t is not an ASP.NET t ut orial; m any ot her books on t he m arket accom plish t his t ask very well. Likewise, t his book assum es t hat t he reader is fam iliar wit h eit her Visual Basic .NET, C# , or bot h. The reader will not be able t o underst and and use t he code exam ples wit hout t his knowledge.
Or ga n iza t ion of Th is Book The book part s and chapt ers are out lined in t he next several sect ions.
Pa r t I : ASP D e bu ggin g Ba sics Chapt er 1, “ Concept ual Fram ework,” explains som e of t he new concept s int roduced wit h ASP.NET, such as server- side event s, t he ASP.NET page life cycle, and t he new language opt ions available. Chapt er 2, “ Tradit ional Approaches t o Debugging in ASP,” covers som e of t he approaches used t o debug t radit ional ASP web applicat ions. I t highlight s several of t he problem s and short com ings wit h t he lim it ed t ools t hat were available. Chapt er 3, “ Debugging St rat egies,” out lines several plans of at t ack for debugging ASP.NET web applicat ions. This includes debugging applicat ion t iers individually and dist illing com plex code int o sm aller, m ore m anageable pieces. Chapt er 4, “ Code St ruct ure That Eases Debugging,” gives advice on how t o build code t hat is bot h less likely t o cont ain bugs and easier t o debug when bugs creep in. Topics include code part it ioning, cont rol- of- flow guidelines, st ruct ured except ion handling, and global except ion handling.
Pa r t I I : ASP.N ET D e bu ggin g Tools Chapt er 5, “ Condit ional Com piling,” covers how t o t ake advant age of funct ion at t ribut es and preprocessor direct ives t o dynam ically add debugging code t o your web applicat ions. Chapt er 6, “ Tracing,” shows you how t o use t he new TraceCont ext obj ect available in ASP.NET and int erpret it s result s. Trace configurat ion at bot h t he page and t he applicat ion levels is covered, as is using t he Trace Viewer ut ilit y.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Chapt er 7, “ Visual St udio .NET Debugging Environm ent ,” int roduces all t he powerful debugging feat ures packed int o t he Visual St udio .NET I DE. Som e of t he t opics covered include how t o set breakpoint s, t he call st ack, t he wat ch window, inline ASP.NET page debugging, and how t o at t ach t o processes. Chapt er 8, “ Leveraging t he Windows 2000 Event Log,” explains how t o writ e dat a t o t he Windows 2000 Event Log. Som e of t he t hings you will learn in t his chapt er include how t o creat e cust om event logs, how t o handle bot h expect ed and unexpect ed event s, and how t o access t he cont ent s of t he Windows 2000 Event Log via t he web.
Pa r t I I I : D e bu ggin g t h e N e w ASP.N ET Fe a t u r e s Chapt er 9, “ Debugging Server- Side Cont rols,” t akes you t hrough t he process of creat ing a cust om server cont rol, out lining m any of t he issues t hat you m ight encount er. Pract ical advice and solut ions for t hese issues are provided. Chapt er 10, “ Debugging Dat a- Bound Cont rols,” t akes a close look at som e of t he com m on m ist akes t hat can be m ade while using dat a- bound server cont rols. Dat aGrid, Dat aList , and t he XML dat a binding are a few of t he t opics covered. Chapt er 11, “ Debugging User Cont rols,” covers m any of t he issues t hat you m ight encount er while building user cont rols. The basics are covered, as are propert ies, m et hods, and dynam ic user cont rol issues. Chapt er 12, “ Caching I ssues and Debugging,” delves int o t he t ypes of issues t hat crop up when leveraging caching in ASP.NET web applicat ions. Highlight s of t his chapt er include cache dependencies, out put caching, t he caching API , expirat ion callbacks, and declarat ive at t ribut es.
Pa r t I V: D e bu ggin g Re la t e d Te ch n ologie s Chapt er 13, “ Debugging Web Services,” uncovers and offers solut ions for m any of t he problem s t hat you m ight encount er while building and im plem ent ing web services. Several different error m essages are discussed. Som e of t he ot her t opics covered are t he XMLSerializer, SOAP, and UDDI . Chapt er 14, “ Debugging .NET Com ponent s and Ht t pHandlers,” explains how t o use t he St ackTrace and Text Writ erTraceList er obj ect s t o t rack down bugs in .NET com ponent s and Ht t pHandlers. The chapt er also discusses issues wit h int erfaces and st at e m anagem ent .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Chapt er 15, “ COM+ I ssues,” covers t he problem s and issues t hat can occur when set t ing up com ponent s t o leverage COM+ . I t also covers som e of t he runt im e anom alies t hat m ight occur in t he cont ext of COM+ . Chapt er 16, “ Debugging ADO.NET,” helps you int erpret ADO.NET error m essages, as well as t rack down bugs associat ed wit h each of t he new ADO.NET obj ect s. Dat abase perm issions issues are also briefly discussed.
Appe n dix Appendix A, “ I ssues That Arise When Migrat ing from ASP t o ASP.NET” , is a collect ion of issues t hat you are likely t o run int o while port ing your t radit ional ASP web applicat ions t o ASP.NET. The new declarat ion synt ax for script blocks is discussed along wit h m any ot her useful t opics, such as page declarat ives, event s, and cookies.
Sou r ce Code a n d Er r a t a All t he source code provided in t his book can be downloaded from www.debuggingasp.net . Also available at t he sit e are any correct ions and updat es t o t he t ext . The errat a will be updat ed as issues are discovered and correct ed
Con ve n t ion s This book follows t hese t ypographical convent ions: •
List ings, funct ions, variables, and ot her “ com put er language” are set in a fixed- pit ch font —for exam ple, “ you should not e t he addit ion of t he
•
RUNAT=" ser ver " param et er added t o each cont rol.” Code Cont inuat ion charact hers
are insert ed int o code when a line is t oo
wide t o fit int o m argins.
Pa r t I : ASP D e bu ggin g Ba sics ASP Debugging Basics 1 Concept ual Fram ework 2 Tradit ional Approaches t o Debugging in ASP 3 Debugging St rat egies 4 Code St ruct ure t hat Eases Debugging
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Ch a pt e r 1 . Con ce pt u a l Fr a m e w or k
ASP.NET I S THE NEXT STAGE I N THE Act ive Server Page evolut ionary process. I t ext ends t he exist ing ASP fram ework int o a whole new realm of power. Now you can use ASP in a t rue t hree- t ier archit ect ure. Wit h ASP.NET, you will be able t o harness t he power of a t rue program m ing language, such as Visual Basic .NET or C# , inst ead of VBScript . I s ASP.NET easy t o use? Yes. I s it t he sam e as ASP? Not even close. But do not fret . I n t his chapt er, we discuss som e of t he new feat ures of t he ASP.NET fram ework and show how it differs from t he ASP fram ework t hat you current ly know and love—or at least know and use. First we focus on server- side event s, and t hen we discuss new language opt ions for use wit h t he .NET version of ASP.
Un de r st a n din g Se r ve r - Side Eve n t s Server- side event s are one of t he fundam ent al changes in t he ASP.NET archit ect ure, com pared t o older versions of ASP. These server- side event s provide for a program m ing m odel t hat is very sim ilar t o t hat of a t radit ional event - m odel Visual Basic applicat ion. The code for t hese event s is generally st ored in a separat e file called a code- behind file. This allows for separat ion bet ween your client and server code, m aking t hings m uch m ore organized and st ruct ured. The code- behind file sim ply cont ains everyt hing t hat used t o be cont ained wit hin t he files in your old ASP pages; however, it is st rict ly code wit hout any HTML. Now let ’s see what event s are available t o you on t he server and how you can exploit t hem t o your advant age.
D iffe r e n ce s fr om Clie n t - Side Eve n t s The m aj or difference bet ween client - side event s and server- side event s, obviously, is t hat server- side event s are handled on t he server. This adds a great degree of flexibilit y and power t o t he exist ing ASP fram ework. I t also provides for far m ore st ruct ured code. Client - side event s are part of t he DHTML st andard. They can be script ed in eit her JavaScript or VBScript , and t hey are em bedded direct ly in t he HTML of your page. These event s allow you t o t rap but t on clicks, t ab out of t ext boxes, det ect t he
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
presence of t he m ouse cursor over cert ain cont rols, and handle ot her event s t hat involve a user changing som et hing on t he client - side int erface. Server- side event s enable you t o respond t o sim ilar event s, such as changing a t ext box or clicking a but t on, but , obviously, t hese are handled on t he server inst ead of t he client . Because a t rip t o t he server is required t o act ivat e t hese event s, only a sm all subset of event s is available. These are generally lim it ed t o “ click- t ype” event s rat her t han “ m ouse- over” event s. I m agine having t o m ake a t rip t o t he server every t im e your m ouse m oved 1 pixel!
Type s of Se r ve r - Side Eve n t s The t ypes of event s available on t he server are very basic. For exam ple, you will be able t o respond t o but t on clicks, t ext box changes, and drop- down box changes. Take a look here at what one of t hese event s looks like on t he server. List ing 1.1 shows a very sim ple ASP page t hat cont ains a form wit h a t ext box and a Subm it but t on. List in g 1 .1 Sim ple ASP Pa ge w it h a For m
You will not ice t hat t his looks like som e plain old HTML. However, you should not e t he addit ion of t he RUNAT=" ser ver " param et er added t o each cont rol. This enables you t o t rap t he event s on t he server and respond t o t hem appropriat ely. Now t ake a look at a server- side event associat ed wit h bot h t he t ext box and t he Subm it but t on. List ing 1.2 shows t his in C# . List in g 1 .2 Se r ve r - Side Eve n t s in C# publ i c voi d bt nSubmi t _Ser ver Cl i ck( sender As Obj ect , e as Event Ar gs) { t xt Tex t . Val ue = " You cl i cked t he Submi t but t on! " ; }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
pr ot ect ed voi d t xt Text _Text Changed( obj ect sender , Event Ar gs e) { Response. Wr i t e( " Text Changed: " + t xt Text . Val ue) ; } List ing 1.3 shows t he sam e event exam ples in Visual Basic. List in g 1 .3 Se r ve r - Side Eve n t s in Visu a l Ba sic .N ET Pr i vat e Sub bt nSubmi t _Ser ver Cl i ck ( sender As Obj ect , e as Event Ar gs) t xt Tex t . Val ue = " You cl i cked t he Submi t but t on! " End Sub Sub t xt Text _Text Changed( sender Obj ect , e As Event Ar gs) Response. Wr i t e( " Text Changed: " & t xt Text . Val ue) End Sub I n each of t hese exam ples, t wo separat e event s are being handled on t he server: a Subm it but t on being clicked and t he value of a t ext box being changed. Each event t hat is handled on t he server t akes t he Obj ect and Event Ar gs argum ent s. The obj ect is sim ply t he obj ect t hat sent you t he event ( for exam ple, t he but t on, t he t ext box, and so on) . The Event Ar gs argum ent cont ains any event - or obj ect - specific argum ent s t hat are relevant t o t he obj ect being act ed upon.
ASP.N ET Pa ge Life Cycle The life cycle of an ASP.NET page is sim ilar t o t hat of an ASP page. However, you can hook int o a few new event s as well. Table 1.1 runs down t he event s of an ASP.NET page. Tabl e 1. 1. Event s i n t he Li f e Cycl e of an ASP. NET Page
Event Page_I ni t
Description This is t he first event t o be called in t he process. Here you should provide any init ializat ion code required for inst ant iat ion of t he page.
Page_Load
At t his point , cont rol view st at e is rest ored. You can now read and updat e cont rol propert ies.
Page_Pr eRender This event is raised before any page cont ent is sent t o t he browser. Page_Unl oad
This is t he very last event t o be raised.At t his point , you should clean up everyt hing you have used, including closing connect ions and dereferencing obj ect s.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n t erm s of t he life cycle of your ASP.NET applicat ion, quit e a few new event s can be used inside t he global.asax file. The event s t hat can be hooked int o in global.asax are described in Table 1.2. Tabl e 1. 2. Event s That Can Be Used I nsi de gl obal . asax
Event Appl i cat i on_St ar t
Description Raised
only
once,
when
t he
applicat ion st art s for t he first t im e. I nit ialize
applicat ion- wide
t hings
here. Sessi on_St ar t
Raised when a new user ’s session begins.
Appl i cat i on_End
Raised when your applicat ion shut s down or is reset . Clean up here.
Sessi on_End
Raised when a user ’s session t im es out or is reset .
Appl i cat i on_Er r or
Raised when an unhandled except ion is raised ( t hose not caught in a t ry/ cat ch block) . You could call a logging rout ine here.
Appl i cat i on_Begi nRequest
Raised every t im e a new request is received at t he server.
Appl i cat i on_Aut hent i cat e
Raised when t he request is t o be aut hent icat ed.You
can
provide
cust om aut hent icat ion code here. Appl i cat i on_Aut hor i zeRequest
Raised when t he request is t o be aut horized. Again, you can provide cust om aut horizat ion code.
Appl i cat i on_Resol veRequest Cache
Raised t o enable you t o st op t he processing
of
request s
t hat
are
cached. Appl i cat i on_Acqui r eRequest St at e
Raised t o enable you t o m aint ain st at e in
your
applicat ion
( session/ user
st at e) . Appl i cat i on_Pr eRequest Handl er Execut e The last event t o be raised before t he request is processed by t he ASP.NET page or a web service. Appl i cat i on_Post Request Handl er Execut e Raised aft er t he handler has finished processing t he request . Appl i cat i on_Rel easeRequest St at e
Raised t o enable you t o st ore t he st at e of your applicat ion.
New Riders - Debugging ASP.NET
Appl i cat i on_Updat eRequest Cache
m ade by dot net er@t eam fly
Raised when processing is com plet e and
t he
page
is going
int o
t he
ASP.NET cache. Appl i cat i on_EndRequest
Raised
at
t he very
end
of
your
request . Appl i cat i on_Pr eRequest Header sSent
Raised before HTTP headers are sent t o t he client . Here you can add cust om headers t o t he list .
Now you can’t say t hat you don’t have enough cont rol of what happens when and where in your ASP.NET applicat ion. These event s also provide excellent places t o hook int o t he ASP.NET processing chain for debugging, as you will see in som e lat er chapt ers.
N e w La n gu a ge Opt ion s ASP.NET gives you unprecedent ed flexibilit y in t hat it enables you t o use any .NET- enabled language as your server- side code. Out of t he box, you’ll be able t o use Visual Basic, C# , JScript , and C+ + wit h m anaged ext ensions as your server- side language. Not e t hat we said Visual Basic, not VBScript . ASP.NET finally enables you t o use a real program m ing language, not a script ed language. This offers a huge benefit in a couple areas. First , you gain t he speed of a com piled language versus an int erpret ed language. Because no t im e is wast ed in parsing t he script ed code, and because your code is com piled down int o nat ive m achine code, you get a very significant speed increase. Anot her benefit t o using a real program m ing language is t hat you have real dat a t ypes. I f you’re fam iliar wit h ASP, you will rem em ber t hat every variable is of t ype Variant . ASP.NET enables you t o use t yped languages t o your advant age. Now you will never need t o quest ion whet her your variable is really a St ring or an I nt eger int ernally because you will be able t o specify it s t ype before it is assigned.
Su m m a r y This chapt er discussed server- side event s and showed how t hey change t he way an ASP.NET page is processed versus a t radit ional ASP page. I t also discussed t he advant ages of using a real program m ing language t o writ e your server code. The next chapt er t akes a look at som e exist ing ways t o debug ASP code t hat can be easily used in t he ASP.NET environm ent . Lat er chapt ers discuss debugging t echniques t hat are new and specific t o ASP.NET only.
New Riders - Debugging ASP.NET
Ch a pt e r
2.
Tr a dit ion a l
m ade by dot net er@t eam fly
Appr oa ch e s
to
D e buggin g in ASP
I F YOU HAVE EVER USED A PREVI OUS version of ASP, you are already aware of t he night m are t hat debugging a t radit ional ASP applicat ion can becom e. This chapt er explains som e of t he short com ings of t he original ASP t echnology, t he pot ent ial problem s and pit falls involved in debugging a t ypical ASP applicat ion, and a few ways t o overcom e t hese obst acles. At t he end of t he chapt er, you’ll find a debugging obj ect t hat can be used in t andem wit h a t radit ional ASP page t o display a great deal of useful inform at ion for t racking down t hose pesky errors in your ASP code.
St r u ct u r e of Pr e – ASP.N ET Pa ge s As you will soon see, t he st ruct ure of a page in previous versions of ASP is quit e different from t hat of an ASP.NET page. Pre–ASP.NET pages are severely lacking in t he st ruct ure depart m ent . Alt hough t here are a few ways t o m ake your ASP code slight ly st ruct ured, several lines becom e blurred. This sect ion t alks about a few of t he com m on problem s t hat developers run int o when developing wit h previous versions of ASP.
Th e Gr e a t M on olit h So how do you current ly writ e ASP pages? Well, if you’re anyt hing like us—and let ’s hope t hat you’re not , in som e respects—your ASP pages have t he st ruct ure of a 50- st ory skyscraper m ade out of Popsicle st icks. Now, don’t get us wrong: A cert ain degree of st ruct ure can be at t ained wit h st andard ASP program m ing, but it is not t he t ype of st ruct ure and organizat ion t hat is obt ained wit h a real program m ing language. The fact is, t here j ust isn’t any great way t o writ e ext rem ely st ruct ured code in ASP like t here is in Visual Basic or C# . For exam ple, if you have a series of “ global” funct ions t hat are used t hroughout your applicat ion, you probably shove t hem int o an .asp file and use t he #i ncl ude f i l e direct ive t o bring t hem int o t he rest of your .asp pages t o avoid code repet it ion. Alt hough t his m ight get t he j ob done, you m ight not realize what is happening behind t he scenes wit h t he script parser.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
By including pages in t his m anner, t hey sim ply get t acked on at t he point where you include t hem . This m eans t hat t he ent ire included page is parsed and processed even if only a single const ant declarat ion, for exam ple, is used out of it . Luckily, because ASP.NET uses t rue, com piled languages, it get s you out of t his bind.
Pa st a N igh t m a r e You probably have heard t he expression “ spaghet t i code,” which is code t hat lacks st ruct ure and clear separat ion am ong t he m ain elem ent s. Tradit ional ASP code is t he epit om e of spaghet t i code. Code does not get m uch m ore t angled up in any language quit e like it does in ASP. The m ain reason for t his is t he lack of a dist inct separat ion bet ween client - side present at ion code and server- side business/ logic code. I n t he t radit ional ASP environm ent , you generally wind up m ixing your HTML present at ion layer wit h your VBScript server code, as shown in List ing 2.1. List in g 2 .1 A Typica l ASP Pa ge
As you can see, inst ead of a very clear dist inct ion bet ween t he HTML t hat creat es t he drop- down box and t he code t hat fills it , t he t wo are very m uch int ert wined. This t ype of coding conflict s wit h t he basic principles of “ t hree- t ier” program m ing. The t heory of t hree- t ier program m ing is t hat t here is a dist inct separat ion am ong t he client present at ion layer, t he server business logic layer, and t he dat abase layer. I n ASP, t he lines bet ween t hese layers can very easily becom e blurred. I n t he previous exam ple, you are doing work t hat could and should be perform ed at t he business logic layer inst ead of at t he client layer.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Th e I n clu sion Con clu sion Code reuse is a very im port ant part of writ ing any t ype of applicat ion. No one want s t o rewrit e t he sam e code t o perform t he sam e funct ion t im e and t im e again. Most program m ing languages provide a way for developers t o include libraries of funct ions in t heir applicat ions, saving t hem from having t o reinvent t he wheel every t im e t hey need t o do som et hing sim ple. ASP allows for som et hing sim ilar, but it has one very m aj or flaw. For exam ple, im agine t hat you are writ ing a screen for an applicat ion t hat needs t o pull several ADO recordset s from a dat abase and display t hem t o t he user in a t able. The code t o grab t he recordset from t he dat abase m ight look sim ilar t o List ing 2.2. List in g 2 .2 Code t o Re t r ie ve a n AD O Re cor dse t
Every t im e you need t o ret rieve an ADO recordset , you m ust rewrit e t he code t hat creat es t he connect ion obj ect , opens t he connect ion, creat es t he recordset obj ect , and opens t he recordset . So how do you solve t his in t radit ional ASP? Well, you can writ e som e generic rout ines t hat open connect ions or open recordset s and put t hem in a separat e file. Then you can use t he #i ncl ude f i l e=" " direct ive t o pull t his file int o t he page t hat is about t o be displayed t o t he user. However, t his scenario cont ains one m aj or downfall: Every page t hat is included in t his fashion is parsed in it s ent iret y. So, if you creat ed an ASP page t hat included all your dat abase rout ines for your ent ire applicat ion, and you t hen included it on a page on which only one of t he funct ions is used, t he ASP processor st ill would parse t he ent ire page and work it s way t hrough all t he unused code before giving you what you need. Wit hout a doubt , t his is t erribly inefficient . So how do you com bat t hat in ASP? The way t o current ly work around t his problem in ASP is t o m ove your business logic code int o com ponent s. From ASP, you can creat e an inst ance of your com ponent and call m et hods on it j ust as you would from Visual Basic. Wit h t his approach, you gain t he benefit of a com piled language—t hat is, increased speed and decreased m em ory usage. However, t his approach suffers from a num ber of downfalls. First , you will be forced t o com pile your code every t im e you want t o m ake a change inst ead of j ust edit ing a t ext file. This can becom e quit e cum bersom e if your sit e undergoes m any changes before becom ing st able. Second, when t he obj ect is inst ant iat ed in your ASP page, you get only a generic obj ect t hat pret ends t o be t he real obj ect . Because of t his, every t im e you call a m et hod on t hat obj ect , t he Get I DsOf Names API call is fired t o locat e t he posit ion of t he m et hod in t he obj ect ’s vt able. This is a definit e perform ance hit . Finally, deploying com ponent s can be a difficult process. Access t o t he server is required t o regist er t he result ing DLLs. This runs cont rary t o t he sim ple process of copying assem blies t o t he server in t he case of a ASP.NET applicat ion, which can even be done t hrough a sim ple shared drive or folder.
Pr oble m s a n d Sh or t com in gs Alt hough ASP is a very powerful t echnology, it suffers from a num ber of problem s and short com ings. I t lacks separat ion of client - and server- side code, it does not allow for st ruct ured program m ing, and it does not follow an event - st yle program m ing m odel, am ong ot her issues. Luckily, ASP.NET addresses m any of
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t hese problem s and t urns ASP int o an even m ore powerful and easy- t o- use t echnology for t oday’s high- powered web- based applicat ions.
N o Eve n t s I f you’re a Visual Basic program m er, you are quit e fam iliar wit h event - based program m ing. For exam ple, if you drop a but t on on a form in Visual Basic, t hen when a user clicks it , it generat es a Cl i ck event t hat you can respond t o and act on appropriat ely. I n ASP, t his t ype of program m ing m odel is nonexist ent , even t hough t he sam e t ypes of event s are t aking place in your web page–based applicat ion. That is, but t ons are being clicked, users are ent ering and leaving fields, and so on. Why shouldn’t you have t he capabilit y t o answer t hese event s in a sim ilar m anner? This is one area in which ASP.NET really shines.
I n clu de s Ea t Up M e m or y As discussed in t he previous sect ion,“ includes” are a horribly inefficient way t o do som et hing t hat is inherent ly very sim ple. As an ASP program m er, you should be able t o link a library of funct ions int o t he m ain applicat ion wit hout a det rim ent al perform ance hit . Most program m ing languages allow for dynam ically or st at ically linked libraries t hat cont ain com m only called funct ions direct ly t o t he applicat ion only once, in t he case of st at ic linking, or t hat allow t hem t o be called from an ext ernal binary file in t he scenario of dynam ic linking. An excellent exam ple of a bloat ed include file is t he ADOVBS.I NC file provided by Microsoft , which defines an ASP int erface for ADO. This file is huge, and m ost people will use only a few it em s out of t he m yriad of t hings it declares. Even t hough you m ight use only t hose very few it em s, however, t he ent ire page is parsed every single t im e it is referenced. I n a real program m ing language, such as Visual Basic or C, you would com pile against a library cont aining point ers for t he real versions of t he funct ions in precom piled DLLs. I n t his way, you are never wast ing t im e accessing any port ion of t he ADO library t hat you don’t explicit ly request .
Scr ipt e d La n gu a ge Ve r su s Com pile d La n gu a ge One of t he m aj or problem s wit h ASP is t hat it is a script ed language rat her t han a com piled language. This involves an enorm ous and severe perform ance hit , for a num ber of reasons.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
First , t he script parser needs t o parse t he ent ire page t op t o bot t om before any of t he code can be execut ed. Second, when t he code is parsed, it is not generat ed int o a nat ive m achine code t hat can be execut ed direct ly every t im e t hereaft er. This process m ust be repeat ed every single t im e t hat t he page is rendered, which is obviously incredibly inefficient .
Old St r a t e gie s Th a t St ill D o t h e Job W e ll Alt hough a variet y of new debugging feat ures in t he Visual St udio .NET I DE can be used in debugging your ASP.NET applicat ions, som e old m et hods and t ricks from t he days of ASP are st ill wort hwhile.
Usin g t h e Re spon se Obj e ct Previous versions of ASP are built on t he foundat ion of five obj ect s: Response, Request , Ser ver , Appl i cat i on, and Sessi on. The Response obj ect is used t o send inform at ion from t he server down t o t he client ’s browser. The Wr i t e m et hod of t he Response obj ect can be used t o dynam ically writ e cont ent t o t he client ’s browser. This is one of t he easiest ways t o debug st andard ASP pages and is st ill applicable in t he new archit ect ure. The problem wit h t his approach is t hat it isn’t very pret t y. At t he end of debugging a long logic process, you will wind up wit h a pile of i f / t hen st at em ent s and Response. Wr i t e( ) calls lit t ered t hroughout your .asp pages. This out put can get lost inside t he HTML if it ’s not placed properly. A bet t er approach is t o creat e a specific debugging obj ect t hat out put s im port ant and pert inent inform at ion but handles it in a m uch nicer and cleaner fashion.You will writ e an obj ect like t his lat er in t he chapt er so t hat you can use it very easily in your ASP debugging procedures.
Usin g t h e Se r ve r Obj e ct I nt ernet I nform at ion Server ( I I S) 5.0 included a new m et hod on t he Ser ver obj ect , called Get Last Er r or . This m et hod ret urns an ASPEr r or obj ect t hat cont ains alm ost everyt hing you need t o know about t he error except how t o correct it . Table 2.1 shows what propert ies are available on t he ASPError obj ect . Tabl e 2. 1. Pr oper t i es of t he ASPEr r or Obj ect
ASP Code
Error Code from IIS
Num ber
COM error code
Source
Source of line t hat caused error
Cat egory
Type of error ( ASP, script , obj ect )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
File
ASP file where error occurred
Line
Line num ber where error occurred
Colum n
Colum n where error occurred
Descript ion
A t ext descript ion of t he error
ASPDescript ion
Det ailed descript ion if error was ASP- relat ed
You will not ice t hat t he inform at ion ret urned in t he obj ect is t he sam e inform at ion t hat is present ed t o you in a st andard ASP error page. However, wit h t his inform at ion at your disposal, you can creat e a cust om error page t hat is displayed inst ead of t he st andard ASP error page.You can set t he error t o your own cust om page by using t he I I S Adm in t ool. I f a cust om page is select ed, t hen when t he server encount ers an error, it will perform a Ser ver . Tr ansf er t o t he error page, m aint aining all st at e inform at ion t o t he new page. This enables you t o get an inst ance of t he ASPEr r or obj ect and pull out t he pert inent inform at ion for display as a debugging guide. List ing 2.3 shows such a page. List in g 2 .3 Sa m ple ASP Er r or Pa ge Usin g t h e ASPEr r or Obj e ct
Er r or
An er r or has occur r ed!
Descr i pt i on
Number
Cat egor y
Fi l e
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Using t his obj ect for debugging and t racing is ext rem ely sim ple. All you need t o do is include t he page at t he t op of t he ASP page t hat you want t o t rack, inst ant iat e an inst ance of t he obj ect in your ASP page, enable it , and t hen call t he Pr i nt m et hod t o out put your own debugging inform at ion. When you’re finished, call t he End m et hod t o display t he collect ion inform at ion. Finally, set it equal t o Not hi ng t o dest roy it . Anot her nice feat ure of t his obj ect is t hat it can be enabled and disabled
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
at will. I f you t ossed in a few Debug. Pr i nt calls for t est ing and did not want t hem out put for a dem o, for exam ple, you could sim ply disable t he debug obj ect on t hat page t o st op t he out put from appearing inst ead of m anually rem oving all t he lines t hat reference it . As an addit ional guide, t ake a look at List ing 2.5, which shows an exam ple ASP page where t he debug obj ect t hat you j ust built is being used. List in g 2 .5 Sa m ple ASP Pa ge Usin g clsD e bu g ( D e bugTe st .a sp)
i nput t ype=" submi t " name=" bt nSubmi t 2" i d=" bt nSubmi t 2" >
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 4 .2 5 Tr a ppin g a Spe cific Ex ce pt ion Type ( Visua l Ba sic .N ET)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Globa l Ex ce pt ion H a n dlin g You can’t debug a problem if you don’t know t hat it exist s. Aft er you t ake your web applicat ion live, you are no longer t he only one who is using it ( hopefully) , so you need an effect ive plan t o t rack except ions when t hey occur while ot hers are surfing your sit e. A great way t o do t his is t o im plem ent an except ion handler at t he applicat ion level. This will allow you t o consolidat e t he logging and not ificat ion part s of your except ion handling in one convenient place. As you’ll see from t he code exam ples t hat follow, your global except ion handler can handle bot h specific except ions t hat you t rap in your code and generic unhandled except ions. Aft er your global except ion handler has done it s work, you’ll want t o redirect t he users of your websit e t o a friendly page t hat t ells t hem t hat som et hing has gone wrong, and t hen provide t hem wit h cust om er support inform at ion as well as a link back t o your web applicat ion’s hom e page.
I m ple m e n t in g t h e Applica t ion _ Er r or Eve n t H a n dle r The Ht t pAppl i cat i on class in t he Syst em . Web nam espace im plem ent s an Er r or event handler. This should not be confused wit h t he Ht t pAppl i cat i onSt at e class, which cont ains t he definit ion for t he Appl i cat i on obj ect t hat you use in a t ypical ASP.NET page ( see t he .NET fram ework docum ent at ion for m ore det ail on t he differences bet ween t hese t wo classes) .You can im plem ent t his event handler in t he global.asax file as shown in List ings 4.26 and 4.27. List in g 4 .2 6 Applica t ion _ Er r or Eve n t H a n dle r
voi d Appl i cat i on_Er r or ( obj ect sender , Event Ar gs e) { / / get r ef er ence t o t he sour ce of t he except i on chai n Except i on ex = Ser ver . Get Last Er r or ( ) . Get BaseExcept i on( ) ; / / l og t he det ai l s of t he except i on and page st at e t o t he / / Wi ndows 2000 Event Log Event Log. Wr i t eEnt r y( " Test Web" , " MESSAGE: " + ex. Message + " \ nSOURCE: " + ex. Sour ce + " \ nFORM: " + Request . For m. ToSt r i ng( ) + " \ nTARGETSI TE: " + ex. Tar get Si t e +
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
" \ nQUERYSTRI NG: " + Request . Quer ySt r i ng. ToSt r i ng( ) + " \ nSTACKTRACE: " + ex. St ackTr ace, Event LogEnt r yType. Er r or ) ; / / I nser t opt i onal emai l not i f i cat i on her e. . . }
List in g 4 .2 7 Applica t ion _ Er r or Eve n t H a n dle r ( Visua l Ba sic .N ET)
Sub Appl i cat i on_Er r or ( sender As Obj ect , e As Event Ar gs) '
get r ef er ence t o t he sour ce of t he except i on chai n
Di m ex As Except i on = Ser ver . Get Last Er r or ( ) . Get BaseExcept i on( ) '
l og t he det ai l s of t he except i on and page st at e t o t he
'
Wi ndows 2000 Event Log
Event Log. Wr i t eEnt r y( " Test Web" , _ " MESSAGE: " & ex. Message & _ " \ nSOURCE: " & ex. Sour ce & _ " \ nFORM: " & Request . For m. ToSt r i ng( ) & _ " \ nQUERYSTRI NG: : " & Request . Quer ySt r i ng. ToSt r i ng( ) & _ " \ nTARGETSI TE: " & ex. Tar get Si t e & _ " \ nSTACKTRACE: " & ex. St ackTr ace, _ Event LogEnt r yType. Er r or ) ' I nser t opt i onal emai l not i f i cat i on her e. . . End Sub
First , you have t o be sure t o set a reference t o t he Syst em .Diagnost ics nam espace. You’ll use t he Event Log class in t his nam espace t o writ e except ion det ails t o t he Windows 2000 event log. I nside t he Appl i cat i on_Er r or event handler, you declare an Except i on obj ect and init ialize it t hrough a call t o Ser ver . Get Last Er r or ( ) . Get BaseExcept i on( ) . The Get Last Er r or ( ) m et hod of t he Ser ver obj ect sim ply ret urns a reference t o a generic Ht t pExcept i on. This is a wrapper t hat was placed around t he original except ion when it was passed from your ASP.NET page t o t he Appl i cat i on_Er r or event . To get access t o t he original except ion, you need t o call it s Get BaseExcept i on( ) m et hod. This will yield t he original except ion inform at ion, regardless of how m any layers have been added t o t he except ion t ree.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Next , you m ake a call t o t he Wr i t eEnt r y( ) m et hod of t he Event Log class. There are several overloaded signat ures for t his m et hod.You can read m ore about how t o leverage t he Windows 2000 event log in Chapt er 8,“ Leveraging t he Windows 2000 Event Log.” The im plem ent at ion t hat we chose t o use here accept s t hree param et ers. The first param et er is t he source of t he error. I t appears in t he Source field of t he Windows 2000 event log viewer. The second param et er is t he log dat a it self.You can see t hat we have added a lot of inform ation t o help t rack down what caused t he except ion, including t he except ion m essage, t he except ion source, t he cont ent s of t he For m collect ion, t he cont ent s of t he Quer ySt r i ng collect ion, t he nam e of t he m et hod t hat generat ed t he error ( Tar get Si t e) , and a com plet e st ack t race. Not e t hat t he st ack t race cont ains t he nam e of t he file t hat was t he source of t he except ion. However, it st rips off t he cont ent s of t he query st ring—hence t he need t o specifically include it previously. The t hird and final param et er t o t he Wr i t eEnt r y( ) m et hod is an enum erat ion of t ype Event LogEnt r yType. We chose t o use t he Er r or elem ent of t he enum erat ion. At t he end of t he event handler, we insert ed a com m ent block where you can opt ionally put code t o em ail t he except ion inform at ion t o your I T support st aff. Discussion of t he different m essaging paradigm s in t he .NET fram ework is beyond t he scope of t his book. Aft er t he Appl i cat i on_Er r or event has com plet ed it s work, it aut om at ically redirect s t he user of your web applicat ion t o your cust om error page ( which you will set up in t he next sect ion) . Opt ionally, however, you can use t he Ser ver . Cl ear Er r or ( ) m et hod aft er you have logged t he except ion and redirect your user using t he Ser ver . Execut e( ) m et hod, specifying t he page t hat you want t o load in t he user’s browser. The code t hat you have j ust im plem ent ed will capt ure all unhandled except ions t hat occur in your web applicat ion. I f you need t o do som e cleanup in t he event of an except ion and you im plem ent st ruct ured except ion handling inside your ASP.NET page, you can st ill leverage t he global except ion handler. List ings 4.28 and 4.29 present exam ples of how you would do it . List in g 4 .2 8 Th r ow ing a H a n dle d Ex ce pt ion
pr ot ect ed voi d but t on1_cl i ck( obj ect sender , Event Ar gs e) { try { / / do some compl ex st uf f
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
/ / gener at e your f i ct i onal except i on i nt x = 1; i nt y = 0; i nt z = x / y; } cat ch( Di vi deByZer oExcept i on ex) { / / put cl eanup code her e t hr ow( ex) ; } }
List in g 4 .2 9 Th r ow ing a H a n dle d Ex ce pt ion ( Visua l Ba sic .N ET)
Pr ot ect ed Sub but t on1_cl i ck( sender As Obj ect , e As Event Ar gs) Tr y '
do some compl ex st uf f
'
gener at e your f i ct i onal except i on
Di m x As I nt eger = 1 Di m y As I nt eger = 0 Di m z As I nt eger = x / y Cat ch ex As Di vi deByZer oExcept i on '
put cl eanup code her e
Thr ow( ex) End Tr y End Sub
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
The code in t hese list ings defines a web form wit h a t ext box and a but t on. When you click t he but t on, it fires t he but t on1_cl i ck event handler. I n t he event handler, you would do processing as usual. For t he purposes of t his dem onst rat ion, however, you int ent ionally generat e a Di vi deByZer oExcept i on. This t akes you t o t he cat ch block. Here, you can perform any page- specific cleanup code before calling t hr ow( ex) t o pass your except ion t o t he global except ion handler t o be logged t o t he Windows 2000 event log. When t he global except ion handler is finished logging t he error, t he def aul t r edi r ect at t ribut e t hat you set in your config.web file ( discussed in t he next sect ion) t akes over, and you are redirect ed t o t he error.aspx page t o display your friendly m essage t o t he user of your web applicat ion.
Se t t in g Up t h e Cu st om Er r or Pa ge The first st ep in set t ing up a cust om error page is t o m odify your config.web file t o rout e t he users of your web applicat ion t o a friendly error page if an except ion occurs. I t helps t o boost users’ confidence in your sit e when it can recover gracefully from t he unexpect ed. Add t he code in List ing 4.30 t o t he config.web file of your web applicat ion. List in g 4 .3 0 Adding t h e < cu st om e r r or s> Ta g t o Your Config.w e b File
Not e t hat your config.web file m ight already have a t ag, so you m ight only need t o m odify t he exist ing one. The mode at t ribut e of t he t ag has t hree set t ings: On, Of f , and Remot eOnl y. I f t he m ode is On, users will always be redirect ed t o t he cust om error page specified by t he def aul t r edi r ect at t ribut e if an unhandled except ion occurs. I f t he m ode is Of f , t he det ails of any except ion t hat occurs will be shown t o t he user in t he browser. The Remot eOnl y m ode is a hybrid of t he t wo ot her m odes. I f you are browsing your web applicat ion while sit t ing at t he web server it self, it behaves like t he Of f m ode. All ot her browsers of t he sit e will get t he behavior of t he On m ode. I f no def aul t r edi r ect at t ribut e is set , a default ASP.NET “ friendly, yet not so friendly” m essage will be displayed t o t he user when except ions occur. Next , you need t o build t he cust om error page ( error.aspx) referenced in t he config.web file. This is j ust an ordinary ASP.NET page t hat includes helpful inform at ion for t he user of your web applicat ion if an error occurs. An ext rem ely sim ple exam ple is t he one in List ing 4.31.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 4 .3 1 Sim ple Cu st om Er r or Pa ge
My web appl i cat i on: Er r or page
An unexpect ed er r or occur r ed i n t he appl i cat i on. Pl ease cont act cust omer ser vi ce at ( 800) 555- 5555. Or , you can cl i ck her e t o go back t o t he homepage. Thank you f or your pat i ence.
Su m m a r y This chapt er covered a t rem endous am ount of ground. I t st art ed off wit h a discussion of code part it ioning and how it helps t o reduce bugs t hat are caused by failure t o updat e repet it ive code. The int roduct ion of code- behind classes helps you t o bet t er separat e your user int erface logic from your business logic. Leveraging user cont rols enables you t o reuse pieces of user int erface code m uch m ore efficient ly t han using include files in t radit ional ASP web applicat ions. ASP.NET cont inues t o support and encourage t he use of business obj ect s t o encapsulat e frequent ly used business logic in your web applicat ions Next , t he chapt er m oved on t o cont rol- of- flow guidelines t o help you prevent bugs from happening in t he first place. We covered how Swit ch and Case const ruct s are oft en superior t o m ult iple I f st at em ent s. The im port ance of a single exit point t o bot h funct ions and loops was also st ressed. This was followed wit h a discussion of when and how t o use st ruct ured except ion handling in your ASP.NET web applicat ions. We rounded out t he chapt er wit h a discussion on how t o im plem ent a global except ion handler t o log bot h unhandled except ions in your ASP.NET web applicat ions and handled except ions t hat you st ill want t o be logged. I n t his discussion, you were int roduced t o t he t ag in t he config.web file, and you learned how it is used t o specify a cust om error page t hat t he user will be redirect ed t o in t he event of an error. The next chapt er discusses condit ional com piling and shows how it enables you t o t oggle bet ween debug and product ion code quickly and easily.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Pa r t I I : ASP.N ET D e bu ggin g Tools ASP.NET Debugging Tools
5 Condit ional Com piling 6 Tracing 7 Visual St udio .NET Debugging Environm ent 8 Leveraging t he Windows 2000 Event Log
Ch a pt e r 5 . Con dit ion a l Com pilin g
CONDI TI ONAL COMPI LI NG I S ARGUABLY ONE OF t he great est debugging t ools available t o any program m er. This chapt er discusses what condit ional com piling is, t ells how it works, and shows what it can provide for you in t erm s of debugging your ASP.NET applicat ions.
W h a t I s Con dit ion a l Com pilin g? Condit ional com piling is a very basic concept t hat enables you t o do som e pret t y powerful t hings. Basically, condit ional com piling enables you t o com pile part s of your code based on a cert ain condit ion defined at com pile t im e. Generally, t his is used if you have a debugging funct ion t hat you do not want t o include in your release build. Or, you m ight have a funct ion t hat you want t wo versions of: one for your debugging and one for a release. The debug version m ight be lit t ered wit h out put st at em ent s or ot her code t hat would be t oo slow t o execut e in a release environm ent . Wit h condit ional com piling, you could creat e t wo versions of t he funct ion and flip t he swit ch on which one should be com piled in your program , depending on it s environm ent . I n t he .NET fram ework, t here are t wo ways t o accom plish t his t ype of condit ional com pilat ion. One m et hod uses funct ion at t ribut es t o t ag t he funct ion as condit ionally com piled. The second m et hod involves using preprocessing direct ives t o t ell t he com piler at com pile t im e which funct ions t o include and which funct ions t o rem ove.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Con dit ion a l Com pilin g w it h Fu n ct ion At t r ibu t e s First t ake a look at condit ional com piling using at t ribut es. List ing 5.1 is a program list ing in C# t hat uses condit ional com piling via funct ion at t ribut es. List in g 5 .1 Condit iona lly Com pile d Code ( C# ) usi ng Syst em; usi ng Syst em. Di agnost i cs; namespace WebAppl i cat i on7 { publ i c cl ass WebFor m1 : Syst em. Web. UI . Page { publ i c WebFor m1( ) { Page. I ni t += new Syst em. Event Handl er ( Page_I ni t ) ; } pr ot ect ed voi d Page_Load( obj ect sender , Event Ar gs e) { CondCl ass cc = new CondCl ass( ) ; g cc. I AmHer e( ) ; Response. Wr i t e( " Am I her e? " + cc. AmI Her e( ) ) ; } pr ot ec t ed voi d Page_I ni t ( obj ect sender , Event Ar gs e) { I ni t i al i zeComponent ( ) ; } pr i vat e voi d I ni t i al i zeComponent ( ) { t hi s. Load += new Syst em. Event Handl er ( t hi s. Page_Load) ; } } } publ i c cl ass CondCl ass { St r i ng st r ; [ Condi t i onal ( " DEBUG" ) ] publ i c voi d I AmHer e( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
{ st r = " I am her e! " ; } publ i c St r i ng AmI Her e( ) { r et ur n st r ; } } List ing 5.2 is t he sam e program writ t en Visual Basic .NET. List in g 5 .2 Condit iona lly Com pile d Code ( Visua l Ba sic .N ET) I mpor t s Syst em I mpor t s Syst em. Di agnost i cs Publ i c Cl ass WebFor m1 I nher i t s Syst em. Web. UI . Page Di m Wi t hEvent s WebFor m1 As Syst em. Web. UI . Page Sub New( ) WebFor m1 = Me End Sub Pr i vat e Sub I ni t i al i zeComponent ( ) End Sub Pr ot ect ed Sub WebFor m1_Load( ByVal Sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Di m cc As CondCl ass = New CondCl ass( ) cc. I AmHer e( ) Response. Wr i t e( " Am I her e?
" + cc. AmI Her e( ) )
End Sub Pr ot ect ed Sub WebFor m1_I ni t ( ByVal Sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) I ni t i al i zeComponent ( ) End Sub End Cl ass
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Publ i c Cl ass CondCl ass Di m st r As St r i ng
Publ i c Sub I AmHer e( ) st r = " I am her e! " End Sub Publ i c Funct i on AmI Her e( ) As St r i ng AmI Her e = st r End Funct i on End Cl ass Now you’ll exam ine what is going on in t hese code snippet s. The first t hing t hat you will need t o do in eit her language is t o “ im port ” t he Syst em .Diagnost ics nam espaces. I n Visual Basic .NET, you use t he I mpor t s keyword; in C# , you use t he using keyword. I n each of t hese pieces of code, we have creat ed a class nam ed CondCl ass t hat cont ains a st ring and t wo funct ions: I AmHer e and AmI Her e. Calling I AmHer e set s t he st ring in t he class t o “ I am here! ” . Ot herwise, t hat part icular st ring is em pt y.You will not ice t hat , in bot h code snippet s, t he Condi t i onal at t ribut e is used wit h t he I AmHer e funct ion. Not ice t he different placem ent , depending on t he language you are using. The condit ion in which t his funct ion will be com piled is whet her DEBUG is defined in t he proj ect propert ies. I n a debug build, t his is always t he case. I n a release build, t his is never t he case. I n t he WebFor m1_Load/ Page_Load m et hod, you will not ice t hat an inst ance of your CondCl ass obj ect is inst ant iat ed, and t hen bot h t he I AmHer e and AmI Her e m et hods are called. Then a Response. Wr i t e is called t o see if t he st ring in t he obj ect has been set by t he call t o I AmHer e. I f you’re com piling in debug m ode, t he sym bol DEBUG has been defined by t he default set t ings of t he proj ect , so t he st ring will be set and t he out put will show “ Am I here? I am here! ” . I f you com pile in release m ode, you will see only t he “ Am I here?” st ring—t he I AmHer e funct ion will not be called because it has not been com piled int o t he applicat ion due t o t he Condi t i onal failing. I f you are com piling from t he com m and line, you will need t o define t he DEBUG sym bol yourself. This can be done wit h t he / d swit ch. I n t his case, it would look like / d: DEBUG. Not e t hat you can use any sym bol t hat you choose inst ead of DEBUG.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you are com piling using t he Visual St udio .NET I DE, you can change bet ween RELEASE and DEBUG builds wit h t he Proj ect Propert ies dialog box.You can access t his from t he Build m enu under Configurat ion Manager.
Con dit ion a l Com pilin g w it h Pr e pr oce ssor D ir e ct ive s Now you’ll t ake a look at t he second way t o achieve condit ional com piling t hrough preprocessor direct ives. List ings 5.3 and 5.4 show t he sam e program in C# and Visual Basic .NET, respect ively. List in g 5 .3 Condit iona l Com pilin g w it h Pr e pr oce ssor D ir e ct ive s ( C# ) #def i ne MYDEBUG usi ng Syst em; namespace WebAppl i cat i on7 { publ i c cl ass WebFor m1 : Syst em. Web. UI . Page { publ i c WebFor m1( ) { Page. I ni t += new Syst em. Event Handl er ( Page_I ni t ) ; } pr ot ect ed voi d Page_Load( obj ect sender , Event Ar gs e) { CondCl ass cc = new CondCl ass( ) ; cc. I AmHer e( ) ; Response. Wr i t e( " Am I her e? " + cc. AmI Her e( ) ) ; } pr ot ect ed voi d Page_I ni t ( obj ect sender , Event Ar gs e) { I ni t i al i zeComponent ( ) ; } pr i vat e voi d I ni t i al i zeComponent ( ) { t hi s. Load += new Syst em. Event Handl er ( t hi s. Page_Load) ; } }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
} publ i c cl ass CondCl ass { St r i ng st r ; publ i c voi d I AmHer e( ) { #i f MYDEBUG st r = " I am her e! " ; #endi f } publ i c St r i ng AmI Her e( ) { r et ur n st r ; } } List in g 5 .4 Condit iona l Com pilin g w it h Pr e pr oce ssor D ir e ct ive s ( Visu a l Ba sic .N ET) #Const MYDEBUG = 1 Publ i c Cl ass WebFor m1 I nher i t s Syst em. Web. UI . Page
Di m Wi t hEvent s WebFor m1 As Syst em. Web. UI . Page Sub New( ) WebFor m1 = Me End Sub Pr i vat e Sub I ni t i al i zeComponent ( ) End Sub
Pr ot ec t ed Sub WebFor m1_Load( ByVal Sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Di m cc As CondCl ass = New CondCl ass( ) cc. I AmHer e( )
New Riders - Debugging ASP.NET
Res ponse. Wr i t e( " Am I her e?
m ade by dot net er@t eam fly
" + c c. AmI Her e( ) )
End Sub Pr ot ec t ed Sub WebFor m1_I ni t ( ByVal Sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) I ni t i al i zeComponent ( ) End Sub End Cl ass
Publ i c Cl ass CondCl ass Di m st r As St r i ng Publ i c Sub I AmHer e( ) #I f MYDEBUG Then st r = " I am her e! " #End I f End Sub Publ i c Funct i on AmI Her e( ) As St r i ng AmI Her e = st r End Funct i on End Cl ass The sam e class wit h t he sam e funct ionalit y is provided. However, t his version of t he code works a bit different ly. First , we’ll discuss what preprocessor direct ives are. Sim ply put , preprocessor direct ives are com m ands em bedded in your code t hat are int erpret ed by t he com piler at com pilat ion t im e and t hat will influence it s behavior as it com piles your code. I n t his inst ance, you are using t he #I f . . . Then. . . #End I f / #i f . . . #endi f and t he #Const / #def i ne direct ives. #Const in Visual Basic .NET and #def i ne in C# define condit ional com piler const ant s. These can be t hought of as variable const ant s in eit her Visual Basic .NET or C# , but t hese com piler const ant s are known t o t he com piler only. They cannot be referenced in your program like a Visual Basic .NET or a C# variable const ant . I n bot h versions, you will see t hat a const ant known as MYDEBUG is defined using each language’s m et hod, as described. I n Visual Basic .NET, t he #Const declarat ion m ust com e before any nam espace im port s or any program code for it t o be valid.You can
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
see t hese used in t he previous exam ples. I n t he Visual Basic .NET list ing, t he line looks like #Const MYDEBUG. I n t he C# exam ple, it is writ t en as #def i ne MYDEBUG. These const ant s are used in conj unct ion wit h t he #I f . . . Then. . . #End I f direct ives in Visual Basic .NET and t he #i f . . . #endi f direct ives in C# . I n eit her case, t hese t ags are wrapped around t he st at em ent s t hat you want t o be included only if t he const ant t hat you choose has been defined. I n t he previous sam ple, t hese t ags were put around t he cont ent s of t he I AmHer e funct ion. I f you keep t he const ant in place at t he t op of your code, t hen t he cont ent s of what is in bet ween t he t ags will be com piled in, and you will get t he “ Am I here? I am here! ” out put . I f you rem ove t he const ant , t he funct ion’s int ernals will not be com piled in, and you will get only t he “ Am I here?” out put because t he int ernal st ring in t he class will not be set during t he I AmHer e call. List ing 5.5 shows t he appropriat e lines in C# . List in g 5 .5 Usa ge of # if...# e n dif ( C# ) publ i c voi d I AmHer e( ) { #i f MYDEBUG st r = " I am her e! " ; #endi f } List ing 5.6 dem onst rat es t he sam e concept in Visual Basic .NET. List in g 5 .6 Usa ge of # I f... Th e n...# End I f ( Visu a l Ba sic .N ET) Publ i c Sub I AmHer e( ) #I f MYDEBUG Then st r = " I am her e! " #End I f End Sub I f you are using C# , you m ay also use operat ors t o t est whet her an it em has been defined.You can use t he following operat ors t o evaluat e m ult iple sym bols: = = ( equalit y) , ! = ( inequalit y) , && ( and) , and | | ( or) .You can group sym bols and operat ors wit h parent heses.
Ot h e r Pr e pr oce ssor D ir e ct ive s A few ot her preprocessor direct ives are available in C# t hat are not found in Visual Basic .NET. This sect ion discusses t hese addit ional direct ives, t ells how t hey work, and shows what t hey can provide for you.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
# u n de f #undef is t he exact opposit e of #def i ne. I t rem oves t he definit ion of a preprocessor const ant . List ing 5.7 shows an exam ple of how it is used. List in g 5 .7 Using # unde f #def i ne MYDEBUG publ i c voi d MyFunct i on( ) { #i f MYDEBUG Response. Wr i t e( " Hel l o" ) ; #endi f #undef MYDEBUG #i f MYDEBUG Response. Wr i t e( " You won' t see me! " ) ; #endi f } I f you called t he MyFunct i on funct ion, you would get an out put of Hel l o but not You won' t see me! . Because MYDEBUG has been defined, t he fir st Res pons e. Wr i t e w ill be com piled in and execut ed. However, im m ediat ely aft erward, t he MYDEBUG sym bol is undefined, so t he second #i f check will fail; t he second Response. Wr i t e will not be com piled int o t he program and, t herefore, will not be execut ed. This can be useful if you need t o t em porarily rem ove a line or t wo inside a debugging funct ion.You could sim ply #undef t he sym bol for t he lines t hat you want t o execut e and t hen again #def i ne t he sym bol where you want t o rest art t he execut ion of t he funct ion.
# w a r n in g a n d # e r r or #war ni ng and #er r or are very sim ilar, so t hey are dem onst rat ed t oget her here. These t wo direct ives enable you t o display a m essage t o t he user in t he out put window as t he program is com piling. This m essage can have eit her a warning st at us or an error st at us. List ing 5.8 shows an exam ple of each. List in g 5 .8 # w a r n in g a n d # e r r or Ex a m ple #def i ne MYDEBUG
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
#i f MYDEBUG && ! DEBUG #er r or Bot h MYDEBUG and RELEASE ar e def i ned! ! #el i f MYDEBUG #war ni ng WARNI NG - MYDEBUG i s def i ned! #endi f I n t his exam ple, if you were in a debug build wit h MYDEBUG defined, you would sim ply see a warning t elling you t hat MYDEBUG was defined while com piling your program . This is j ust a handy hint . However, if you swit ched your build configurat ion t o a release build and built t he program , you would get a com piler error wit h t he t ext st at ed because bot h MYDEBUG and RELEASE were defined and DEBUG was not . This would be very useful t o ensure t hat you do not com pile any of your own debugging code int o your release applicat ion.
Su m m a r y Condit ional com piling is ext rem ely easy t o im plem ent , wit h t rem endously powerful result s. This chapt er looked at t wo different ways t o accom plish a sim ilar t ask: t hrough preprocessor direct ives and via funct ion at t ribut es. The key difference here is t hat by using t he Condi t i onal funct ion at t ribut e, t he debug code is com piled int o t he applicat ion; however, it is never execut ed. By using t he preprocessor direct ives of t his sect ion, t he code is never com piled int o t he applicat ion—t herefore, it could never be execut ed. Next , you looked at som e ot her preprocessor com piler direct ives and how t hey can provide addit ional inform at ion t o aid you in debugging your ASP.NET applicat ions. By adding som e condit ional com piling t o your code, you will be able t o add a robust debugging int erface t o your applicat ion and im m ediat ely rem ove it from t he product ion- level out put at t he proverbial flip of a swit ch. I n t he next chapt er, you will st art t o look at t he built - in .NET t racing facilit ies and how t hey can help you explore what is happening inside your applicat ion as it is running, bot h in a debug and a product ion environm ent .
Ch a pt e r 6 . Tr a cin g
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
ONE OF THE MOST COMMON WAYS t o debug t radit ional ASP web applicat ions is t o use t rust y calls t o Response. Wr i t e. This enables you t o creat e checkpoint s in your code t o view t he cont ent s of variables in t he browser. This approach had several drawbacks, however. The out put creat ed by calls t o Response. Wr i t e appears wherever t he call is m ade in t he code. I t som et im es becom es a chore t rying t o int erpret your debugging inform at ion because it is st rewn all over t he page in t he browser. The form at t ing of your page is also affect ed. When you are finished debugging your web applicat ion using calls t o Response. Wr i t e, you are t hen faced wit h t he daunt ing t ask of st ripping out all t his debug code. Because you are using t he sam e t ype of code bot h t o debug and t o creat e valid out put , you m ust carefully scan each of your ASP pages t o m ake sure t hat you rem ove all t he Response. Wr i t e calls t hat pert ain t o debugging. When your ASP pages get t o be hundreds of lines long, t his can be a real pain. To address t his issue, ASP.NET im plem ent s t he Tr aceCont ext class. The Tr aceCont ext class solves all t hese issues and offers m any m ore feat ures. Let ’s t ake a look at som e of t he ways t hat t he Tr aceCont ext class can help you debug your ASP.NET web applicat ions m ore effect ively.
Con figu r a t ion To use t racing in your ASP.NET web applicat ion, you need t o enable it . This can be done at eit her t he page level or t he applicat ion level.
Pa ge - Le ve l Con figu r a t ion Enabling t racing at t he page level ent ails adding t he Tr ace at t ribut e t o t he @Page direct ive, like t his:
I f t he Tr ace at t ribut e has a value of t r ue, t racing inform at ion will be displayed at t he bot t om of your ASP.NET page aft er t he ent ire page has been rendered. Alt ernat ively, you can include t he Tr aceMode at t ribut e. The value t hat you assign t o t his at t ribut e det erm ines t he display order of t he t race result s. The possible values are Sor t ByTi me and Sor t ByCat egor y. Sor t ByTi me is t he default if you do not specify t he Tr aceMode at t ribut e.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Applica t ion - Le ve l Con figu r a t ion Several t racing opt ions are available at t he applicat ion level. These set t ings are specified using t he XML elem ent in t he sect ion of t he web.config file. The at t ribut es available t o you are shown in Table 6.1. Tabl e 6. 1. Tr aci ng Opt i ons
enabl ed
I s t r ue if t racing is enabled for t he applicat ion; ot her– wise, is f al se. The default is f al se.
pageOut put
I s t r ue if t race inform at ion should be displayed bot h on an applicat ion’s pages and in t he .axd t race ut ilit y; ot herwise, is f al se. The default is f al se. Not e t hat pages t hat have t racing enabled on t hem are not affect ed by t his set t ing.
r equest Li mi t Specifies t he num ber of t race request s t o st ore on t he server. The default is 10. t r aceMode
I ndicat es whet her t race inform at ion should be displayed in t he order it was processed, Sor t ByTi me, or alphabet ically by user- defined cat egory, Sor t ByCat egor y. Sor t ByTi me is t he default .
l ocal Onl y
I s t rue if t he t race viewer ( t race.axd) is available only on t he host Web server; ot herwise, is false. The default is t rue.
An exam ple of a t race ent ry in t he web.config file m ight look like List ing 6.1. List in g 6 .1 Applica t ion - Le ve l Tr a ce Configu r a t ion in t h e w e b.con fig File
Even t hough t his exam ple uses all t he available at t ribut es, none of t hem is required. Also not e t hat page- level configurat ion set t ings overrule applicat ion- level set t ings. For inst ance, if t racing is disabled at t he applicat ion level but is enabled at t he page level, t race inform at ion will st ill be displayed in t he browser. The r equest Li mi t at t ribut e set s a lim it on how m any page request s are kept in t he t race log. This prevent s t he logs from get t ing t oo large. Set t ing t he l ocal Onl y at t ribut e t o t r ue enables you t o view t race inform at ion if you are logged int o t he server locally, but rem ot e users will not see anyt hing. That way,
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
you can enable t racing t o debug a problem , and t he users of your websit e will never be t he wiser.
Tr a ce Ou t pu t Now t hat you’ve heard so m uch about configuring ASP.NET t racing, what exact ly does it provide? Essent ially, t he t race out put generat ed by t he Tr aceCont ext obj ect and displayed at t he bot t om of your rendered ASP.NET page cont ains several sect ions. Each of t hese sect ions is out lined here, along wit h explanat ions. Because t he t ot al out put is t oo large t o be viewed in one screenshot , a screenshot is included for each individual sect ion of t he t race out put . Lat er in t he chapt er, when we discuss writ ing m essages t o t he t race out put , you’ll get a chance t o see what several sect ions put t oget her look like.
Re qu e st D e t a ils The Request Det ails sect ion cont ains six pieces of inform at ion, out lined in Table 6.2. Tabl e 6. 2. Request Det ai l s
Item
Description
Session I d
Unique ident ifier for your session on t he server
Tim e of request
The t im e ( accurat e t o t he second) t hat t he page request was m ade
Request encoding The encoding of t he request—for exam ple, Unicode ( UTF – 8) Request t ype
GET or POST
St at us code
The st at us code for t he request—for exam ple, 200
Response
The encoding of t he response—for exam ple, Unicode ( UTF – 8)
encoding You can see it all put t oget her in Figure 6.1. Figur e 6 .1 . Re qu e st D e t a ils se ct ion of t r a ce ou t pu t .
Tr a ce I n for m a t ion The Trace I nform at ion sect ion cont ains t he various t race m essages and warnings t hat bot h you and t he ASP.NET engine add t o t he t race out put . By default , t he
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
ASP.NET engine adds m essages for when any event s begin or end, as wit h Pr eRender and SaveVi ewSt at e. The fields displayed for each it em are Cat egory, Message, t im e int erval from t he beginning of page processing, and t im e int erval from t he last t race out put it em . The order in which t he cont ent s of t he Trace I nform at ion sect ion appear is det erm ined by eit her t he Tr aceMode at t ribut e of t he @Page direct ive or t he Tr aceMode propert y of t he Tr aceCont ext class. Figure 6.2 shows an exam ple of t he Trace I nform at ion sect ion. Figur e 6 .2 . Tr a ce I n for m a t ion se ct ion of t r a ce ou t put .
Con t r ol Tr e e The Cont rol Tree sect ion list s all t he elem ent s on your ASP.NET page in a hierarchical fashion. This enables you t o get a feeling for which cont rols cont ain ot her cont rols, helping you t o decipher cont rol scope and ownership issues. The fields displayed for each it em are Cont rol I d,Type, Render Size Byt es, and Viewst at e Size Byt es. Figure 6.3 shows an exam ple of t he Cont rol Tree sect ion. Figur e 6 .3 . Con t r ol Tr e e se ct ion of t r a ce out pu t .
Cook ie s Colle ct ion The Cookies Collect ion sect ion list s all t he cookies t hat are associat ed wit h your ASP.NET web applicat ion. The fields displayed for each it em are Nam e,Value, and Size. Figure 6.4 shows an exam ple of t he Cookies Collect ion sect ion. Figur e 6 .4 . Cook ie s Colle ct ion se ct ion of t r a ce ou t put .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
H e a de r s Colle ct ion The Headers Collect ion sect ion list s all t he HTTP headers t hat are passed t o your ASP.NET page. The fields displayed for each it em are Nam e and Value. Figure 6.5 shows an exam ple of t he Headers Collect ion sect ion. Figur e 6 .5 . H e a de r s Colle ct ion se ct ion of t r a ce ou t put .
For m Colle ct ion The Form Collect ion sect ion is displayed only if your ASP.NET page includes a web form and you have already subm it t ed it back t o t he server. I t cont ains t wo im port ant pieces of inform at ion. First , it displays t he page’s VI EWSTATE. This is t he condensed represent at ion of t he st at e of each of t he cont rols on t he web form . Below t he VI EWSTATE it em is a list ing of each cont rol in t he Form Collect ion sect ion, along wit h it s value. The fields displayed for each it em are Nam e and Value. Figure 6.6 shows an exam ple of t he Form Collect ion sect ion. Figur e 6 .6 . For m Colle ct ion se ct ion of t r a ce ou t pu t .
Qu e r yst r in g Colle ct ion The Queryst ring Collect ion sect ion is displayed only if your ASP.NET page has Quer yst r i ng param et ers passed t o it . The fields displayed for each it em are Nam e and Value. Figure 6.7 shows an exam ple of t he Queryst ring Collect ion sect ion. Figur e 6 .7 . Qu e r yst r in g Colle ct ion se ct ion of t r a ce out pu t .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Se r ve r Va r ia ble s The Server Variables sect ion cont ains a list ing of all t he server variables associat ed wit h your ASP.NET page. A few exam ples are PATH_I NFO, REMOTE_HOST, and SCRI PT_NAME. The fields displayed for each it em are Nam e and Value. Figure 6.8 shows an exam ple of t he Server Variables sect ion ( t runcat ed because of t he large num ber of elem ent s in t he collect ion) . Figur e 6 .8 . Se r ve r Va r ia ble s se ct ion of t r a ce ou t pu t .
Se t t in g Tr a ce M e ssa ge s The Tr aceCont ext class has a fairly sim ple int erface, wit h only one const ruct or, t wo propert ies, and t wo m et hods. Of course, t hese are in addit ion t o t he st andard propert ies and m et hods inherit ed from t he Obj ect class. An inst ance of t he Tr aceCont ext class is available t o your ASP.NET pages t hrough t he Tr ace propert y of t he Page obj ect , so you will need t he const ruct or only if you want t o enable t racing in your .NET com ponent s ( discussed lat er in t his chapt er) .
Tr a ce Con t e x t Pr ope r t ie s The I sEnabl ed propert y works t he sam e way as t he Tr ace at t ribut e of t he @Page direct ive. The nice part about having t his propert y available t o you is t hat , unlike t he @Page direct ive, it can be dynam ically assigned. For inst ance, you can specify t racing t hrough a Quer yst r i ng param et er, as shown in List ings 6.2 and 6.3. List in g 6 .2 Se t t ing t he I sEna ble d Pr ope r t y D yna m ica lly ( C# )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
pr ot ect ed voi d Page_Load( obj ect Sender , Event Ar gs e) { bool t r aceFl ag = Request . Quer ySt r i ng[ " t r ace" ] ! = nul l ? t r ue : f al se; Tr ace. I sEnabl ed = t r aceFl ag; }
List in g 6 .3 Se t t ing t he I sEn a ble d Pr ope r t y D yna m ica lly ( Visua l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( Sender As Obj ect , e As Event Ar gs) Di m t r aceFl ag As Bool ean = I I F( Request . Quer ySt r i ng( " t r ace" ) _ Not hi ng, Tr ue, Fal se) Tr ace. I sEnabl ed = t r aceFl ag End Sub
These list ings set t he I sEnabl ed propert y of t he Tr ace obj ect dynam ically, based on t he presence of t he t r ace Quer yst r i ng variable. Not ice t hat no Tr ac e at t ribut e is assigned t o t he @Page direct ive. I t is int erest ing t o not e t hat even if you specify a Tr ace at t ribut e and set it t o f al se, t he I sEnabl ed propert y value st ill dict at es whet her t race inform at ion was displayed t o t he page. The real power of using t he I sEnabl ed propert y is t hat when you set it t o f al se, t he t race inform at ion not only isn’t displayed, but it also isn’t even com piled. This m eans t hat you can leave your t racing code in your ASP.NET applicat ion when you m ove it t o product ion. As long as t he I sEnabl ed propert y is set t o f al se, you will not suffer any perform ance penalt y. The Tr aceMode propert y works exact ly like t he Tr aceMode at t ribut e of t he @Page direct ive. The sam e behaviors and advant ages t hat apply t o t he I sEnabl ed propert y also exist for t he Tr aceMode propert y.
Tr a ce Con t e x t M e t h ods Only one t hing ( besides t heir nam es) different iat es t he t wo m et hods of t he Tr aceCont ext class, Wr i t e and War n: The out put generat ed by t he Wr i t e m et hod is black, while t he out put generat ed by t he War n m et hod is red. For t his reason, we will be discussing only t he Wr i t e m et hod. Just realize t hat everyt hing said about t he
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Wr i t e m et hod can also be applied t o t he War n m et hod. There are t hree overloaded versions of t he Wr i t e and War n m et hods. The first version accept s a t race m essage. The second version accept s a t race m essage and a cat egory. The t hird version accept s a t race m essage, a cat egory, and an inst ance of an Except i on class. Each of t hese is covered in m ore det ail next . Tr a ce Con t e x t .W r it e ( st r in g) The first of t he overloaded Wr i t e m et hods of t he Tr aceCont ext class accept s a single- st ring param et er. This st ring cont ains t he m essage t hat is displayed in t he Message field of t he Trace I nform at ion sect ion of t he t race out put ( as seen in Figure 6.2) . List ings 6.4 and 6.5 dem onst rat e it s use. List in g 6 .4 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing) ( C# )
pr ot ect ed voi d Page_Load( obj ect Sender , Event Ar gs e) { Tr ace. Wr i t e( " I ' m t r aci ng now" ) ; }
List in g 6 .5 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing) ( Visu a l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( Sender As Obj ect , e As Event Ar gs) Tr ace. Wr i t e( " I ' m t r aci ng now" ) End Sub
Figure 6.9 shows what t he t race out put for t he previous code looks like. Figur e 6 .9 . Vie w ing a t r a ce m e ssa ge in t he t r a ce out pu t .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Not ice t he m essage “ I ’m t racing now” t hat appears as t he t hird line it em in t he Trace I nform at ion sect ion. No cat egory was specified, so it is blank. The next overloaded version of t he Wr i t e/ War n m et hod includes t he cat egory param et er. Tr a ce Con t e x t .W r it e ( st r in g, st r in g) The second overloaded Wr i t e m et hod of t he Tr aceCont ext class t akes t wo st ring param et ers. The first param et er is t he cat egory of t he t race it em . I t appears in t he Cat egory field of t he Trace I nform at ion sect ion of t he t race out put . The second param et er is t he m essage t hat will be displayed in t he Message field, and it is t he sam e as t he single- st ring param et er in t he first overloaded Wr i t e m et hod. This is probably t he m ost likely version of t he Wr i t e m et hod t hat you will use when debugging your ASP.NET pages.You can assign cat egories t o your t race it em s, leveraging t he Tr aceMode at t ribut e of t he @Page direct ive or t he Tr aceMode propert y of t he Tr aceCont ext class t o sort t he Trace I nform at ion sect ion result s. As previously described, t his is done using t he Sor t ByCat egor y m em ber of t he Tr aceMode enum erat ion. List ings 6.6 and 6.7 dem onst rat e t he use of t his version of t he Wr i t e m et hod. List in g 6 .6 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing, st r in g) ( C# )
pr ot ect ed voi d Page_Load( obj ect Sender , Event Ar gs e) { Tr ace. Tr aceMode = Tr aceMode. Sor t ByCat egor y; Tr ace. Wr i t e( " Cat egor y 1" , " Cat egor y 1 dat a" ) ; Tr ace. Wr i t e( " Cat egor y 2" , " Cat egor y 2 dat a" ) ; Tr ace. Wr i t e( " Cat egor y 1" , " Mor e Cat egor y 1 dat a" ) ; }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 6 .7 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing, st r in g) ( Visua l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( Sender As Obj ect , e As Event Ar gs) Tr ace. Tr aceMode = Tr aceMode. Sor t ByCat egor y Tr ace. Wr i t e( " Cat egor y 1" , " Cat egor y 1 dat a" ) Tr ace. Wr i t e( " Cat egor y 2" , " Cat egor y 2 dat a" ) Tr ace. Wr i t e( " Cat egor y 1" , " Mor e Cat egor y 1 dat a" ) End Sub
Figure 6.10 shows t he t race out put for t he previous code. Figur e 6 .1 0 . Vie w ing a t r a ce m e ssa ge w it h a ca t e gor y in t he t r a ce ou t pu t .
Not ice t hat t he t race it em s are sort ed by cat egory so t hat bot h of t he cat egory 1 it em s appear t oget her, inst ead of being separat ed by t he cat egory 2 it em ( which was t he order in which t he code m ade t he calls t o t he Wr i t e m et hod) . Also, t he previous code uses t he Tr aceMode propert y of t he Tr ace obj ect t o set t he sort order.You could alt ernat ively have used t he Tr aceMode at t ribut e of t he @Page direct ive. Tr a ce Con t e x t .W r it e ( st r in g, st r in g, Ex ce pt ion ) The t hird overloaded version of t he Wr i t e m et hod t akes t hree param et ers. The first t wo param et ers m at ch up wit h t he t wo param et ers of t he previous overloaded m et hod call. For t he t hird param et er, you should pass in an obj ect inst ance of t he Except i on class or an obj ect inst ance of a class t hat inherit s from t he Except i on class.You would m ost likely use t his m et hod call when writ ing t race out put in conj unct ion wit h st ruct ured except ion handling. List ings 6.8 and 6.9 dem onst rat e
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t his concept by int ent ionally causing an except ion in a Tr y block t hat adds t o t he t race inform at ion in t he Cat ch block. List in g 6 .8 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing, st r in g, Ex ce pt ion) ( C# )
pr ot ect ed voi d Page_Load( obj ect Sender , Event Ar gs e) { i nt x = 1; i nt y = 0; try { i nt z = x / y; } cat ch( Di vi deByZer oExcept i on ex) { Tr ace. Wr i t e( " Er r or s" , " Test i ng t he l i mi t s of i nf i ni t y?" , ex) ; } }
List in g 6 .9 I m ple m e nt in g Tr a ce Con t e x t .W r it e ( st r ing, st r in g, Ex ce pt ion) ( Visu a l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( Sender As Obj ect , e As Event Ar gs) Di m x As I nt eger = 1 Di m y As I nt eger = 0 Tr y Di m z As I nt eger = x / y Cat ch ex As Over f l owExcept i on Tr ace. Wr i t e( " Er r or s" , " Test i ng t he l i mi t s of i nf i ni t y?" , ex) End Tr y End Sub
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Figure 6.11 shows t he t race out put for t he C# version of t his code. Figur e 6 .1 1 . Vie w ing a t r a ce m e ssa ge w it h a ca t e gor y a n d e x ce pt ion in for m a t ion in t h e t r a ce ou t pu t .
I n addit ion t o t he m essage t hat you specify in t he call t o t he Wr i t e m et hod, you get t he m essage from t he except ion t hat was t hrown, as well as t he nam e of t he procedure where t he except ion occurred.You can see valuable debugging inform at ion associat ed wit h t he error t hat was t hrown alongside your own cust om com m ent s, m aking it easier t o com bine t he t wo int o a solut ion t o t he bug.
Tr a ce Vie w e r I n t he “ Applicat ion- Level Configurat ion” sect ion at t he beginning of t he chapt er, we discussed t he various at t ribut es of t he XML elem ent in t he web.config file. You’ll recall t hat t he r equest Li mi t at t ribut e set s how m any page request s t o keep in t he t race log. So, now t hat you have all t hat dat a st ored in t he t race log, what do you do wit h it ? Anot her fine quest ion! The answer is t o use t he Trace Viewer t o analyze it .
Acce ssin g t h e Tr a ce Vie w e r The Trace Viewer is accessed via a special URL. I n any direct ory of your web applicat ion, you can access it by navigat ing t o t race.axd.You’ll not ice t hat t here is no t race.axd file anywhere. I nst ead, any request for t his file is int ercept ed by an Ht t pHandl er t hat is set up in eit her t he m achine.config file or your web applicat ion’s web.config file. An ent ry wit hin t he XML elem ent looks like List ing 6.10. List in g 6 .1 0 H t t pH a ndle r s Se ct ion of t he m a ch in e .con fig File
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
. . . ot her handl er ent r i es. . .
. . . ot her handl er ent r i es. . .
Wit h t his Ht t pHandl er ent ry in place, all t hat is left t o do t o use t he Trace Viewer is m ake sure t hat t he enabl ed at t ribut e of t he XML elem ent in your web.config file is set t o t r ue.
Usin g t h e Tr a ce Vie w e r The Trace Viewer uses a fairly sim ple int erface, consist ing of t wo different pages. When you first navigat e t o t he t race.axd file, you are present ed wit h t he Applicat ion Trace screen. I t cont ains a list of page request s for which t race inform at ion has been t racked. Three it em s are present in t he header of t his page. The first is a link t o clear t he current t race log. Clicking t his link reset s t racing, clearing all page request s from t he screen. The second it em in t he header is t he physical direct ory of t he ASP.NET web applicat ion. The t hird header it em is a count er t hat t ells you how m any m ore request s can be t racked before t he r equest Li mi t is reached. Aft er t hat point , t race inform at ion is not st ored for anym ore page request s unt il t he t race inform at ion is cleared by clicking t he Clear Current Trace link. The fields displayed for each page request on t he Applicat ion Trace screen are No., Tim e of Request , File, St at us Code, and Verb. I n addit ion, a link next t o each it em in t he list shows t he det ails for t hat specific page request . Figure 6.12 shows an exam ple of t he Applicat ion Trace screen of t he Trace Viewer. Figur e 6 .1 2 . Applica t ion Tr a ce pa ge of t he Tr a ce Vie w e r .
When you click one of t he View Det ails links on t he Applicat ion Trace screen, you are t aken t o t he Request Det ails screen. On t his page you will see is an exact
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
represent at ion of t he t race inform at ion t hat would be displayed at t he end of t he part icular ASP.NET page if t racing had been enabled on it . The only difference is t he large Request Det ails capt ion at t he t op of t he page. Several exam ples of t his screen have been shown in previous figures in t his chapt er, so t here is no need t o present it again.
Tr a cin g via Com pon e n t s The Page obj ect in your ASP.NET pages cont ains an inst ance of t he Tr aceCont ext class, m aking it easy t o writ e t race inform at ion from your ASP.NET page. But what if you want t o writ e t race inform at ion from wit hin a com ponent ? Luckily, t he .NET Fram ework m akes t his t ask equally easy. Let ’s t ake a look at how t his would be done. First , you need t o build your sim ple com ponent . List ings 6.11 and 6.12 present t he com ponent . List in g 6 .1 1 Com pone n t Tha t Le ve r a ge s ASP.N ET Tr a cing ( C# ) usi ng Syst em; usi ng Syst em. Web; namespace Chapt er 6 { publ i c cl ass Test Cl ass { publ i c voi d DoSt uf f ( ) { Ht t pCont ext . Cur r ent . Tr ace. Wr i t e ( " Component " , " I ' m i nsi de t he component " ) ; } } } List in g 6 .1 2 Com pone n t Tha t le ve r a ge s ASP.N ET Tr a cin g ( Visu a l Ba sic .N ET) I mpor t s Syst em I mpor t s Syst em. Web Namespace Chapt er 6 Publ i c Cl ass Test Cl ass Publ i c Sub DoSt uf f ( ) Ht t pCont ext . Cur r ent . Tr ace. Wr i t e _ ( " Component " , " I ' m i nsi de t he component " ) End Sub
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
End Cl ass End Namespace Next , com pile your com ponent using one of t he following com pile script s. The first is for C# , and t he second is for Visual Basic .NET. csc / t : l i br ar y / out : Chapt er 6. dl l / r : Syst em. Web. dl l Chapt er 6. cs or vbc / t : l i br ar y / out : Chapt er 6. dl l / r : Syst em. Web. dl l Chapt er 6. vb Finally, you can see t hat t his works by using it in an ASP.NET page. List in g 6 .1 3 Usin g Tr a ce - Ena ble d Com pon e n t in a n ASP.N ET Pa ge ( C# )
pr ot ec t ed voi d Page_Load( obj ect Sender , Event Ar gs e) { Test Cl ass t c = new Test Cl ass( ) ; t c. DoSt uf f ( ) ; }
List in g 6 .1 4 Usin g Tr a ce - Ena ble d Com pon e n t in a n ASP.N ET Pa ge ( Visua l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( Sender As Obj ect , e As Event Ar gs) Di m t c As Test Cl ass = New Test Cl ass( ) t c. DoSt uf f ( ) End Sub
When you run t his code, you’ll get result s like t hose shown in Figure 6.13. Figur e 6 .1 3 . Vie w ing t r a ce in for m a t ion w r it t e n t o t he t r a ce out pu t fr om w it h in a com pon e n t .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I nside t he Trace I nform at ion sect ion, you’ll see t he t race m essage “ I ’m inside t he com ponent ,” wit h a cat egory of Com ponent t hat was added from wit hin t he com ponent . This can be a powerful t ool for finding bugs in your ASP.NET web applicat ions.
Tips for Usin g Tr a ce I n for m a t ion Now t hat you have all t his t race inform at ion sit t ing in front of you, how do you use it t o your best advant age? Well, t hat really depends. Most of t he t race inform at ion present ed ( such as cookies, headers, and server variables) was available t o you in t radit ional ASP. I t j ust wasn’t neat ly packaged like it is in t he Trace Viewer.You can use t hat inform at ion j ust as you previously did. The t rue power of ASP.NET t racing is in t he Trace I nform at ion sect ion. I t enables you t o see when each part of your ASP.NET page is processing and det erm ine how long it t akes t o process. This can be crucial t o t he process of finding perform ance bot t lenecks in your code. I t can also help you solve m yst eries about why cert ain code is not processing correct ly. Oft en, t he code isn’t being execut ed in t he sam e order t hat you t hought it was. Or, m aybe t he code is being execut ed m ult iple t im es by accident . These nuances, which were t ough t o discover in t radit ional ASP, becom e fairly obvious when observing t he cont ent s of t he Trace I nform at ion sect ion of t he t race out put . Applicat ion- level t racing, if used properly, can great ly reduce t he am ount of t im e and effort expended on debugging your ASP.NET web applicat ions. For inst ance, you could t urn on t racing but set t he pageOut put at t ribut e of t he XML elem ent in t he web.config file t o f al se. Then you could let som e of t he pot ent ial users of your web applicat ion t ry it out .You can record lot s of inform at ion about what t hey are doing and what is going wrong wit h t heir experience, all behind t he scenes. This can help you t o det erm ine which part icular scenarios cause errors.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Su m m a r y I n t his chapt er, you t ook a det ailed look at t racing in ASP.NET.You st art ed by learning how t o configure t racing in ASP.NET, at bot h t he page level and t he applicat ion level. This ent ailed adding at t ribut es t o t he @Page direct ive and t o t he web.config file. Next , you learned about t he different sect ions t hat are included in t he t race out put at t he page level. These include t he Request Det ails,Trace I nform at ion, Cont rol Tree, Cookies Collect ion, Headers Collect ion, Form Collect ion, QuerySt ring Collect ion, and Server Variables Collect ion sect ions. Following t hat , we discussed t he prim ary player in t he ASP.NET t racing process: t he Tr aceCont ext class.You learned about it s t wo propert ies, I sEnabl ed and Tr aceMode, and you learned how t hey can be used t o cont rol t he t race out put of your ASP.NET pages t hrough t he Tr aceCont ext obj ect inst ance in t he Page class’s Tr ace propert y. The Tr aceCont ext class’s t wo m et hods, Wr i t e and War n, were discussed next . Each of t he t hree overloaded Wr i t e m et hods was explained and was correlat ed t o t he sim ilar War n m et hod, which differs only in nam e and out put appearance. We deferred t he discussion of t he const ruct or t o t he sect ion on t racing via com ponent s, lat er in t he chapt er. Then you learned how t o bot h configure and use t he Trace Viewer, as well as how it is accessed via an Ht t pHandl er t hat int ercept s request s for t he t race.axd file. Tracing in an ASP.NET web applicat ion is not j ust lim it ed t o ASP.NET pages. We also discussed how t o leverage ASP.NET t racing from wit hin com ponent s t hat your ASP.NET pages call. The chapt er wrapped up wit h a few t ips and t echniques for ut ilizing ASP.NET t racing t o it s fullest pot ent ial. I n t he next chapt er, you’ll get a t horough int roduct ion t o debugger in t he Visual St udio .NET I DE.
New Riders - Debugging ASP.NET
Ch a pt e r
7.
Visu a l
m ade by dot net er@t eam fly
St u dio
.N ET
D e buggin g
En vir on m e n t
THE ASP SCRI PT DEBUGGER THAT I S I NTEGRATED wit h t he new Visual St udio .NET I DE is, wit hout a doubt , one of t he great est enhancem ent s t o debugging from t he previous versions of ASP. Unlike t rying t o debug t radit ional ASP pages in Visual I nt erdev, t his act ually works right out of t he box! I n t his chapt er, you will be looking at all t he feat ures available for debugging in t he Visual St udio .NET I DE, how t o use t hem , and where each one is applicable for t he problem you m ight be t rying t o conquer. This will all be accom plished by building a proj ect from scrat ch in t he I DE, so w e recom m end creat ing t he proj ect on your own as it is done in t his chapt er.
I n t r odu ct ion t o Fe a t u r e s Let ’s st art out by t aking a look at t he m ost im port ant feat ures of t he Visual St udio .NET I DE debugger.You will t ake a det ailed look at all of t hese as t he chapt er progresses. Many of t hese feat ures have exist ed in t he Visual St udio 6.0 I DEs ; however, not all were previously available when debugging t radit ional ASP pages in Visual I nt erDev.
Ca ll St a ck The call st ack enables you t o display t he list of funct ions current ly called. As t he nam e im plies, t his can be im agined sim ply as a st ack. ( As funct ions are called from wit hin funct ion, which, in t urn, are called from wit hin funct ions, a st ack is creat ed.) Wit h t he call st ack viewer, you can look at t his st ack and j um p forward and backward int o t he st ack t o debug at any point in t he chain. Figure 7.1 shows t he call st ack in act ion. Figur e 7 .1 . Th e ca ll st a ck w in dow .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Com m a n d W in dow I f you have used t he Visual Basic I DE previously, t he com m and window will be quit e fam iliar t o you. The com m and window enables you t o execut e program st at em ent s separat ely from t he running program . For exam ple, if you want t o set a variable equal t o a new value, or if you want t o print t he value of a variable, or even if you want t o creat e an obj ect and call som e m et hods on it , you can do it from t his window. Figure 7.2 shows how t he com m and window can be used. Figur e 7 .2 . Th e com m a n d w in dow .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Br e a k poin t s Breakpoint s enable you t o st op t he execut ion of a program at a defined point eit her in all inst ances or based on a cert ain set of crit eria. The easiest way t o set a breakpoint is t o click in t he gray left m argin next t o t he line where you want t o st op. The I DE drops a red “ dot ” in t he m argin; when you st art t he program in debug m ode, it st ops at t hat specified posit ion. By popping up t he breakpoint window from t he debugging windows at t he bot t om of t he screen, you can see all breakpoint s current ly set in t he syst em . Figure 7.3 shows an exam ple of t he breakpoint window. Figur e 7 .3 . Th e br e a k poin t w in dow .
W a t ch W in dow The wat ch window can be used t o wat ch t he cont ent s of a variable or series of variables. This window also enables you t o change t he value of a variable, which can be quit e useful in debugging applicat ions.You can see an exam ple of t he w at ch window in Figure 7.4. Figur e 7 .4 . Th e w a t ch w indow .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Tr a cin g Tracing sim ply enables you t o writ e out a series of t ext m essages as t he program is execut ing so t hat you can see what is happening at any point during t he program ’s life cycle. This can be very useful in creat ing a log of event s t hat can be inspect ed lat er t o ensure t hat t he program is operat ing as you expect in all aspect s. Figure 7.5 shows an out put from a Debug. Tr ace st at em ent in t he out put window. Figur e 7 .5 . Tr a cin g a n d t h e ou t pu t w in dow .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
At t a chin g t o Pr oce sse s At som e point you m ight need t o at t ach t o a process running som ewhere on t he com put er and debug it from wit hin t he ASP.NET page. This could be t he ASP.NET process, aspnet _wp.exe, or anot her running service, or any ot her program running on t he server. This can be accom plished quit e easily. Under t he Debug m enu you will find t he Processes select ion. Clicking t his brings up t he dialog box in Figure 7.6. Figur e 7 .6 . At t a ch in g t o a r u n n in g pr oce ss.
By default , you will see only t he processes t hat you have st art ed in som e way. I f you click t he Show Syst em Processes check box, you have access t o everyt hing t hat is running on t he current m achine. Click t he process t o be debugged, and t hen click t he At t ach but t on. Now, if t hat process hit s a breakpoint or any ot her t ype of debugger event , t hat event pops up in t he Visual St udio .NET I DE.You can also force t he program t o break by clicking t he Break but t on at t he bot t om of t he window. At any t im e, you can st op debugging t he process by clicking t he Det ach but t on. Term inat e kills t he process alt oget her. Aft er clicking t he At t ach but t on, you are given a choice of what t ype of debugging you want t o do on t he process you’ve select ed. Figure 7.7 shows an exam ple of t his dialog box. Figur e 7 .7 . Ch oosing t h e de bug t ype .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you are at t aching t o a .NET process writ t en using t he Com m on Language Runt im e ( CLR) , choose t he Com m on Language Runt im e opt ion from t he dialog box. I f you’ll be breaking int o a process t hat uses Microsoft Transact SQL language, check Microsoft T- SQL as your debug t ype. Nat ive enables you t o debug a st andard Win32 applicat ion. This enables you t o debug a Win32 program at an assem bly language level. Finally, t he Script t ype gives you t he capabilit y t o debug st andard Visual BasicScript and JavaScript . This is especially useful for debugging an inst ance of I nt ernet Explorer.
Se t t in g I t All Up There really isn’t a whole lot t o m ent ion here. I t is ext rem ely sim ple t o use t he Visual St udio .NET I DE for debugging ASP.NET pages. I n m ost cases, it will be a plug- and- play affair. The default debug build of any ASP.NET proj ect will have everyt hing set up for you t o begin. However, even t hough t hat probably will be t he case, we will discuss what is absolut ely required for t he debugging t o work, j ust in case som et hing goes wrong. Take a look at t he web.config file cont ained in your proj ect . This is an XML file t hat cont ains specific configurat ion inform at ion for your ASP.NET proj ect . One line in t his file will look sim ilar t o t he following:
The def aul t Language param et er will be based on t he default language of your ASP.NET proj ect . But what we are concerned about here is t he debug param et er. I f you are running in a debugging environm ent and want t o be able t o access t he spiffy feat ures of t he Visual St udio .NET I DE, t his debug param et er m ust be set t o t r ue, as it is in t he previous line. I f it is set t o f al se, none of t he feat ures will work. This is what you want for a release build of your proj ect .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n lin e D e buggin g of ASP.N ET Pa ge s This is so very easy—you’re going t o be ext rem ely happy about t his. I f you’ve ever debugged a program using Visual St udio 6.0 ( Visual Basic,Visual C+ + , and so on) you will feel right at hom e wit h what you are about t o learn about Visual St udio .NET. Let ’s discuss t hese great feat ures using a sam ple proj ect m ent ioned earlier in t he chapt er. As usual, bot h Visual Basic .NET and C# versions of t he code will be provided for you t o see. This sam ple proj ect will consist of an ASP.NET page and a Visual Basic .NET/ C# com ponent so t hat you can see how easily t he t wo int eract and how t hey can be debugged sim ult aneously. The proj ect it self will sim ply ask t he user for a valid em ail address and t hen send a form let t er t o t hat address. St art out by creat ing t he proj ect . We called ours Chap5Visual Basic for t he Visual Basic .NET version and Chap5CS for t he C# version. The first t hing t o do is creat e t he ASP.NET page t hat t he user will see. List ing 7.1 cont ains t he m ain ASP.NET page t hat cont ains t he input form on which t he user can ent er t he em ail address where t he m ail will be sent . Here t he page nam e is left as WebFor m1, t he default nam e provided when t he proj ect was creat ed. List in g 7 .1 ASP.N ET Pa ge for D e bugging Ex a m ple
Emai l Test Page
Pl ease ent er t he emai l addr ess t o send t o:
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
This page would work in a Visual Basic .NET proj ect . To have it work in a C# proj ect , change t he first line t o t he following:
This is a very sim ple page. I t consist s of t wo elem ent s: a t ext box for t he em ail address and a Subm it but t on t o send t he form t o t he server. Now you will creat e t he server– side code for t his proj ect . I t will be cont ained in t wo part s: First , you will look at t he code- behind file t hat is associat ed wit h t his file. Here you will verify t hat you have a valid em ail address. Second, you will creat e a Visual Basic .NET/ C# com ponent t hat will act ually send t he em ail. List ing 7.2 cont ains t he code- behind file for t he C# proj ect , and List ing 7.3 cont ains t he code- behind file for t he Visual Basic .NET proj ect . List in g 7 .2 List in g for D e bu gging Ex a m ple ( C# ) usi ng Syst em; namespace Chap7CS { publ i c cl ass WebFor m1 : Syst em. Web. UI . Page { pr ot ect ed Syst em. Web. UI . Ht ml Cont r ol s. Ht ml I nput Text t xt Emai l ; pr ot ect ed Syst em. Web. UI . Ht ml Cont r ol s. Ht ml I nput But t on bt nSubmi t ; publ i c WebFor m1( ) { Page. I ni t += new Syst em. Event Handl er ( Page_I ni t ) ; } pr i vat e voi d Page_I ni t ( obj ect sender , Event Ar gs e) { I ni t i al i zeComponent ( ) ; } pr i vat e voi d I ni t i al i zeComponent ( ) { t hi s. bt nSubmi t . Ser ver Cl i ck += new Syst em. Event Handl er ( t hi s. bt nSubmi t _Ser ver Cl i ck) ; } pr i vat e voi d bt nSubmi t _Ser ver Cl i ck( obj ect sender , Syst em. Event Ar gs e) {
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
i f ( t xt Emai l . Val ue. I ndexOf ( " @" ) == - 1 | | t xt Emai l . Val ue. I ndexOf ( " . " ) == - 1) Response. Wr i t e( " The suppl i ed emai l addr ess i s not val i d. " ) ; } } } List in g 7 .3 List in g for D e bu gging Ex a m ple ( Visu a l Ba sic .N ET) Publ i c Cl ass WebFor m1 I nher i t s Syst em. Web. UI . Page Pr ot ect ed Wi t hEvent s t xt Emai l As Syst em. Web. UI . Ht ml Cont r ol s. Ht ml I nput Text Pr ot ect ed Wi t hEvent s bt nSubmi t As Syst em. Web. UI . Ht ml Cont r ol s. Ht ml I nput But t on Pr i vat e Sub bt nSubmi t _Ser ver Cl i ck( ByVal sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Handl es bt nSubmi t . Ser ver Cl i ck I f t xt Emai l . Val ue. I ndexOf ( " @" ) = - 1 Or _ t xt Emai l . Val ue. I ndexOf ( " . " ) = - 1 Then Response. Wr i t e( " The suppl i ed emai l addr ess i s not val i d. " ) End I f End Sub End Cl ass These exam ples are also ext rem ely sim ple, but t hey dem onst rat e t he feat ures of t he Visual St udio .NET I DE quit e effect ively. I n t his exam ple, you are list ening t o t he Ser ver Cl i ck event of t he Subm it but t on, nam ed bt nSubmi t . When t he user clicks t he Subm it but t on, t his event is fired. At t his point , you can inspect what is in t he t ext box on t he form . I f it does not cont ain an @sym bol or a., it cannot be a valid em ail address and you t hen report t his back t o t he user wit h a Response. Wr i t e of an error m essage. Next you will look at how t he previously m ent ioned debugging t ools can aid you in t racking down a problem in t his sim ple page.
Se t t in g a Br e a k poin t Let ’s st art out by set t ing a breakpoint on t he Ser ver Cl i ck event of t he Subm it but t on. This is t he bt nSubmi t _Ser ver Cl i ck funct ion in eit her piece of code. To set a breakpoint , sim ply m ove t he m ouse cursor t o t he gray left m argin in t he code edit or window, and click. This drops a red dot int o t he m argin, signifying t hat a
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
breakpoint has been set at t hat specific line. Figure 7.8 shows exact ly where t o set t his breakpoint and what t he m argin will look like aft er clicking. Figur e 7 .8 . Se t t ing t he br e a k poin t in t h e e x a m ple pr ogr a m .
Now go ahead and run t he program . When I nt ernet Explorer appears, ent er som e gibberish int o t he t ext box t hat does not cont ain eit her an @sym bol or a . .Now click t he Subm it but t on. When t his occurs, t he Visual St udio .NET I DE should pop up wit h t he breakpoint line highlight ed in yellow. The execut ion of your program has paused, and now you can use som e of t he ot her debugging feat ures.You will look at t he wat ch window next .
W a t ch W in dow At t he bot t om of your screen, you will see a debugging window wit h som e t abs below it . Click t he one labeled Wat ch 1. I f t his t ab is not available, you will find t he sam e ent ry under t he Debug m enu as part of t he Windows subopt ion. Figure 7.9 shows t he m enu ent ry. Figur e 7 .9 . Th e w a t ch w indow opt ion un de r t h e D e bu g m e n u .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
The wat ch window enables you t o t ype in a specific variable nam e, cont rol nam e, or ot her obj ect and t hen see what value it cont ains and what t ype it is. For now, t ype in t xt Emai l .You will see t hat you can expand t his ent ry int o all t he cont rol’s propert ies t o see what t hey each cont ain. To save space, you m ight want t o see only t he Val ue propert y—in t hat case, you could ent er t xt Emai l .Value as your wat ch nam e. Wit h t he t xt Emai l cont rol expanded, you can see t hat t he Val ue propert y cont ains what ever you ent ered in t he cont rol on t he client side. This can be ext rem ely useful when debugging all t ypes of cont rols t o see what values t hey cont ain. I t is always useful t o st art here when debugging alm ost any problem t o m ake sure t hat t he dat a isn’t t o blam e. For exam ple, you m ight be chasing aft er a problem only t o find t hat t he Val ue propert y is em pt y for som e reason or t hat it does not cont ain t he dat a t hat you t hink it does. The ot her t hing t hat you can do wit h t he wat ch window is change t he value of a variable. I f you click t he propert y value in t he Value colum n in t he wat ch window, you can ent er a new value as you see fit . This m ight be helpful if you want t o t est a cert ain case in your logic t hat m ight be difficult t o hit . For exam ple, if an error is supposed t o occur if a value equals –1, at t his point you could change t he value t o –1 and cont inue execut ion t o m ake sure t hat t he code pat h is operat ing properly. That ’s about it for t he wat ch window. This is a feat ure t hat you will use quit e a bit in your debugging. Rem em ber t hat you can ent er any variable or any obj ect int o t he window and view any or all of it s specific propert ies. Also not e t hat you can change t he values of any of t hese propert ies at any t im e.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Th e Com m a n d W in dow I f you have used Visual Basic, t his will be a fam iliar sight . The com m and window was called t he im m ediat e window in Visual Basic, but it s feat ures are ident ical. This window enables you t o issue com m ands t o debug or evaluat e expressions on t he fly. To display t he window, eit her click t he Com m and Window t ab locat ed at t he bot t om of your screen, or choose Windows, I m m ediat e from t he Debug m enu at t he t op of your screen. Figure 7.10 shows where you can find t he opt ion under t he Debug m enu. Figur e 7 .1 0 . Th e im m e dia t e w in dow opt ion u nde r t h e D e bug m e nu .
To view t he cont ent s of a variable or obj ect , j ust t ype it s nam e int o t he com m and window. For exam ple, t yping t xt Emai l . Val ue while at t he breakpoint displays t he cont ent s of t he t ext box upon subm ission t o t he server. Sim ilar t o t he wat ch window, you can change t he value of variables or obj ect propert ies. To change t he value of t he form t ext box, you could ent er t xt Emai l . Val ue = " newval ue" , which would set t he st ring t o " newval ue" . What m akes t he com m and window a bit m ore excit ing t han t he wat ch window is it s capabilit y t o execut e funct ions. For exam ple, if you want t o execut e t he Val i dat eEmai l funct ion in your code list ing at any t im e, you could do it right from t he com m and window: Just click in t he window and call t he funct ion wit h t he appropriat e param et er. For exam ple, if you t ype Val i dat eEmai l ( " t est @myhost . com" ) ,you will see t hat it ret urns 0. I f you t ype Val i dat eEmai l ( " asdf asdf " ) , it ret urns –1. So, you can t est any funct ion t hat you
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
writ e right here wit hout having t he execut ing program call it explicit ly—a great debugging aid.
Tr a cin g Tracing is a very sim ple m et hod of debugging problem s. Tracing can be used t o print t ext st at em ent s during t he execut ion of your code. This can be used as a log t o see exact ly what is happening at any point in your code. As you can see in t he previous exam ples, in t he Ser ver Cl i ck funct ion of t he Subm it but t on, you are calling Debug. Wr i t eLi ne wit h t he value of t he form ’s t ext box. This call spit s out t he value of t he t ext box t o t he debug st ream . The easiest place t o see t he debug st ream is in t he out put window at t he bot t om of t he Visual St udio .NET I DE. This window can be displayed by eit her clicking t he Out put t ab or choosing Out put under t he View m enu and t hen choosing Ot her Windows. This window shows you all t he debug st at em ent s t hat you have insert ed int o your code, as well as anyt hing else t hat get s writ t en t o t he debug st ream by any ot her com ponent s t hat m ight be associat ed wit h t he running proj ect . Keep t his in m ind if you see a flood of m essages t hat you didn’t writ e int o your code.
Ex e cu t ion Con t r ol Before we st art t alking about t he call st ack, let ’s t ake a brief j ourney int o t he execut ion cont rol feat ures of t he debugger. These feat ures enable you t o cont rol exact ly what is execut ed in your program —and in what order. They can also be used t o t race deeply int o cert ain port ions of t he code or skip over t hem , if t hat level of det ail is unnecessary. All t hese feat ures can be found under t he Debug m enu at t he t op of your screen. All are also associat ed wit h keyboard short cut s t hat vary depending on how you have configured Visual St udio .NET. The keyboard short cut s are t he easiest m et hod of using t hese feat ures because t hey enable you t o m ove t hrough m any lines of code in a very quick fashion. We recom m end learning t he keyboard short cut s and using t hem while debugging your own code. The t hree opt ions are St ep I nt o, St ep Over, and St ep Out . St ep I nt o enables you t o st ep one level deeper int o t he code at t he current point of execut ion or, at t he very least , m ove t o t he next st at em ent . I f you are about t o call a funct ion in your code, using St ep I nt o cont inues execut ion at t he first line of t he called funct ion. St ep Over does t he opposit e of St ep I nt o. I f you are about t o call a funct ion, using St ep Over at t his point does j ust t hat —it st eps over execut ion of t he funct ion t o t he very next line of t he funct ion t hat you are current ly execut ing. Now keep in m ind
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t hat t his does not m ean t hat it will not execut e t he funct ion—it j ust will not allow you t o dig int o it . I t execut es t he funct ion and m oves on t o t he next line. This is quit e useful when you know t hat a funct ion or block of code is working correct ly and you do not want t o spend t he t im e hit t ing every single line. St ep Out enables you t o j um p out of t he current funct ion t hat you are debugging and go one level up. Again, sim ilar t o t he St ep Over feat ure, t his does not skip t he execut ion of t he rem aining lines of code; t hey j ust execut e behind your back, and your debugging cursor m oves t o t he next line in t he previous funct ion you were in. So how do you know which funct ion you were previously in? That leads t o t he next debugging feat ure, t he call st ack.
Ca ll St a ck The call st ack shows t he current funct ion you are in and all funct ions t hat preceded it . When you call a funct ion from a funct ion from a funct ion from a funct ion, you have a call st ack t hat is four levels deep, wit h t he current funct ion on t he t op. You can view t he call st ack window by clicking t he Call St ack t ab at t he bot t om of your screen or by choosing Call St ack from t he Debug m enu under Windows. Cont inuing t he previous exam ple, st op execut ion again on t he bt nSubmi t _Ser ver Cl i ck funct ion and t hen t race int o t he Val i dat eEmai l funct ion. Now you have called a funct ion from a funct ion. Take a look at t he call st ack window. The t op t wo levels should show you t he Val i dat eEmai l funct ion, followed by t he bt nSubmi t _Ser ver Cl i ck funct ion. You will also see quit e a few ot her funct ions t hat are called by t he ASP.NET syst em processes. Now go ahead and double- click t he bt nSubmi t _Ser ver Cl i ck funct ion. A green highlight appears over t he point in t he funct ion t hat you current ly are in. I n t his case, t he call t o Val i dat eEmai l is highlight ed because t his is t he exact posit ion t hat you are current ly at in t hat funct ion. This feat ure can be of use when you are debugging code t hat m ight not be all your own. I f you are m any levels deep int o a funct ion st ack, you m ight need t o know where you cam e from . By using t his, you can t race back t o t he calling st ack and see exact ly who called you and wit h what inform at ion. Aft er you have t raced back t o t he call st ack, you can use t he wat ch window or t he com m and window t o inspect t he local variables from t he previous funct ions. This can be handy when you want t o find where cert ain dat a values are com ing from if t hey are wrong.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Fe a t u r e Su m m a r y That about wraps up t he baseline feat ures of t he Visual St udio .NET I DE. Next you will look at how t o add a C# or Visual Basic .NET com ponent t o your proj ect and debug t hat sim ult aneously wit h your ASP.NET pages. The process is ext rem ely st ream - lined and quit e seam less, as you will soon see.
I n lin e D e bu ggin g of Com pon e n t s I f you t ried debugging Visual Basic com ponent s wit hin an ASP page in t he previous version of Visual St udio, you will rem em ber t hat it can be a pain t o deal wit h.You need t he Visual I nt erdev I DE open for debugging t he ASP page, and you need t he separat e Visual Basic I DE open t o debug t he com ponent s at t he sam e t im e. The new Visual St udio .NET I DE m akes t his process rem arkably sim pler.You can add t he com ponent t o your ASP.NET proj ect , and debugging of t hat com ponent can be done wit hin t he sam e I DE in sequence wit h your ASP.NET code. Let ’s look at how t his is done. To do t his, you will add a com ponent t o t he previous proj ect t hat act ually sends out t he em ail t o t he address provided.
Addin g t h e Com pon e n t You will now add t he com ponent t o t he ASP.NET applicat ion. Just right - click your m ouse on t he proj ect nam e ( Chap5VB or Chap5CS, if you’ve nam ed t hem what we called t hem ) and choose Add Com ponent under t he Add subm enu. Here, choose eit her a Visual Basic .NET com ponent class or a C# com ponent class, depending on which t ype of proj ect you are current ly doing. Nam e t he com ponent Em ailer, for lack of a bet t er nam e. Figure 7.11 shows t he m enu opt ion t o choose aft er right - clicking t he proj ect nam e. Figur e 7 .1 1 . Adding a n e w com pone n t t o t h e pr oj e ct .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Now t hat you have added t he com ponent , it needs som e code. List ing 7.4 is t he C# version of t he em ailer, and List ing 7.5 is t he Visual Basic .NET version. Reference whichever one is applicable for your proj ect . List in g 7 .4 Code for Em a ile r Com pon e n t ( C# ) usi ng Syst em. Web. Mai l ; namespace Chap7CS { publ i c cl ass Emai l er : Syst em. Component Model . Component { pr i vat e Syst em. Component Model . Cont ai ner component s = nul l ; publ i c Emai l er ( Syst em. Component Model . I Cont ai ner cont ai ner ) { cont ai ner . Add( t hi s) ; I ni t i al i zeComponent ( ) ; } publ i c Emai l er ( ) { I ni t i al i zeComponent ( ) ; } pr i vat e voi d I ni t i al i zeComponent ( ) { component s = new Syst em. Component Model . Cont ai ner ( ) ; }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
publ i c voi d SendFor mEmai l ( st r i ng t oAddr ) { Mai l Message mm = new Mai l Message( ) ; mm. To = t oAddr ; mm. Fr om = " admi n@domai n. com" ; mm. Body = " Thi s i s a t est message. Exci t i ng, i sn' t i t ?" ; mm. Subj ect = " Chapt er 7 Test Message" ; Smt pMai l . Smt pSer ver = " smt p. domai n. com" ; Smt pMai l . Send( mm) ; } } } List in g 7 .5 Code for Em a ile r Com pon e n t ( Visua l Ba sic .N ET) I mpor t s Syst em. Web. Mai l Publ i c Cl ass Emai l er I nher i t s Syst em. Component Model . Component Publ i c Sub New( By Val Cont ai ner As Sys t em. Component Model . I Cont ai ner ) MyCl ass. New( ) Cont ai ner . Add( Me) End Sub Publ i c Sub New( ) MyBase. New( ) I ni t i al i zeComponent ( ) End Sub Pr i vat e component s As Syst em. Component Model . Cont ai ner Pr i vat e Sub I ni t i al i zeComponent ( ) component s = New Syst em. Component Model . Cont ai ner ( ) End Sub Publ i c Sub SendFor mEmai l ( ByVal t oAddr As St r i ng) Di m mm As Mai l Message = New Mai l Message( ) mm. To = t oAddr
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
mm. Fr om = " admi n@domai n. com" mm. Body = " Thi s i s a t est message. Exci t i ng, i sn' t i t ?" mm. Subj ect = " Chapt er 7 Test Message" Smt pMai l . Smt pSer ver = " smt p. domai n. com" Smt pMai l . Send( mm) End Sub End Cl ass The code here is pret t y sim ple. Each version cont ains a funct ion called SendFor mEmai l t hat t akes t he em ail address t o send t o as a param et er. Then you use t he Mai l Message and Smt pMai l obj ect s from t he Syst em. Web. Mai l assem bly t o form t he em ail m essage and send it out using a valid SMTP server. To get t his t o work in your environm ent , be sure t o replace t he Smt pMai l . Smt pSer ver value wit h t he SMTP server of your local net work. You will need t o m odify your bt nSubmi t _Ser ver Cl i ck funct ion t o creat e an inst ance of t his com ponent and call t he SendFor mEmai l m et hod t o m ake it happen. List ing 7.6 gives t he code for t he m odified bt nSubmi t _Ser ver Cl i ck in C# , and List ing 7.7 gives t he sam e code in Visual Basic .NET. List in g 7 .6 M odifie d Code for bt n Subm it _ Se r ve r Click ( C# ) pr i vat e voi d bt nSubmi t _Ser ver Cl i ck( obj ect sender , Syst em. Event Ar gs e) { Emai l er em = new Emai l er ( ) ; Debug. Wr i t eLi ne( " User ent er ed: " + t xt Emai l . Val ue) ; i f ( Val i dat eEmai l ( t xt Emai l . Val ue) == - 1) Res ponse. Wr i t e( " The suppl i ed emai l addr ess i s not val i d. " ) ; el se { em. SendFor mEmai l ( t xt Emai l . Val ue) ; Res ponse. Wr i t e( " The emai l was sent successf ul l y. " ) ; } } List in g 7 .7 M odifie d Code for bt n Subm it _ Se r ve r Click ( Visua l Ba sic .N ET) Pr i vat e Sub bt nSubmi t _Ser ver Cl i ck( ByVal sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Handl es bt nSubmi t . Ser ver Cl i ck Di m em As Emai l er = New Emai l er ( ) I f t xt Emai l . Val ue. I ndexOf ( " @" ) = - 1 Or _ t xt Emai l . Val ue. I ndexOf ( " . " ) = - 1 Then
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Res ponse. Wr i t e( " The suppl i ed emai l addr ess i s not val i d. " ) El se em. SendFor mEmai l ( t xt Emai l . Val ue) Res ponse. Wr i t e( " The emai l was sent successf ul l y. " ) End I f End Sub
D e bu ggin g t h e Com pon e n t Now we get t o t he cool part . You can debug t his com ponent while you debug t he ASP.NET page and it s respect ive code- behind file. To prove t his, set a breakpoint on t he bt nSubmi t _Ser ver Cl i ck in t he code- behind file and t hen st art t he program . When I nt ernet Explorer appears, ent er a valid em ail address in t he appropriat e box, and click t he Subm it but t on. I m m ediat ely, t he breakpoint on t he bt nSubmi t _Ser ver Cl i ck funct ion should fire and t he program is paused on t hat line. Now st ep t o t he point where t he current funct ion is about t o call t he Emai l er . SendFor mEmai l funct ion. At t his posit ion, do a St ep I nt o. You will see t hat t he source code t o t he Em ailer com ponent appears wit h t he code point er at t he t op of t he SendFor mEmai l funct ion. From here, you can use all t he t echniques m ent ioned earlier t o inspect variables, set t race st at em ent s, m odify variable values, and so on. I t couldn’t be easier! Say goodbye t o m ult iple program s being open sim ult aneously and ot her configurat ion issues t hat m ake your life difficult .
Re m ot e D e bu gging Every t im e we have a discussion wit h som eone regarding debugging ASP pages, we always ask if t hat person has ever t ried t o set up ASP debugging on t he local m achine. The response usually is “ yes.” We t hen follow up wit h t he quest ion of if t hat person has ever got t en it t o work. The num ber who answer “ yes” t o t hat quest ion is m uch lower. Finally, we ask if t hat person has ever got t en ASP debugging t o work rem ot ely. We have yet t o find som eone who has got t en it t o work properly and consist ent ly. Wit h ASP.NET and Visual St udio .NET, t hat all changes. I t finally works. And it couldn’t possibly be easier t o inst all, configure, and use.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n st a lla t ion When you inst all Visual St udio .NET on your server, all you need t o do is inst all bot h Rem ot e Debugging opt ions list ed under t he Server Com ponent s opt ion during t he inst all procedure.
Se t u p To configure rem ot e debugging, t he only t hing you need t o do is place your user account int o t he newly creat ed Debugger Users group bot h on t he client m achine and on t he server m achine. This can be done using t he st andard user configurat ion t ools t hat are part of whichever Windows operat ing syst em you are using.
Usin g I t This is t he easiest part of all. To use t he new rem ot e debugging feat ures, sim ply creat e a proj ect on your client com put er t hat point s t o t he proj ect running on t he server. This can be done by choosing Open Proj ect from t he Web from t he File m enu. Just t ype in t he nam e of t he server where t he proj ect resides, and you will be present ed wit h a list of proj ect s current ly residing on t hat server. Choose t he appropriat e one. I f you are not connect ing t o an exist ing proj ect , you can creat e a brand new proj ect on t he server, and rem ot e debugging will st ill t ake place. Next , set a breakpoint on t he line where you want t o st op, or sim ply st art t he applicat ion running. I t will connect t o t he server and bring up an I nt ernet Explorer window, as usual. The big difference here is t hat t he applicat ion is running ent irely on t he server. When you hit your breakpoint , you are hit t ing it on t he server, in t he server’s m em ory space. The sam e goes for com ponent s and anyt hing else t hat you m ight be debugging. Everyt hing t hat can be debugged in Visual St udio .NET locally can now be debugged rem ot ely on any server where t he rem ot e debugging opt ions have been inst alled. And t hat ’s it ! I t ’s alm ost com plet ely aut om at ic. I wish it was t his easy in Visual St udio 6.0 —it ’s a huge t im e saver and a powerful t ool.
Su m m a r y I n t his chapt er, you looked at m any of t he debugging feat ures found in t he new Visual St udio .NET I DE. You should now be fam iliar wit h t hings such as t he wat ch
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
window, t he com m and window, breakpoint s, variable inspect ion, and variable m odificat ion as applied bot h t o debugging ASP.NET pages and Visual Basic .NET and C# com ponent s.Wit h t hese concept s in m ind, you are prepared t o st art debugging your own proj ect s, and you are prepared for what is explained in t he rem ainder of t his book. I n t he next chapt er, we discuss how you can use t he Windows NT and Windows 2000 Event Log t o aid in t racking down t roublesom e code in your proj ect s.
Ch a pt e r 8 . Le ve r a gin g t h e W in dow s 2 0 0 0 Eve n t Log
WHI LE YOU ARE DEVELOPI NG A WEB APPLI CATI ON, if som et hing goes wrong and you receive a page error, you get feedback right on t he screen. You can t hen use t hat inform at ion t o t rack down t he source of t he error and fix it . Aft er you put your web applicat ion int o product ion, however, you are not always t here when a problem occurs. Wit hout a way t o t rack t hese errors, t hey could go unnot iced for days or even weeks. A great solut ion t o t his problem is t o leverage t he Windows 2000 Event Log. This chapt er explains what t he Windows 2000 Event Log is and t ells how t o im plem ent it in your web applicat ions. We’ll also define expect ed and unexpect ed event s, and t ell how t o handle bot h t ypes. The chapt er concludes wit h an exercise in building a web- based event log viewer.
Th e W in dow s 2 0 0 0 Eve n t Log D e fin e d The Windows 2000 Event Log is t he syst em by which Windows 2000 t racks event s t hat happen on t he server. The event log t racks t hree t ypes of event s: securit y event s, syst em event s, and applicat ion event s. The last cat egory, applicat ion event s, is what t his chapt er focuses on. The applicat ion event log is designed for not ificat ions concerning non–syst em - level applicat ions on t he server. Most oft en, t hese are cust om applicat ions from t hird- part y vendors.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
W e b Applica t ion s Ca n Use t h e Eve n t Log Web applicat ions can also leverage t he applicat ion event log. Previous versions of ASP did not offer an easy way t o writ e inform at ion t o t he applicat ion event log—you had t o build a Visual Basic com ponent t hat would enable t his funct ionalit y. This, coupled wit h t he fact t hat t here was no st ruct ured error handling in t radit ional ASP applicat ions, m eant t hat you had t o eit her use t he On Er r or Resume Next st at em ent or direct all of your page errors t o a cent ralized error page for processing—not very elegant at all. ASP.NET offers full support for m anipulat ing t he Windows 2000 Event Log. This includes creat ing cust om applicat ion logs t hat are specific t o your web applicat ion. This helps you st ay organized if you are host ing m ult iple web applicat ions on t he sam e server. The st ruct ured error handling t hat Microsoft ’s .NET Fram ework provides is ideal for capt uring and logging applicat ion event s. Global event s also can be used t o capt ure error inform at ion if errors occur in your web applicat ion.
Th e Syst e m .D ia gn ost ics Eve n t Log I nt e r fa ce The event log int erface in t he Syst em .Diagnost ics nam espace is very feat ure- com plet e; t his nam espace is t he one discussed and used in all t he code exam ples in t his chapt er. Despit e it s ext ra feat ures, t he Event Log obj ect in t he Syst em .Diagnost ics nam espace is quit e easy t o m anipulat e and use. To writ e a m essage t o t he Windows 2000 Event Log, sim ply call t he st at ic Wr i t eEnt r y m et hod of t he Event Log class as illust rat ed in List ings 8.1 and 8.2. List in g 8 .1 W r it in g t o t h e Eve n t Log Usin g t h e Eve n t Log obj e ct in Syst e m .D ia gnost ics ( C# )
List in g 8 .2 W r it in g t o t h e Eve n t Log Usin g t h e Eve n t Log obj e ct in Syst e m .D ia gnost ics ( Visu a l Ba sic .N ET)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Event User Comput er Message
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n t his sam ple, when t he page first loads, you build and display an ASP.NET Dr opDownLi st server cont rol t hat cont ains t he nam es of all t he event logs on t he local server. This list is obt ained by calling t he St at ic Get Event Logs m et hod of t he Event Log class and passing in t he . wildcard charact er t hat st ands for local server. Alt ernat ively, you could specify anot her m achine on t he net work. The Get Event Logs m et hod ret urns an array of Event Log obj ect s t hat you bind t o t he Dr opDownLi st server cont rol. I f you select one of t he event logs from t he Dr opDownLi st cont rol and click t he Get Log Ent ries but t on, t he get Messages_Cl i ck server event is fired. This event calls t he Get LogEnt r i es funct ion t hat you define. The Get LogEnt r i es funct ion get s a list of event log ent ries for t he select ed event log. I t t hen binds t his collect ion of Event LogEnt r y obj ect s t o t he m essages Repeat er server cont rol. The m essages Repeat er displays t he propert ies of each Event LogEnt r y obj ect in an HTML t able. The funct ion t hen calls t he Cl ose m et hod of t he Event Log obj ect inst ance. A Clear Log Ent ries but t on also calls t he cl ear Log_Cl i ck event . I nside t his event , you est ablish a connect ion t o t he event log t hat was select ed in t he Dr opDownLi s t server cont rol and call t he Cl ear m et hod of t he Event Log obj ect inst ance. You t hen call t he Cl ose m et hod. Finally, you call t he Get LogEnt r i es funct ion t o refresh t he Repeat er server cont rol. The web- based Event Log Viewer wit h som e sam ple result s will look sim ilar t o Figure 8.3. Figur e 8 .3 . You ca n pr ogr a m m a t ica lly r e - cr e a t e t h e W in dow s 2 0 0 0 Eve nt Log in t h e for m of a n ASP.N ET pa ge .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Su m m a r y I n t his chapt er, you learned t hat Microsoft ’s .NET Fram ework exposes an int erface for m anaging t he Windows 2000 Event Log. This int erface is locat ed in t he Syst em .Diagnost ics nam espace. The Event Log class in t he Syst em .Diagnost ics nam espace offers a rich int erface for bot h reading and writ ing t o t he Windows 2000 Event Log. This includes set t ing up cust om event logs and m anipulat ing all t he propert ies of an event . You also learned t hat t here are t wo different t ypes of event s: expect ed event s and unexpect ed event s. Expect ed event s are ident ified using logic st ruct ures and are logged according t o t he rules out lining t heir im port ance. Unexpect ed event s are t rapped and handled via st ruct ured error handling. Specific except ions can be t rapped and logged, as can generic except ions. The chapt er concluded by showing you how t o build a web- based Event Log Viewer t hat enables you t o select an event log from a Dr opDownLi st server cont rol and click a but t on t o display all t he event s in t hat event log. Anot her but t on clears all t he log ent ries from t he select ed event log in t he Dr opDownLi st server cont rol. I n t he next chapt er, you m ove on t o Part I I I , “ Debugging t he New ASP.NET Feat ures,” and st art off wit h a discussion on debugging ASP.NET server cont rols.
Pa r t
III:
D e buggin g
the
Fe a t u r e s Part I I I Debugging t he New ASP.NET Feat ures 9 Debugging Server- Side Cont rols 10 Debugging Dat a- Bound Cont rols 11 Debugging User Cont rols 12 Caching I ssues and Debugging
New
ASP.N ET
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
9 . D e bu ggin g Se r ve r - Side Con t r ols
ASP.NET SERVER CONTROLS PROVI DE AN ENORMOUS am ount of power t o you as a program m er in developing t ruly obj ect - orient ed web- based applicat ions. I n t he sim plest t erm s, a server cont rol is a cont rol t hat is execut ed on t he server and t hat provides som e t ype of out put t o t he user. These generally are used t o creat e brandnew t ypes of user- int erface cont rols t hat are not current ly available in ASP.NET. I f you have been using ASP.NET, you will be fam iliar wit h t he st yle t ags t hat have been int roduced int o t he language. These t ags t hat you insert int o your HTML page are really server- side cont rols t hat im plem ent eit her a st andard HTML cont rol or a cust om cont rol t hat is only part of ASP.NET, such as a dat a grid. I n t he t radit ional ASP paradigm , t his can be t hought of as an include file t hat cont ains t he HTML or JavaScript required t o im plem ent a new t ype of cont rol. Now, however, you are act ually building a real com piled com ponent t hat is execut ed ent irely on t he server. This chapt er focuses on creat ing a server- side ASP.NET cont rol, including navigat ing som e com m on pit falls in developing a cont rol like t his and properly debugging it bot h as it is being writ t en and aft er it has been com plet ed. The dem onst rat ion proj ect used in t his chapt er is an ext rem ely sim ple t ab cont rol.
Cr e a t in g t h e Pr oj e ct I f you plan t o follow along st ep by st ep wit h t his chapt er, we recom m end following som e nam ing convent ions t o m ake com piling and debugging easier. As always, bot h C# and Visual Basic .NET code will be provided for t his proj ect . You’ll st art by creat ing t he proj ect . First , creat e a st andard ASP.NET applicat ion in t he language of your choice. Nam e it eit her Chapt er9CS for C# or Chapt er9VB for Visual Basic .NET. Next , right - click t he proj ect nam e in t he Solut ion window and choose Add and t hen New Com ponent . I n t he dialog box t hat appears, choose Web Cust om Cont rol and nam e t his com ponent Sim pleTabCont rol.cs or Sim pleTabCont rol.vb, depending on t he language you have chosen for t his exam ple.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Now you can st art coding t he basic t ab cont rol fram ework. First , you will creat e t he very basic input and out put rout ines of t he t ab cont rol. List ing 9.1 cont ains t he C# version of t he code, while List ing 9.2 cont ains t he Visual Basic .NET version. List ings 9.3 and 9.4 cont ain t he code of one of t he ASP.NET pages t hat you will be using t o t est t he cont rol for t he C# and Visual Basic .NET proj ect s, respect ively. Finally, List ing 9.5 is a list ing of t he code- behind file t hat will be used for t he C# ASP.NET pages, and List ing 9.6 cont ains t he sam e code in Visual Basic .NET. You will want t o creat e t hree separat e ASP.NET pages, each wit h t he sam e code. The only difference bet ween t he pages is having t he proper code- behind file referenced from each page, as well as having each code- behind file wit h a unique class in it . This will be explained a bit m ore as we explain t he exam ple in t he pages ahead. List in g 9 .1 Ta b Con t r ol ( C# —Sim ple Ta bCon t r ol.cs) usi ng Syst em; usi ng Syst em. Web. UI ; namespace Chapt er 9CS { publ i c cl ass Si mpl eTabCont r ol : Syst em. Web. UI . WebCont r ol s. WebCont r ol , I Post BackEvent Handl er { pr i vat e st r i ng[ ] aPages; pr i vat e st r i ng[ ] aNames; publ i c st r i ng Cur Page { get { r et ur n ( st r i ng) Vi ewSt at e[ " cur Page" ] ; } set { Vi ewSt at e[ " cur Page" ] = val ue; } } publ i c st r i ng Names { get { r et ur n ( st r i ng) Vi ewSt at e[ " names" ] ; } set { Vi ewSt at e[ " names" ] = val ue; aNames = val ue. Spl i t ( " ~" ) ; Vi ewSt at e[ " aNames" ] = aNames; } } publ i c st r i ng Pages { get { r et ur n ( st r i ng) Vi ewSt at e[ " pages" ] ; } set { Vi ewSt at e[ " pages" ] = val ue; aPages = val ue. Spl i t ( " ~" ) ; Vi ewSt at e[ " aPages" ] = aPages; } }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
publ i c st r i ng Act i veCol or { get { r et ur n ( st r i ng) Vi ewSt at e[ " act i veCol or " ] ; } set { Vi ewSt at e[ " act i veCol or " ] = val ue; } } publ i c st r i ng I nact i veCol or { get { r et ur n ( st r i ng) Vi ewSt at e[ " i nact i veCol or " ] ; } set { Vi ewSt at e[ " i nact i veCol or " ] = val ue; } } publ i c st r i ng Redi r Page { get { r et ur n ( st r i ng) Vi ewSt at e[ " r edi r Page" ] ; } set { Vi ewSt at e[ " r edi r Page" ] = val ue; } } publ i c voi d Rai sePost BackEvent ( st r i ng event Ar gument ) { Vi ewSt at e[ " cur Page" ] = event Ar gument ; Vi ewSt at e[ " r edi r Page" ] = aPages[ Conver t . ToI nt 32( event Ar gument ) ] ; } / / Over r i de f or out put t i ng t ext t o t he br owser pr ot ect ed over r i de voi d Render ( Ht ml Text Wr i t er out put ) { i nt i ; i f ( aPages. Get Upper Bound( 0) ! = aNames. Get Upper Bound( 0) ) { / / t oss t he er r or her e } el se { out put . Wr i t e( " " ) ; f or ( i = 0; Page 3
Thi s i s PAGE 1.
On every form subm ission, t his elem ent is sent t o t he server, where it is decoded and t hrown int o t he ViewSt at e dict ionary. This is how ASP.NET reset s default values in t ext boxes, list boxes, and ot her elem ent s. I n t his case, it is how you keep t rack of our pages, t heir nam es, t he page you are on, and t he page you are m oving t o. So, if you are creat ing som e st at e inform at ion using t he ViewSt at e dict ionary and are expect ing t o be able t o use t hese values on a new page t hrough a st andard link, you will be very disappoint ed. These will be accessible only t hrough a form subm ission t o t he sam e page. That is why, in t his exam ple, t he page t hat you are on is passed via a query st ring variable because it can’t be t racked t he ViewSt at e dict ionary. The __VI EWSTATE form variable is not sent t o t he next page.
D e cla r in g t h e Con t r ol in t h e Code - Be h in d File I n t he ASP.NET page list ed earlier, t he t ab cont rol is declared in t he act ual page wit h t he server cont rol t ag ( < t ab: Si mpl eTabCont r ol . . . / >) . How ev er , t his is not enough t o reference t he cont rol from your code- behind file. To do t his, it is necessary t o have a declarat ion of t he t ab cont rol in your code- behind file. I n C# , t his would look like t his: pr ot ect ed Chapt er 9CS. Si mpl eTabCont r ol t ab; I n Visual Basic .NET, it would be t his: Pr ot ect ed t ab as Chapt er 9Vi sual Basi c. Si mpl eTabCont r ol The crit ical t hing t o rem em ber about t he declarat ion here is t hat t he variable nam e ( t ab, in t his case) m ust m at ch t he nam e t hat you assigned t o t he cont rol in it s name and i d param et ers on t he corresponding ASP.NET page.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you do not rem em ber t o declare your cont rols in t he code- behind file, you will not be able t o reference t he t ab cont rol direct ly, and your code will eit her not com pile or not run as you had ant icipat ed. Generally, you will see an error m essage sim ilar t o t he following when t rying t o build your applicat ion: The t ype or namespace name ' t ab' coul d not be f ound ( ( ar e you mi ssi ng a usi ng di r ect i ve or an assembl y r ef er ence?) I f you see a sim ilar error in your fut ure proj ect s, be sure t hat you have added a declarat ion of your cont rol in your code- behind file.
Re gist r a t ion of Con t r ol on ASP.N ET Pa ge At t he t op of any ASP.NET page t hat uses a server cont rol, you m ust use t he Regi st er direct ive t o regist er t hat specific cont rol for use in t hat page. This looks like t he following line:
I n t his line, you need t o specify t he TagPr ef i x, which is t he nam e t hat will be used t o reference t he cont rol. I n t he exam ple, t he nam e Tab is used, so when adding t he cont rol t o t he page, you would writ e t his:
The ot her t hings t o specify are t he nam espace t hat cont ains t he cont rol, as well as t he assem bly where t he cont rol is locat ed. I f t hese are incorrect , your page will not be displayed. I nst ead, you will see an error m essage because t he ASP.NET parser will not be capable of finding t he cont rol t o include in t he page. I f you forget eit her of t hese at t ribut es, t he parser will t ell you which one is m issing. Just add it in, as appropriat e, and your cont rol should work fine on t hat specific page. r u n a t = se r ve r As wit h all server- side cont rols, it is absolut ely essent ial t o include t he r unat =ser ver at t ribut e on t he cont rol for it t o work properly.We cannot st ress enough how im port ant t his is.We st ress t his so m uch sim ply because t he error m essage( s) t hat you will see st at e not hing about t his being t he problem .What you will m ost likely see is a m essage regarding a reference t o t he cont rol, or a propert y or m et hod on t he cont rol being nul l . The m essage will usually be t he following: Val ue nul l was f ound wher e an i nst ance of an obj ect was r equi r ed.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you see an error resem bling t his, t he first t hing t o check is t o be sure t hat you’ve placed t he r unat =ser ver at t ribut e on t he server- side cont rol.
D e bu ggin g in Visu a l St u dio .N ET I f you are using Visual St udio .NET, consider yourself lucky. You will have unprecedent ed power in debugging your server- side cont rols in t his I DE.You can set breakpoint s on any line in t he server- side code or any references t o it in your code- behind file. Then, when execut ion reaches any of t hese point s, your code will break and you can inspect exact ly what is happening and see if it is what you expect . As discussed in Chapt er 7,“ Visual St udio .NET Debugging Environm ent ,” t he Visual St udio .NET I DE provides a lot of flexibilit y when debugging your code. Figure 9.1 shows a debugging session from t he C# proj ect , inspect ing t he cont ent s of t he cur Page ent ry in t he ViewSt at e dict ionary in t he Com m and window.You can also see t he Aut os window in t he lower- left pane, wit h a few of t he variables t hat t he debugger has aut om at ically decided t o add for inspect ion. Figur e 9 .1 . D e bu gging a n ASP.N ET se r ve r con t r ol inVisua l St udio .N ET.
Here in t he I DE, you can also t race t he order of event s t o m ake sure t hat t hey are being called in t he order t hat you t hink t hey are being called, or t o see if t hey are even being called at all. For exam ple, if you forgot t o use t he over r i des keyword when overriding t he Render funct ion on your server cont rol, t he funct ion would never be called because it isn’t t he “ proper” Render funct ion.Wit hin t he I DE, you can set a breakpoint on t he Render funct ion and see if execut ion breaks at t his spot t hat it is supposed t o.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Su m m a r y This chapt er discussed t he issues t hat can arise when creat ing a server- side cont rol in ASP.NET. This includes looking at t he m ost com m on problem s t hat developers can face when developing cont rols of t his t ype.We also looked at solut ions t o t hese problem s and ways t o avoid t hem from t he st art . The next chapt er t akes a look at dat a- bound cont rols and som e com m on st rat egies for debugging t hem in t he .NET environm ent .
Ch a pt e r 1 0 . D e bu ggin g D a t a - Bou n d Con t r ols
I N THI S CHAPTER,WE WI LL LOOK AT t he issues t hat surround debugging dat a binding. Microsoft has included a list of new cont rols, such as t he dat a grid and dat a list cont rols. These cont rols have t he capabilit y t o bind dat a elem ent s or dat a sources t o t hem . This chapt er looks at various areas such as t em plat es, dat a grids, and nam espace issues.
D a t a - Bou n d Con t r ols You can bind dat a t o a lim it ed num ber of cont rols, but we will focus on som e of t he m ore com m on cont rols, including t he dat a grid, t he dat a list , and a few ot hers. Let ’s st art out by t aking a closer look at t hese dat a- bound cont rols and where you m ight have problem s.
Th e D a t a Gr id Con t r ol The dat a grid cont rol is a great new addit ion t o t he t ool box. This cont rol enables you t o creat e a spreadsheet - like page of dat a and t hen m anipulat e t he dat a as you need t o. List ings 10.1 and 10.2 show a sim ple dat a grid cont rol in C# and Visual Basic .NET. Then we’ll ident ify som e areas where you m ight need t o im plem ent som e debugging t echniques. List in g 1 0 .1 Sim ple D a t a Gr id Con t r ol ( C# ) pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
{ / / Put user code t o i ni t i al i ze t he page her e Sql Connect i on conn = new Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) ; conn. Open( ) ; Sql Dat aAdapt er da = new Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , conn) ; Dat aSet ds = new Dat aSet ( ) ; da. Fi l l ( ds, " pr oduct s" ) ; Dat aGr i d1. Al t er nat i ngI t emSt yl e. BackCol or = Col or . Al i ceBl ue; Dat aGr i d1. Header St yl e. BackCol or = Col or . Bei ge; Dat aGr i d1. Font . Bol d = t r ue; Dat aGr i d1. Dat aSour ce = ds; Dat aGr i d1. Dat aBi nd( ) ; conn. Cl ose( ) ; } List in g 1 0 .2 Sim ple D a t a Gr id Con t r ol ( Visu a l Ba sic .N ET) Pr i vat e Sub Page_Load( ByVal sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Handl es MyBase. Load Di m conn = New Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) conn. Open( ) Di m da As Sql Dat aAdapt er = New Sql Dat aAdapt er ( ) da. Sel ect Command = New Sql Command( " Sel ect * f r om pr oduct s" , conn) Di m ds = New Dat aSet ( ) da. Fi l l ( ds, " pr oduct s" ) Dat aGr i d1. Al t er nat i ngI t emSt yl e. BackCol or = Col or . Al i ceBl ue Dat aGr i d1. Header St yl e. BackCol or = Col or . Bei ge Dat aGr i d1. Font . Bol d = Tr ue Dat aGr i d1. Dat aSour ce = ds Dat aGr i d1. Dat aBi nd( ) conn. Cl ose( ) This is a pret t y sim ple exam ple. I t j ust m akes a call t o t he dat abase t o get a list of product s and t hen displays t hem in t he dat a grid.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
D a t a Gr id Pa gin g When you st art get t ing int o som e of t he ot her capabilit ies of t he dat a grid, you will undoubt edly com e across t he paging feat ure t hat is built int o t he cont rol. I t is very easy t o run int o problem s if you are not fam iliar wit h t he workings of t he dat a grid cont rol. I f you look at t he following code line, you will see t hat it is very sim ple t o t urn on t he paging feat ure on t he dat a grid cont rol:
I f you t ry t o use t he code as it appears here, you will not ice but t ons for Next and Previous at t he bot t om of t he dat a grid, but t hey don’t seem t o do anyt hing. A few t hings need t o happen t o really get t he paging feat ure t o work.You will also need t o im plem ent t he OnPageI ndexChanged handler, as shown in t his next exam ple:
Aft er you have changed t he aspx code t o include t he OnPageI ndexChanged at t ribut e t o point t o a handler funct ion such as Gr i dChange, you can add t he required code t o handle t he paging funct ionalit y. I f you st op t o look at what is happening here, you are j ust t elling t he dat a grid t o call t he Gr i dChange funct ion when t he OnPageI ndexChanged event is fired.You can put any addit ional code t hat you want in t he GridChange funct ion, but for t he paging feat ure t o work, a few t hings need t o be done. Take a look at what you need t o do t o m ake t he paging feat ure work. List ings 10.3 and 10.4 show you how t o im plem ent t he last piece of t he dat a grid paging feat ure. List in g 1 0 .3 Gr id Pa gin g Eve n t H a ndle r ( C# ) publ i c voi d Gr i dChange( Obj ect sender , Dat aGr i dPageChangedEvent Ar gs e) { / / Set Cur r ent PageI ndex t o t he page t he user cl i cked. Dat aGr i d1. Cur r ent PageI ndex = e. NewPageI ndex; Sql Connect i on conn = new Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
conn. Open( ) ; Sql Dat aAdapt er da = new Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , conn) ; Dat aSet ds = new Dat aSet ( ) ; da. Fi l l ( ds, " pr oduct s" ) ; / / Rebi nd t he dat a. Dat aGr i d1. Dat aSour ce = ds; Dat aGr i d1. Dat aBi nd( ) ; } List in g 1 0 .4 Gr id Pa gin g Eve n t H a ndle r ( Visu a l Ba sic .N ET) Publ i c Funct i on Gr i dChange( ByVal sender As Obj ect , ByVal e As Dat aGr i dPageChangedEvent Ar gs) '
Set Cur r ent PageI ndex t o t he page t he user cl i cked.
Dat aGr i d1. Cur r ent PageI ndex = e. NewPageI ndex Di m conn As New Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) conn. Open( ) Di m da As New Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , conn) Di m ds As New Dat aSet ( ) da. Fi l l ( ds, " pr oduct s" ) '
Rebi nd t he dat a.
Dat aGr i d1. Dat aSour ce = ds Dat aGr i d1. Dat aBi nd( ) End Funct i on You m ight not ice t hat t he key piece t o t his involves assigning t he NewPageI ndex value t o t he dat a grid’s Cur r ent PageI ndex propert y. Aft er you have done t his, t he dat a grid will display only t he set of dat a t hat resides on t hat new index page value. You m ight com e across t he error shown in Figure 10.1 t elling you t hat t he funct ion you provided t o handle t he event s is not accessible because of it s prot ect ion level. Don’t worry—t his is a sim ple fix. Figur e 1 0 .1 . Pr ot e ct ion - le ve l com pila t ion e r r or list in g.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
You will see t his error if your code does not declare t he event - handling funct ion as public. I f you look at t he following exam ples, you will see t hat t he m et hod is declared wit h t he publ i c keyword. When you don’t define your m et hod or variables, t hey m ight be set t o privat e. Any m et hod or propert y t hat is defined as privat e is accessible only t o t he cont ext of it s class or obj ect . Set t ing t he m et hod or propert y t o public grant s ext ernal classes or obj ect s access t o t hat resource. This m ight differ in each language, so if you need t o expose a m et hod or propert y, be sure t o use t he publ i c keyword, t o avoid guesswork. List ings 10.5 and 10.6 provide exam ples of t he proper way t o creat e an event handler for paging t hrough a dat a grid in bot h C# and Visual Basic .NET. List in g 1 0 .5 Cor r e ct M e t h od D e fin it ion ( C# ) publ i c voi d Gr i dChange( Obj ect sender , Dat aGr i dPageChangedEvent Ar gs e) { / / Set Cur r ent PageI ndex t o t he page t he user cl i cked. Dat aGr i d1. Cur r ent PageI ndex = e. NewPageI ndex; Sql Connect i on conn = new Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) ; conn. Open( ) ; Sql Dat aAdapt er da = new Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , conn) ; Dat aSet ds = new Dat aSet ( ) ; da. Fi l l ( ds, " pr oduct s" ) ; / / Rebi nd t he dat a t o t he dat asour ce Dat aGr i d1. Dat aSour ce = ds;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Dat aGr i d1. Dat aBi nd( ) ; } List in g 1 0 .6 Cor r e ct M e t h od D e fin it ion ( Visu a l Ba sic .N ET) Publ i c Sub Gr i dChange( ByVal sender As Obj ect , ByVal e As Dat aGr i dPageChangedEvent Ar gs)
'
Set Cur r ent PageI ndex t o t he page t he user cl i cked.
Dat aGr i d1. Cur r ent PageI ndex = e. NewPageI ndex Di m conn As New Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) conn. Open( ) Di m da As New Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , conn) Di m ds As New Dat aSet ( ) da. Fi l l ( ds, " pr oduct s" ) '
Rebi nd t he dat a.
Dat aGr i d1. Dat aSour ce = ds Dat aGr i d1. Dat aBi nd( ) End Sub
D e buggin g Te m pla t e s Tem plat es provide a m ore flexible way of displaying t he dat a. Most likely, if you will be doing anyt hing wit h dat a, you will probably be using t em plat es t o get t he j ob done. I n t his sect ion, we look at som e problem areas t hat you m ay st um ble over and how t o work around t hem .
W or k in g w it h D a t a List < I t e m Te m pla t e > When you are working wit h t em plat es you can easily run int o problem s t hat won’t be caught by t he com piler. This is because som e aspx code is not validat ed or is synt act ically correct but , at run t im e, is not valid.When you underst and t he basics of t em plat es, t hough, t hey can be a very powerful t ool in developing your sit e. So let ’s get st art ed and t ake a look at som e problem s t hat you m ight run int o.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
When you st art t rying t o cust om ize your dat a list , you will run int o t he Dat aBi nder . Take a look at List ing 10.7 t o see how t he Dat aBinder is used in place of a recordset . List in g 1 0 .7 a spx Code
When you include t he t ag in your aspx page, what ever you put bet ween t he t ags is what is going t o be displayed on t he page; don’t assum e t hat all t he ot her dat a fields will j ust m agically appear. I f you look at t he error shown in Figure 10.2, you will not ice t hat t he error occurred at Line 18. There you are t rying t o read a value from t he dat a cont ainer nam ed st ringvalue, but t he line does not t ell you what t he problem is. I f you look at t he st ack t race, you will not ice t hat it is t elling us t hat t he propert y nam e st ringvalue does not exist . That ’s because, in t he product s t able, t here is no colum n called st ringvalue. Figur e 1 0 .2 . I n va lid pr ope r t y in D a t a Row Er r or list ing.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
N a m e spa ce I ssue s You m ight not t hink m uch about nam espaces now, but when you st art creat ing large applicat ions or st art t o reuse your code from ot her proj ect s, nam espace will becom e an issue. So before you j ust blow off t he nam espace descript ion, t hink hard about what it really m eans and t hen give it an appropriat e nam e. Let ’s look at an exam ple of where you m ight run int o problem s. When you do run int o nam espace problem s, t he first t hing you will probably see is t he error m essage shown in Figure 10.3. Figur e 1 0 .3 . Am biguou s r e fe r e n ce e r r or m e ssa ge .
As t he m essage indicat es, t here is an am biguous reference. I n ot her words, t here are t wo classes called Class1 and t he com piler does not know which t o use. This is where nam espaces com e int o play. First , you’ll t ake a look at how we arrived at t his point ; t hen you’ll see what you need t o do t o fix t he problem . I f you want t o use t hese snippet s of code, you need t o st art wit h an exist ing web proj ect or windows applicat ion. Then you can add t he following snippet s t o your proj ect t o see how t hey react . List ings 10.8– 10.11 illust rat e t he problem and show how nam espaces ent er int o it s solut ion. List in g 1 0 .8 M ySpa ce .Cla ss1 ( C# ) namespace MySpace {
New Riders - Debugging ASP.NET
publ i c cl ass Cl ass1 { publ i c Cl ass1( ) { } publ i c st r i ng[ ] Get MyLi st ( ) { st r i ng[ ] myl i st = new st r i ng[ 4] ; myl i s t [ 0] =" car s" ; myl i s t [ 1] =" t r ucks" ; myl i s t [ 2] =" pl anes" ; myl i s t [ 3] =" boat s" ; r et ur n myl i st ; } } } List in g 1 0 .9 M ySpa ce .Cla ss1 ( Visu a l Ba sic .N ET) Namespace MySpace Publ i c Cl ass Cl ass1 Publ i c Funct i on Get MyLi st ( ) As St r i ng( ) Di m myl i st As St r i ng( ) myl i st ( 0) = " car s" myl i st ( 1) = " t r ucks" myl i st ( 2) = " pl anes" myl i st ( 3) = " boat s" Ret ur n myl i st End Funct i on End Cl ass End Namespace List in g 1 0 .1 0 You r Spa ce .Cla ss1 ( C# ) namespace Your Space {
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
publ i c cl ass Cl ass1 { publ i c Cl ass1( ) { } publ i c st r i ng[ ] Get MyLi st ( ) { st r i ng[ ] myl i st = new st r i ng[ 4] ; myl i s t [ 0] =" eggs" ; myl i s t [ 1] =" bacon" ; myl i s t [ 2] =" mi l k" ; myl i s t [ 3] =" br ead" ; r et ur n myl i st ; } } } List in g 1 0 .1 1 You r Spa ce .Cla ss1 ( Visu a l Ba sic .N ET) Namespace Your Space Publ i c Cl ass Cl ass1 Publ i c Funct i on Get MyLi st ( ) As St r i ng( ) Di m myl i st As St r i ng( ) myl i st ( 0) = " car s" myl i st ( 1) = " t r ucks" myl i st ( 2) = " pl anes" myl i st ( 3) = " boat s" Ret ur n myl i st End Funct i on End Cl ass End Namespace As you can see from t hese list ings, bot h classes have t he sam e nam e and t he sam e m et hods. The only t hing t hat different iat es t hem is t heir nam espace. Now t ake a look at how we were t rying t o im plem ent t hese classes in t he web page ( see List ing 10.12) .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 0 .1 2 a spx Code for I m ple m e n t ing t h e Cla sse s ( C# - I n cor r e ct M e t h od)
pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e) { / / Put user code t o i ni t i al i ze t he page her e Cl ass1 c1 = new Cl ass1( ) ; / / Ambi guous Ref er ence Li st Box1. Dat aSour ce = c1. Get MyLi st ( ) ; Li st Box1. Dat aSour ce = c1. Get MyLi st ( ) ; Li st Box1. Dat aBi nd( ) ; Li st Box2. Dat aBi nd( ) ; }
As you can see, t he nam espaces have been included at t he beginning of t he file so t hat t he com piler can ident ify t he classes. What you need t o do is preface t he class wit h t he nam espace t hat it belongs t o; t hen t he com piler knows definit ively what you want t o do. Take a look at t he code in List ing 10.13 t o see t he correct im plem ent at ion for t hese classes. List in g 1 0 .1 3 a spx Code for Cor r e ct I m ple m e n t a t ion of t h e Cla sse s ( C# - Cor r e ct M e t h od)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e) { MySpace. Cl ass1 c1 = new MySpace. Cl ass1( ) ; Your Space. Cl ass1 c2 = new Your Space. Cl ass1( ) ; Li st Box1. Dat aSour ce = c1. Get MyLi st ( ) ; Li st Box1. Dat aSour ce = c2. Get MyLi st ( ) ; Li st Box1. Dat aBi nd( ) ; Li st Box2. Dat aBi nd( ) ; }
As you can see here, you need t o ident ify which nam espace you are using if t here are nam ing conflict s like t hose wit h Class1. Next you t ake a look at XML bindings and som e hurdles t hat you m ight run int o.
XM L Bin din g XML is a fundam ent al part of t he .NET archit ect ure. I f you look at how dat a is handled in t he Dat a nam espace, you will see t hat it all revolves around XML. So if you are not fam iliar wit h XML basics, pick up som e reading m at erial on XML, such as St eve Holzner’s I nside XML ( New Riders Publishing, 2001) . Figure 10.4 shows an exam ple of a problem t hat you m ight run int o. However, t he syst em does not t hrow an except ion or give you any indicat ion t hat t here is a problem . Figur e 1 0 .4 . a spx out pu t .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Everyt hing looks fine on t he page, but it seem s t o be m issing a few records. Take a look at t he exam ple code in List ings 10.14 and 10.15 and XML file in List ing 10.16 and see if you can ident ify t he problem . List in g 1 0 .1 4 Using XM L a s a D a t a Sou r ce ( C# ) pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e) { / / Put user code t o i ni t i al i ze t he page her e Dat aSet ds = new Dat aSet ( ) ; ds. ReadXml ( " c: \ \ por t f ol i o. xml " ) ; Dat aGr i d1. Dat aSour ce = ds; Dat aGr i d1. Dat aBi nd( ) ; } List in g 1 0 .1 5 Using XM L a s a D a t a Sou r ce ( Visu a l Ba sic .N ET) Pr i vat e Sub Page_Load( ByVal sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Handl es MyBase. Load '
Put user code t o i ni t i al i ze t he page her e
Di m ds As New Dat aSet ( ) ds . ReadXml ( " c: \ \ por t f ol i o. xml " ) Dat aGr i d1. Dat aSour ce = ds Dat aGr i d1. Dat aBi nd( ) End Sub List in g 1 0 .1 6 por t folio.x m l File
I BMI nt ' l Busi ness Machi nes $357, 840
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
WEI NX AI MWei ngar t en Fund A> $318, 150
CSTGX
AI M Const el l at i on Fund
A $256, 603
KGGAX
Kemper Aggr essi ve Gr owt h A
$121, 600
SONE
S1 Cor por at i on
$111, 960
As you can see, it is very sim ple t o load an XML file int o a dat aset and assign it t o t he dat a grid’s dat a source propert y. Microsoft has done a nice j ob of im plem ent ing XML and dat a- bound cont rols t oget her. At first sight , t his m ay look well form ed, but t here is one sm all problem . You are m issing t he root elem ent ! One way t o m ake sure t hat your file is well form ed is t o look at it wit h I E 5.x . I f it can’t parse t he file, it will t ell you what t he problem is. Figure 10.5 shows what happens when we t ried t o look at t he file wit h I E. Figur e 1 0 .5 . I E XM L vie w .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you sim ply add an elem ent called PRODUCTS at t he beginning and end of t he file encom passing all t he XML t ext , you will creat e a root elem ent , as shown in List ing 10.17. List in g 1 0 .1 7 XM L File Cor r e ct e d
I BMI nt ' l Busi ness Machi nes $357, 840
WEI NX AI M Wei ngar t en Fund A $318, 150
Now t hat you have everyt hing set up correct ly, you will get a list of records displayed on your web page t he way you int ended t o. Keep in m ind t hat t his XML file could be form at t ed in a num ber of ways t o st ore j ust about any t ype of dat a you need.
Su m m a r y This chapt er looked at som e key elem ent s t hat play a vit al part in dat a- bound cont rols. These com ponent s will m ake up t he base foundat ion as you m ove forward in building new dat a- driven web sit es. You looked here at how t o use som e of t he m ore useful feat ures of t he dat a grid cont rol, such as event handling and paging. You also learned how t o use t he dat a list and cust om ize it wit h t he it em t em plat e
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t ags. And don’t forget t o use nam espaces when you are using classes wit h t he sam e nam es. This will alleviat e am biguous nam es t hat will give you com piler errors.
Ch a pt e r 1 1 . D e bu ggin g Use r Con t r ols
I N PREVI OUS VERSI ONS OF ASP, I F YOU want ed t o encapsulat e sect ions of user int erface code, you had lim it ed opt ions. You could use an include file, but t here was no way t o cust om ize each “ inst ance” of t he code sect ion.You could package t he user int erface code int o a COM obj ect and call one of it s m et hods t o display it , but t hat m eant t hat you had t o recom pile t he COM obj ect each t im e you want ed t o m ake a change. You could use a library of funct ions in script file includes, but t his approach wast ed a lot of web server resources because, m ost of t he t im e, your page uses only a sm all subsect ion of t he code in each include file. I n ASP.NET, User Cont rols solve t his dilem m a. User Cont rols are designed t o give you t he best of all worlds: encapsulat ion, opt im ized m em ory usage, com piled code, and t he capabilit y t o m ake changes on t he fly. Wit h any aspect of program m ing, however, difficult ies can em erge; t his chapt er deals wit h t hese difficult ies. To m ake sure t hat we cover everyt hing, t he exam ples in t his chapt er follow t he creat ion of a User Cont rol and an ASP.NET page t hat consum es it from st art t o finish. Along t he way, we’ll expose som e of t he nuances, t echnicalit ies, and om issions t hat crop up wit h User Cont rols.
Use r Con t r ol Ba sics To get st art ed, let ’s build a sim ple User Cont rol, MyCont rol.ascx, and an ASP.NET page t hat consum es it , MyPage.aspx.
M yCon t r ol Most of t he t im e, User Cont rols will cont ain dynam ic elem ent s, but t hat ’s not always t he case. For inst ance, you m ight creat e a User Cont rol t o display copyright inform at ion at t he bot t om of each page in your web applicat ion. Likewise, t he User Cont rol MyCont r ol will st art off wit h j ust st at ic cont ent . Right now, you’ll be concerned wit h t he issues surrounding t he basic plum bing of User Cont rols, as you can see in List ing 11.1.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 1 .1 M yCont r ol— Ba sics
Thi s i s MyCont r ol .
M yPa ge Now t hat you have a sim ple User Cont rol built , you can im plem ent it in an ASP.NET page. First , List ing 11.2 shows t he correct im plem ent at ion code. List in g 1 1 .2 M yPa ge —Ba sics
MyPage
Ba sic Got ch a s The code in List ings 11.1 and 11.2 will yield t he sim ple m essage displayed in t he browser “ This is MyCont rol.” Did you get any errors? Here’s what m ight have gone wrong. M issin g End Ta g or En d- Ta g M a r k e r All ASP.NET server cont rols require an end t ag. User Cont rols are a form of server cont rol t hat you cust om - creat e, so t he sam e rules apply. Forget t ing t o include eit her an end t ag or and end- t ag m arker / > will generat e an error like t his: Par ser Er r or Mes sage: Li t er al cont ent ( ' ) i s not al l owed wi t hi n a ' ASP. MyCont r ol _ascx'
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Of course, t he exact synt ax of t he error will vary, depending on what lit eral cont ent is present direct ly aft er your User Cont rol reference. I n t his case, it was t he HTML t ags. M issin g Run a t At t r ibut e What if your User Cont rol doesn’t show up at all? This alm ost always m eans t hat t hat you forgot t o include t he r unat =" ser ver " at t ribut e on your User Cont rol. This is a requirem ent , as it is wit h all ot her ASP.NET server cont rols. A quick way t o verify t his is t o right - click t he screen in I nt ernet Explorer and select View Source. You’ll m ost likely see t hat your User Cont rol t ag was m ist aken for plain- old HTML t ags and was sent direct ly t o t he browser. Wit hout t he runat at t ribut e, t he ASP.NET engine does not know t hat it is supposed t o do anyt hing wit h it , so it com plet ely ignores it . Un k now n Se r ve r Ta g Occasionally, you’ll get a m essage t hat doesn’t m ake any sense at first glance. For inst ance, you m ight get t his error: Par ser Er r or Message: Unknown ser ver t ag ' Chapt er 11: MyCont r ol ' . I t doesn’t seem t o m ake any sense because t hat is t he TagPr ef i x and TagName t hat you specified. Or is it ? Take anot her look at your @Regi st er t ag at t he t op of your ASP.NET page. Odds are, you m isspelled eit her t he TagPr ef i x or t he TagName at t ribut e. I f t he sit uat ion were reversed, it would have been easier t o spot t he issue because t he ASP.NET sourcecode surrounding t he error is shown. I f t he error resides in t he @Regi st er t ag, t he solut ion is not always so obvious.
Adding Pr ope r t ie s a n d M e t h ods Now t hat you can debug t he basic issues wit h User Cont rols, let ’s add som e com plexit y. One of t he nicest t hings about User Cont rols is t hat t hey can expose propert ies, m aking t heir underlying cont ent m ore dynam ic. They can also expose m et hods. Alt hough it ’s not a requirem ent , it is good design pract ice t o im plem ent m et hods in User Cont rols only when t hey are needed t o influence t he appearance of t he cont ent of t he User Cont rol it self. Use code- behind m et hods of your ASP.NET page, .NET com ponent s, or Web Services if you need m ore ut ilit arian funct ionalit y.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Add a Pr ope r t y List ings 11.3 and 11.4 show your MyCont r ol User Cont rol wit h a Name propert y im plem ent ed. List in g 1 1 .3 M yCont r ol w it h Pr ope r t y ( C# )
pr i vat e st r i ng _name; publ i c st r i ng Name { get { r et ur n _name; } s et { _name = val ue; } }
Thi s cont r ol bel ongs t o . List in g 1 1 .4 M yCont r ol w it h Pr ope r t y ( Visu a l Ba sic .N ET)
Pr i vat e _name As St r i ng Publ i c Pr oper t y Name As St r i ng Get Ret ur n _name End Get Set _name = Val ue End Set End Pr oper t y
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Thi s cont r ol bel ongs t o . To access t he Name propert y of your User Cont rol from your ASP.NET page, sim ply add a Name at t ribut e t o your MyCont r ol t ag, like t his:
Pr ope r t y Got ch a s You’ll face t wo prim ary got chas when it com es t o dealing wit h User Cont rol propert ies: t he scope m odifier and t he order in which propert ies are assigned. I m pr ope r Scope M odifie r When t est ing your User Cont rol wit h propert ies, you m ight not ice t hat t he propert y is not appearing, even t hough you are set t ing it in your server t ag definit ion. The problem could be due t o t he scope m odifier ( or lack t hereof ) at t ached t o your propert y definit ion. For t he propert ies of your User Cont rol t o be available t o your ASP.NET page, t hey m ust have public scope. I f you leave off t he scope m odifier com plet ely in Visual Basic, t he default is public, so your propert y will appear j ust fine. However, if you leave off t he scope m odifier in C# , t he default is privat e, so your propert y will not appear. Worse yet , it won’t even t hrow an error because you are set t ing t he propert y in your server t ag definit ion and are not program m at ically in a script block ( discussed next ) . I f you want ed t o assign your User Cont rol propert ies program m at ically, you could add a script block t o your ASP.NET page as shown in List ings 11.5 and 11.6. List in g 1 1 .5 Assign Use r Con t r ols Pr ope r t ie s Pr ogr a m m a t ica lly ( C# )
pr ot ec t ed voi d Page_Load( obj ect sender , Event Ar gs e) { myCont r ol 1. Name = " Jon" ; }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
MyPage
List in g 1 1 .6 Assign Use r Con t r ols Pr ope r t ie s Pr ogr a m m a t ica lly ( Visua l Ba sic .N ET)
Pr ot ec t ed Sub Page_Load( sender As Obj ect , e As Event Ar gs) myCont r ol 1. Name = " Jon" End Sub
MyPage
Not e t hat t he Name at t ribut e of t he server t ag has been replaced wit h an i d at t ribut e. This enables you t o reference it from t he code block. The error t hrown for an im proper scope m odifier at t his point is a lit t le m ore int uit ive: Compi l er Er r or Message: CS0122: ' ASP. MyCont r ol _cs_ascx. Name'
is
i naccessi bl e due t o i t s pr ot ect i on l evel
or ( Visual Basic .NET) Compi l er Er r or Message: BC30390: ' ASP. MyCont r ol _vb_ascx. Pr i vat e Pr oper t y Name( ) As St r i ng'
i s Pr i vat e, , and i s not accessi bl e i n t hi s cont ext .
I t is always bet t er if you do not rely on default behaviors of t he program m ing language you are using. You should always specify scope m odifiers. For t he purposes of exposing User Cont rol propert ies, be sure t o use public scope.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Or de r of Pr ope r t y Assignm e n t You m ight experience what appears t o be som e st range behavior wit h your User Cont rol propert ies if you don’t know t he order in which event s occur in your ASP.NET page. For inst ance, t ake t he following code exam ples shown in List ings 11.7 and 11.8. List in g 1 1 .7 Pr ope r t y Assign m e n t Or de r ( C# )
pr ot ec t ed voi d Page_I ni t ( obj ect sender , Event Ar gs e) { myCont r ol 1. Name = myCont r ol 1. Name + " Br i an" ; } pr ot ec t ed voi d Page_Load( obj ect sender , Event Ar gs e) { myCont r ol 1. Name = myCont r ol 1. Name + " Jon" ; }
MyPage
List in g 1 1 .8 Pr ope r t y Assign m e n t Or de r ( Visua l Ba sic .N ET)
Pr ot ec t ed Sub Page_I ni t ( sender As Obj ect , e As Event Ar gs) myCont r ol 1. Name = myCont r ol 1. Name & " Br i an" End Sub Pr ot ec t ed Sub Page_Load( sender As Obj ect , e As Event Ar gs) myCont r ol 1. Name = myCont r ol 1. Name & " Jon"
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
End Sub
MyPage
As you can see, t he Name at t ribut e has been added back t o t he User Cont rol t ag. This exam ple also added t he Page_I ni t event handler. When you run t he previous code list ings in a browser, it will display t he following t ext : Thi s cont r ol bel ongs t o Br adBr i anJon. This exercise is m eant t o show t he order in which code is execut ed in an ASP.NET page. Tag at t ribut es are evaluat ed and applied first , t he Page_I ni t event fires next , and t he Page_Load event fires last .You can t rap a few ot her page- level event s, but you get t he idea. I f you hadn’t been concat enat ing t he Name propert y in each of t he event handlers, t hen only t he one in t he Page_Load event would survive. The point t o rem em ber is t hat if you don’t get t he expect ed result s displayed for your User Cont rol, it som et im es helps t o check t he sequence in which t he code is execut ed. This can give you clues on what happened, as well as how t o fix it .
Add a M e t h od Now t hat you know som e of t he issues wit h User Cont rol propert ies, let ’s add a m et hod t o your User Cont rol. List ings 11.9 and 11.10 show what your User Cont rol code looks like now: List in g 1 1 .9 M yCont r ol w it h M e t h od ( C# )
pr i vat e st r i ng _name; publ i c st r i ng Name { get {
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
r et ur n _name; } s et { _name = val ue; } } publ i c voi d Di spl ayNewDat eTi me( ) { panel 1. Cont r ol s. Add( new Li t er al Cont r ol ( Dat eTi me. Now. ToSt r i ng( ) + "
" ) ) ; }
Thi s cont r ol bel ongs t o .
List in g 1 1 .1 0 M yCon t r ol w it h M e t h od ( Visu a l Ba sic .N ET)
Pr i vat e _name As St r i ng Publ i c Pr oper t y Name As St r i ng Get Ret ur n _name End Get Set _name = Val ue End Set End Pr oper t y Publ i c Sub Di spl ayNewDat eTi me( ) panel 1. Cont r ol s. Add( _ New Li t er al Cont r ol ( Dat eTi me. Now. ToSt r i ng( ) + "
" ) ) End Sub
Thi s cont r ol bel ongs t o .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
The code required t o call t his m et hod from your ASP.NET page is fairly sim ple. I t is done in t he sam e m anner as any ot her m et hod call on an obj ect ( see List ings 11.11 and 11.12) . List in g 1 1 .1 1 Ca llin g a Use r Cont r ol M e t h od ( C# )
pr ot ec t ed voi d Page_Load( obj ect sender , Event Ar gs e) { myCont r ol 1. Name = " Jon" ; myCont r ol 1. Di spl ayNewDat eTi me( ) ; myCont r ol 1. Di spl ayNewDat eTi me( ) ; }
MyPage
List in g 1 1 .1 2 Ca llin g a Use r Cont r ol M e t h od ( Visua l Ba sic .N ET)
Pr ot ec t ed Sub Page_Load( sender As Obj ect , e As Event Ar gs) myCont r ol 1. Name = " Jon" myCont r ol 1. Di spl ayNewDat eTi me( ) myCont r ol 1. Di spl ayNewDat eTi me( ) End Sub
MyPage
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
M e t h od Got ch a s There really aren’t any t ricky t hings about calling User Cont rol m et hods t hem selves ( besides t he scope m odifier and t he code execut ion order issues discussed in t he previous “ Propert y Got chas” sect ion) . The act ions perform ed by your User Cont rol m et hods can cause problem s, however. M odifyin g t h e Con t r ols Colle ct ion One of t he m ost com m on t hings t hat your User Cont rol m et hods will do is dynam ically creat e new server cont rols. This is exact ly what t he Di spl ayNewDat eTi me m et hod defined previously does. You’ll not ice t hat inst ead of adding your new Li t er al Cont r ol direct ly t o t he Cont r ol s collect ion of your User Cont rol, you creat ed a Panel server cont rol t o act as a placeholder. There are t wo reasons for t his. Because you have already used code blocks in your User Cont rol, you cannot dynam ically add any m ore cont rols t o it . Doing so would result in an error t hat looks like t his: Except i on Det ai l s: Syst em. Web. Ht t pExcept i on: The Cont r ol s col l ect i on cannot be modi f i ed because t he cont r ol cont ai ns code bl ocks ( i . e. ) . I f you had not used a code block t o display t he Name propert y of your User Cont rol, t hen you would have been able t o add your new Li t er al Cont r ol obj ect s direct ly t o t he Cont r ol s collect ion of your User Cont rol. The ot her reason why you shouldn’t do t his, t hough, is because when you add it em s t o t he Cont r ol s collect ion, by default , it adds t he it em t o t he end of t he User Cont rol. This m ight not be t he desired out com e. An AddAt m et hod of t he Cont r ol s collect ion enables you t o specify an insert ion index, but it can be difficult t o det erm ine which index posit ion t o specify. I t is m uch easier ( and less likely t o cont ain bugs) if you use a Panel or Label server cont rol as a placeholder for t he new dynam ic cont rols t hat you want t o add t o your User Cont rol. Acce ssing Ou t - of- Scope Con t r ols A com m on pit fall in using User Cont rol m et hods t rying t o access a cont rol t hat is cont ained in t he ASP.NET page it self. For inst ance, if you placed a Label server cont rol nam ed l abel 1 aft er your MyCont r ol t ag in your ASP.NET page and t hen t ried t o reference it in a m et hod of your User Cont rol, you would get an error t hat looks like t his:
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Compi l er Er r or Message: CS0246: The t ype or namespace name " l abel 1" coul d not be f ound ( ar e you mi ssi ng a usi ng di r ect i ve or an assembl y r ef er ence?) or ( Visual Basic .NET) Compi l er Er r or Message: BC30451: The name " l abel 1" i s not decl ar ed. . The easiest solut ion is t o put any cont rols t hat you want your User Cont rol t o m anipulat e inside t he User Cont rol definit ion file it self. That way, t he cont rols will be wit hin t he scope of your User Cont rol m et hods.
D yn a m ic Use r Con t r ols I nevit ably, you’ll run int o a sit uat ion in which you want t o creat e an ent ire User Cont rol dynam ically. This oft en occurs when it is uncert ain how m any inst ances of t he User Cont rol will be required on your ASP.NET page. Dynam ically generat ed User Cont rols can be a powerful t ool, but you m ust be aware of a few snags.
D e fin in g a Cla ss N a m e To be able t o reference t he propert ies and m et hods of your dynam ically loaded User Cont rols in your ASP.NET page, you m ust be able t o cast t hem t o a st rong t ype. This requires you t o define a class nam e in your User Cont rol definit ion file. This is a relat ively painless process. All it t akes is t o add a cl assName at t ribut e t o t he @Cont r ol direct ive, like t his:
or ( Visual Basic .NET)
Failure t o specify a cl assName at t ribut e will yield an error t hat looks like t his: Compi l er Er r or Message: CS0246: The t ype or namespace name ' MyCont r ol ' coul d not be f ound ( ar e you mi ssi ng a usi ng di r ect i ve or an assembl y r ef er ence?) or ( Visual Basic .NET) Compi l er Er r or Message: BC30002: Type i s not def i ned: ' MyCont r ol '
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Your User Cont rol is now all set up t o be dynam ically loaded and cast t o a st rong t ype.
Re fe r e n cin g Use r Con t r ol Cla sse s The code in your ASP.NET page t hat will dynam ically load your User Cont rol changes significant ly from t he code used t o display User Cont rols using server cont rol t ags. List ings 11.13 and 11.14 illust rat e what t he code should look like: List in g 1 1 .1 3 D yn a m ica lly Loa din g Use r Con t r ols ( C# )
pr ot ec t ed voi d Page_Load( obj ect sender , Event Ar gs e) { MyCont r ol mc1 = ( MyCont r ol ) LoadCont r ol ( " MyCont r ol _cs. ascx" ) ; mc1. Name = " Jon" ; mc1. Di spl ayNewDat eTi me( ) ; panel 1. Cont r ol s. Add( mc1) ; }
MyPage
List in g 1 1 .1 4 D yn a m ica lly Loa din g Use r Con t r ols ( Visu a l Ba sic .N ET)
Pr ot ec t ed Sub Page_Load( sender As Obj ect , e As Event Ar gs) Di m mc1 As MyCont r ol = _ CType( LoadCont r ol ( " MyCont r ol _vb. ascx" ) , MyCont r ol ) mc1. Name = " Jon" mc1. Di spl ayNewDat eTi me( ) panel 1. Cont r ol s. Add( mc1) End Sub
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
MyPage
Not ice t he use of t he @Ref er ence direct ive inst ead of t he @Regi st er direct ive ( which is now gone) . Because you won’t be adding User Cont rols as server cont rol t ags, you don’t need t he @Regi st er direct ive. The @Ref er ence direct ive enables you t o cast t he generic Cont r ol obj ect reference ret urned by t he LoadCont r ol m et hod t o t he specific st rong t ype of your User Cont rol ( in t his case, MyCont r ol ) . Anot her int erest ing t hing t o point out is t hat t he server cont rol t ag you used t o declare your User Cont rol on t he page is now gone, replaced by a Panel server cont rol t hat serves as a placeholder for your dynam ically loaded User Cont rol obj ect .
W h e n D yn a m ic Use r Con t r ols Go W r on g Som e int erest ing t hings can go wrong if you don’t follow t he rules of dynam ic User Cont rols. For inst ance, if you forget t o include t he @Regi st er direct ive, you’ll end up wit h an error t hat looks like t his: Compi l er Er r or Message: CS0246: The t ype or namespace name ' MyCont r ol ' coul d not be f ound ( ar e you mi ssi ng a usi ng di r ect i ve or an assembl y r ef er ence?) or ( Visual Basic .NET) Compi l er Er r or Message: BC30002: Type i s not def i ned: ' MyCont r ol ' Likewise, if you forget t o cast t he generic cont rol obj ect ret urned by t he LoadCont r ol m et hod t o t he st rong t ype of your User Cont rol, t hen you’ll see one of t hese errors: Compi l er Er r or Message: CS0029: Cannot i mpl i ci t l y conver t t ype ' Syst em. Web. UI . Cont r ol '
t o ' ASP. MyCont r ol '
or ( Visual Basic .NET) Compi l er Er r or Message: BC30512: Opt i on St r i ct di sal l ows i mpl i ci t conver si ons f r om Syst em. Web. UI . Cont r ol t o ASP. MyCont r ol .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Not e t hat t he second of t hese t wo errors is t he Visual Basic flavor and will occur only if you are using t he St r i ct =" Tr ue" at t ribut e of t he @Page direct ive. Ot herwise,Visual Basic will im plicit ly cast t he Cont r ol obj ect for you. C# does not offer a set t ing t o t urn off opt ion st rict , so an explicit cast is always necessary. I f you t ry t o access t he propert ies and m et hods of a generic Cont r ol obj ect ret urned from t he LoadCont r ol m et hod, you’ll get an error m essage like t his: Compi l er Er r or Message: CS0117: ' Syst em. Web. UI . Cont r ol ' does not cont ai n a def i ni t i on f or ' Name'
or ( Visual Basic .NET) Compi l er Er r or Message: BC30456: The name ' Name'
i s not a member of
' Syst em. Web. UI . Cont r ol ' .
To see t he propert ies and m et hods specific t o your User Cont rol, you m ust cast it t o t he proper st rong t ype specified in your @Ref er ence direct ive. One final t hing t o not e is t hat if you want t o add m ult iple inst ances of your User Cont rol, you m ust call t he LoadCont r ol m et hod for each one. Sim ply changing t he propert ies of an exist ing User Cont rol inst ance and t hen adding it t o t he Cont r ol s collect ion of your Panel server cont rol will not suffice; it m erely changes t he propert ies of t he original User Cont rol t hat you added. Even t hough you add t he User Cont rol inst ance t o t he Panel server cont rol, your variable st ill m aint ains a reference t o it and can m anipulat e it .
Su m m a r y I n t his chapt er, you looked at som e of t he idiosyncrasies of dealing wit h User Cont rols in ASP.NET web applicat ions. We st art ed by discussing som e of t he basic errors and problem s t hat you m ight run int o wit h User Cont rols. We t hen added a propert y t o your User Cont rol and t ook a look at som e of t he errors t hat can occur if proper scope m odifiers and code execut ion order rules are not followed. We t hen covered problem s encount ered by User Cont rol m et hods, including how t o handle problem s wit h m odifying t he Cont r ol s collect ion of t he User Cont rol and how t o access out - of- scope cont rols. We rounded out t he chapt er by creat ing a dynam ically loaded User Cont rol. Som e of t he issues covered here included class nam e
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
declarat ion, User Cont rol references, and explicit st rong t ype cast ing t o cust om User Cont rol t ypes. The next chapt er discusses caching issues t hat you m ight encount er while debugging your web applicat ions.
Ch a pt e r 1 2 . Ca ch in g I ssu e s a n d D e bugging
ONE OF THE MOST I MPORTANT NEW FEATURES t hat ASP.NET m akes available is a fairly ext ensive caching engine. This rem oves t he need for “ hom e- grown” caching solut ions t hat oft en cont ain m em ory leaks. ASP.NET’s caching capabilit ies are int egrat ed at t he I SAPI level, so t hey are m uch bet t er equipped t o handle cached resources. Alt hough caching in ASP.NET is relat ively easy t o im plem ent , t here are a few int ricacies and “ got chas” t hat we’d like t o cover. One of t he t hings t hat m ight not be so obvious is t hat , by nat ure, caching can m ake debugging your web applicat ion part icularly t roublesom e. For inst ance, if your web applicat ion cont ains a bug t hat displays t he wrong cont ent on a page, t hat cont ent could end up t rapped in cache. At t hat point , you would be forced t o m ake a change t o t he underlying ASP.NET page or user cont rol so t hat it would refresh it self. That ’s not a very elegant solut ion at all. There is a bet t er way t o handle t his issue, using a validat ion callback, which we’ll discuss a bit lat er. Let ’s t ake a look at a few t echniques for how t o deal wit h bot h out put caching and t he Caching API .
Ou t pu t Ca ch in g The easiest way t o im plem ent caching in your ASP.NET web applicat ions is t hrough direct ives at eit her t he page or t he user cont rol level. Unfort unat ely, t his m et hod is also t he m ost lim it ing and frust rat ing t o work wit h.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
@Ou t pu t Ca ch e D ir e ct ive The basis for out put caching at bot h t he page and t he user cont rol level is t he @Out put Cache direct ive. Alt hough you can use m any different possible at t ribut es ( a few of which you’ll see in a bit ) , t wo are m andat ory: Dur at i on and Var yByPar am. Var yByCont r ol can be subst it ut ed for Var yByPar am in user cont rols, however. D u r a t ion At t r ibu t e The Dur at i on at t ribut e is fairly st raight forward, but you m ust realize t hat t he num ber it accept s is t he num ber of “ seconds” t hat you want your cont ent t o be cached for. Accident ally specifying a value of 10, for inst ance, would cache your dat a only for 10 seconds inst ead of 10 m inut es ( which is what you m ight expect ) . I f you forget t o specify t he Dur at i on at t ribut e, you’ll get an error like t his: Par ser Er r or Message: The di r ect i ve i s mi ssi ng a ' dur at i on' at t r i but e. Va r yByPa r a m At t r ibut e Misuse of t he Var yByPar am at t ribut e can lead t o som e st range behavior by your ASP.NET page. This is t he second m andat ory at t ribut e of t he @Out put Cache direct ive. Failure t o include it will yield an error m essage like t his: Par ser Er r or Message: The di r ect i ve i s mi ssi ng a ‘ Var yByPar am’ at t r i but e, , whi ch shoul d be set t o " none" , " * " , or a l i st of name/ val ue pai r s. I f you specify none as a value for t his at t ribut e, you m ust be aware t hat t he sam e cached page will be served up for all request s for t hat page. For inst ance, if you int ended t o cache product inform at ion pages on your web applicat ion, and set t he Var yByPar am at t ribut e t o none, t hen t he first product t hat was request ed would be served up for all subsequent request s, regardless of any changes t hat were m ade t o t he query st ring. The following t wo page request s would bot h ret urn t he dat a for t he product wit h an I D = 10 : ht t p: / / www. your domai n. com/ pr oduct . aspx?I D=10 ht t p: / / www. your domai n. com/ pr oduct . aspx?I D=20 You m ight choose t o fix t his anom aly by specifying a value of * for t he Var yByPar am at t ribut e. Alt hough t his m ight appear t o solve t he problem , what happens if you are passing inform at ion on t he query st ring t hat is personal t o t he current user—say,
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
perhaps a user I D? You would t hen get a cached version for each user t hat browsed each product . Take t he following t wo page request s: ht t p: / / www. your domai n. com/ pr oduct . aspx?I D=10&user =1234 ht t p: / / www. your domai n. com/ pr oduct . aspx?I D=10&user =5678 You would want bot h of t hese request s t o be served up from t he sam e it em in cache. This is where you would want t o specify exact ly which Quer ySt r i ng param et ers you want t he cache t o key off. I n t his case, it would be t he I D param et er only. I t is useful t o not e t hat , in t he scenario j ust discussed, you would likely want t o place your @Out put Cache direct ive in a user cont rol t hat cont ains your product - rendering code so t hat t he user Quer ySt r i ng param et er could be used by ot her sect ions of t he page t o personalize t he out put . Then, only t he product inform at ion it self would be served up from cache. I f you need t o specify m ore t han one Quer ySt r i ng param et er as a caching key, m ake sure t hat you use a sem icolon as t he delim it er inst ead of a com m a. The value I D, user would be int erpret ed as one Quer ySt r i ng param et er, t hereby causing t he wrong caching behavior. The t ricky part is t hat no errors are generat ed when you m ake t his m ist ake. I nst ead, use I D; user . Va r yByCu st om At t r ibu t e When using t he Var yByCust om at t ribut e t o cust om ize t he key used t o st ore your page or user cont rol in cache, you m ust rem em ber t o override t he Get Var yByCust omSt r i ng m et hod in your web applicat ion’s global.asax file. No errors will be generat ed if you forget t o do t his, but your cust om param et er will not t ake part in t he cache key. Va r yByH e a de r At t r ibu t e The m ost com m on error t hat you will run int o wit h t he Var yByHeader at t ribut e occurs if you t ry t o use it in t he @Out put Cache direct ive of a user cont rol. This is not allowed and will generat e an error like t his: Par ser Er r or Message: The ' Var yByHeader ' at t r i but e i s not suppor t ed by t he ' Out put Cache' di r ect i ve. . Use t he Var yByHeader at t ribut e only at t he page level.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
M a n ipu la t ion of Ca ch e d Use r Con t r ols I f you im plem ent t he @Out put Cache direct ive in a user cont rol, you cannot m anipulat e it s propert ies ext ernally. Dynam ically assigning t he propert ies of a user cont rol in one of t he page’s event s ( such as Page_Load) works only if a copy does not already exist in t he fragm ent cache. Subsequent at t em pt s t o dynam ically m odify one of t he propert ies of a user cont rol t hat has out put caching enabled will generat e an error like t his: Except i on Det ai l s: Syst em. Nul l Ref er enceExcept i on: Val ue nul l was f ound wher e an i nst ance of an obj ect was r equi r ed. As you can see, t his error m essage isn’t very int uit ive. To be safe, always set t he propert ies of a cached user cont rol in t he Page_Load event inside t he user cont rol it self. The except ion t o t his is when you want t o use declarat ive at t ribut es; specifying at t ribut es in t he user cont rol t ag it self is perm it t ed. An exam ple m ight look like t his:
Va lida t ion Ca llba ck s Rem em ber t he issue m ent ioned at t he beginning of t he chapt er, pert aining t o dat a being t rapped in t he out put cache? Here is where we’ll put t hat issue t o rest . Here you’ll wire up a validat ion callback so t hat each t im e t he page is request ed from t he cache, you’ll get a chance t o est ablish whet her t he cached it em is st ill good. You’ll do t his by checking for t he exist ence of a passwor d Quer ySt r i ng param et er. Take a look at t he code in List ings 12.1 and 12.2, which dem onst rat e t he t echnique. List in g 1 2 .1 I nva lida t in g t h e Out pu t Ca che Th r ou gh a Va lida t ion Ca llba ck ( C# )
pr ot ect ed voi d MyHt t pCacheVal i dat eHandl er ( Ht t pCont ext cont ext , obj ect dat a, r ef Ht t pVal i dat i onSt at us val i dat i onSt at us) { / / i ni t i al i ze t he passwor d var i abl e st r i ng passwor d = " " ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
/ / set t he passwor d var i abl e i f t he user speci f i ed t he / / " passwor d" Quer ySt r i ng par amet er i f ( cont ext . Request . Quer ySt r i ng[ " passwor d" ] ! =nul l ) { passwor d = ( st r i ng) cont ext . Request . Quer ySt r i ng[ " passwor d" ] ; } / / i f a passwor d was speci f i ed, t hen det er mi ne i f i t i s / / cor r ect . I f i t i s, t hen evi ct t he page f r om t he cache. / / I f t he passwor d i s i ncor r ect or wasn' t / / speci f i ed, t hen val i dat e t he cached page swi t ch( passwor d) { case " mypasswor d" : val i dat i onSt at us = Ht t pVal i dat i onSt at us. I nval i d; br eak; def aul t : val i dat i onSt at us = Ht t pVal i dat i onSt at us. Val i d; br eak; } } pr ot ect ed voi d Page_Load( Obj ect sender , Event Ar gs e) { / / cr eat e an i nst ance of t he Ht t pCacheVal i dat eHandl er / / del egat e so t hat we can wi r e up t he val i dat i on cal l back Ht t pCacheVal i dat eHandl er myHandl er = new Ht t pCacheVal i dat eHandl er ( MyHt t pCacheVal i dat eHandl er ) ; / / wi r e up t he cal l back Response. Cache. AddVal i dat i onCal l back( myHandl er , nul l ) ; / / by di s pl ayi ng t he cur r ent dat e and t i me on t he scr een, / / we can see when t he cache i s bei ng i nval i dat ed l abel 1. Text = Dat eTi me. Now. ToSt r i ng( ) ; }
Val i dat i on Cal l back
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 2 .2 I nva lida t in g t h e Out pu t Ca che Th r ou gh a Va lida t ion Ca llba ck ( Visu a l Ba sic .N ET)
Pr ot ect ed Sub MyHt t pCacheVal i dat eHandl er ( _ cont ext As Ht t pCont ext , dat a As Obj ect , _ ByRef val i dat i onSt at us As Ht t pVal i dat i onSt at us) ' i ni t i al i ze t he passwor d var i abl e Di m passwor d As St r i ng = " " ' set t he passwor d var i abl e i f t he user speci f i ed t he ' " passwor d" Quer ySt r i ng par amet er I f cont ext . Request . Quer ySt r i ng( " passwor d" ) Not hi ng Then passwor d = CSt r ( cont ext . Request . Quer ySt r i ng( " passwor d" ) ) End I f ' i f a passwor d was speci f i ed, t hen det er mi ne i f i t i s ' cor r ect . I f i t i s, t hen evi ct t he page f r om t he cache. ' I f t he passwor d i s i ncor r ect or wasn' t ' speci f i ed, t hen val i dat e t he cached page Sel ect Case passwor d Case " mypasswor d" v al i dat i onSt at us = Ht t pVal i dat i onSt at us. I nval i d Case El se v al i dat i onSt at us = Ht t pVal i dat i onSt at us. Val i d End Sel ect End Sub Pr ot ec t ed Sub Page_Load( sender As Obj ect , e As Event Ar gs) ' cr eat e an i nst ance of t he Ht t pCacheVal i dat eHandl er ' del egat e so t hat we can wi r e up t he val i dat i on cal l back Di m myHandl er As Ht t pCacheVal i dat eHandl er = _ New Ht t pCacheVal i dat eHandl er ( _ Addr essOf MyHt t pCacheVal i dat eHandl er )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
' wi r e up t he cal l back Response. Cache. AddVal i dat i onCal l back( myHandl er , Not hi ng) ' by di spl ayi ng t he cur r ent dat e and t i me on t he scr een, ' we can see when t he cache i s bei ng i nval i dat ed l abel 1. Text = Dat eTi me. Now. ToSt r i ng( ) End Sub
Val i dat i on Cal l back
I n List ings 12.1 and 12.2, you can see t hat we st art off by specifying t he @Out put Cache direct ive wit h a durat ion of 10,000 seconds. This is plent y of t im e t o dem onst rat e t he validat ion callback. Also not ice t he fact t hat t he Var yByPar am at t ribut e is set t o none. Be sure not t o specify a * for t his at t ribut e—if you do, you will never be able t o reset t he correct out put cache. When t he cache is invalidat ed, it im m ediat ely st ores a new copy. Wit h t he * value for Var yByPar am, t he passwor d Quer ySt r i ng param et er would becom e part of t he new cache key. This is not t he desired out com e. You can set t he Var yByPar am at t ribut e t o specific Quer ySt r i ng param et ers. Just don’t include t he passwor d param et er as one of t hem . Below t he @Out put Cache direct ive, you define a handler for t he validat ion callback. I n it , you check for t he presence of t he passwor d Quer ySt r i ng param et er. I f it exist s, t hen you assign it t o t he passwor d variable. I f t he password is correct , you set an I nval i d st at us value t o t he val i dat i onSt at us variable. Ot herwise, you set a Val i d st at us value. Not ice t he use of a swi t ch st at em ent ( Case st at em ent , in Visual Basic .NET) inst ead of an i f st at em ent . As originally st at ed in Chapt er 4,“ code St ruct ure t hat Eases Debugging,” t his enhances t he readabilit y of t he code and enables you t o add m ore opt ions if needed at a lat er t im e. Next , you define your Page_Load event . You creat e an inst ance of t he Ht t pCacheVal i dat eHandl er delegat e, using t he address of t he handler funct ion j ust defined. You can t hen wire up t he callback t hrough t he AddVal i dat i onCal l back m et hod of t he Cache propert y of t he Response obj ect .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
To visually see when t he cache is being invalidat ed, you assign t he current dat e and t im e t o a label server cont rol on t he page. To see t he validat ion callback in act ion, you can navigat e t o t he page in your browser. The first t im e you hit t he page, it is st ored in cache. This is evident when you refresh t he page and t he sam e dat e and t im e appear on t he page. Now add t he passwor d=mypasswor d QuerySt ring param et er t o t he URL and hit t he Ent er key. You can see t hat t he cache is refreshed wit h a new version of t he page because t he dat e and t im e change. I f you now rem ove t he passwor d QuerySt ring param et er and hit t he Ent er key again, you’ll see t hat t he newly cached page is fet ched and displayed. By using t his t echnique, you can force a reset of t he out put cache, elim inat ing t he problem of invalid debugging dat a ( or any ot her incorrect dat a, for t hat m at t er) being t rapped in cache.
Th e Ca ch in g API The Caching API is m uch m ore flexible t han t he @Out put Cache direct ive, in t hat you are in direct cont rol of insert ing it em s int o cache and specifying exact ly when and how t hey should be rem oved. For t his reason, you will not run int o as m any issues while using t he Caching API . The t rade- off is t hat it is not quit e as convenient and it t akes a bit m ore code t o get working. This sect ion of t he chapt er helps you wit h som e of t he issues t hat you m ight encount er while using t he Caching API .
D e pe n de n cie s Set t ing up dependencies for cached it em s is usually pret t y st raight forward. A couple sit uat ions, however, m ight be a bit confusing. When you are set t ing up a file dependency, you m ight get an error t hat looks like t his: Except i on Det ai l s: Syst em. Web. Ht t pExcept i on: I nval i d f i l e name f or moni t or i ng: { 0} This error m eans t hat t he Cache obj ect cannot find t he file t hat you want t o base t he dependency on. The cause of t his error is alm ost always t hat you at t em pt ed t o use a virt ual pat h t o your dependency file or t hat you j ust specified a filenam e, wit hout a pat h. Unlike m ost ot her references in ASP.NET web applicat ions, file dependencies require you t o specify t hat absolut e pat h t o t he file. An easy way t o get t he absolut e pat h is t o use t he Ser ver . MapPat h( ) m et hod call. The code in List ings 12.3 and 12.4 dem onst rat es bot h t he incorrect and correct m et hods of specifying a file dependency. List in g 1 2 .3 W r on g a n d Righ t W a ys t o Use a File D e pe nde n cy ( C# )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
pr ot ect ed voi d Page_Load( obj ect sender , Event Ar gs e) { / / t hi s causes an er r or Cache. I nser t ( " someKey" , " someVal ue" , new Cac heDependency( " keyf i l e. t xt " ) ) ; / / t hi s i s t he cor r ect way Cache. I nser t ( " someKey" , " someVal ue" , new Cac heDependency( Ser ver . MapPat h( " keyf i l e. t xt " ) ) ) ; }
List in g 1 2 .4 W r on g a n d Righ t W a ys t o Use a File D e pe nde n cy ( Visu a l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( sender As Obj ect , E As Event Ar gs) ' t hi s causes an er r or Cache. I nser t ( " someKey" , " someVal ue" , _ new CacheDependency( " keyf i l e. t xt " ) ) ' t hi s i s t he cor r ect way Cache. I nser t ( " someKey" , " someVal ue" , _ new CacheDependency( Ser ver . MapPat h( " keyf i l e. t xt " ) ) ) End Sub
Som e t ricky sit uat ions can arise when you are at t em pt ing t o set up a dependency based on anot her it em in cache t hrough it s key. To do t his, you use t he overloaded signat ure of t he CacheDependency class t hat accept s t wo param et ers. Leave t he first param et er nul l ( unless you want t he dependency t o be file- based as well) . The second param et er is an array of st rings correlat ing t o t he keys upon which you want t his cached it em t o be dependent . The t ricky part com es in when you t ry t o base t he dependency on a single key. I deally, you could j ust specify t he single st ring value as a param et er. I f you do t his, however, you will get an error like t his: Compi l er Er r or Message: CS1502: The best over l oaded met hod mat ch f or ' Syst em. Web. Cachi ng. CacheDependency. CacheDependency( st r i ng[ ] , st r i ng[ ] ) ' ar gument s
has some i nval i d
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
or ( Visual Basic .NET) Compi l er Er r or Message: BC30311: A val ue of t ype ' St r i ng'
cannot be
conver t ed t o ' 1- di mensi onal Ar r ay of St r i ng' . Even t hough you are specifying only a single cache key as a dependency, it m ust st ill be in an array. List ings 12.5 and 12.6 provide exam ples of bot h incorrect and correct ways t o handle a single- cache key dependency: List in g 1 2 .5 W r on g a n d Righ t W a ys t o Use a Single - Ca ch e Ke y D e pe nde ncy ( C# )
pr ot ect ed voi d Page_Load( obj ect sender , Event Ar gs e) { / / t hi s causes an er r or Cache. I nser t ( " someKey" , " someVal ue" , new CacheDependency( nul l , " depKey" ) ) ; / / t hi s i s t he cor r ect way st r i ng[ ] dependency = { " depKey" } ; Cache. I nser t ( " someKey" , " someVal ue" , new CacheDependency( nul l , dependency) ) ; }
List in g 1 2 .6 W r on g a n d Righ t W a ys t o Use a Single - Ca ch e Ke y D e pe nde ncy ( Visu a l Ba sic .N ET)
Pr ot ect ed Sub Page_Load( sender As Obj ect , E As Event Ar gs) ' t hi s causes an er r or Cache. I nser t ( " someKey" , " someVal ue" , _ new CacheDependency( Not hi ng, " depKey" ) ) ' t hi s i s t he cor r ect way Di m dependency As St r i ng( ) = { " depKey" } Cache. I nser t ( " someKey" , " someVal ue" , _
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
new CacheDependency( Not hi ng, dependency) ) End Sub
A final point about dependencies t hat m ight cause you problem s is t hat t he Cache obj ect enables you t o set up a dependency on a cache key t hat does not exist . This m eans t hat t he it em t hat you are t rying t o insert int o t he cache is im m ediat ely invalidat ed. One suggest ion t o avoid t hat sit uat ion is t o check for t he exist ence of an it em in t he cache before you use it as a dependency for anot her it em . I nt erest ingly, if you set up a file- based dependency based on a file t hat doesn’t exist , t he it em I S is insert ed int o t he cache and can be referenced lat er.
D a t e a n d Tim e Ex pir a t ion s Two of t he overloaded signat ures of t he I nser t m et hod of t he Cache class, as well as one signat ure of t he Add m et hod, enable you t o specify an absolut e expirat ion dat e/ t im e for t he cached it em or a sliding expirat ion t im e. The key word t o not e in t he previous sent ence is or. I f you at t em pt t o specify bot h at t he sam e t im e, you will get t he following error m essage: Except i on Det ai l s: Syst em. Ar gument Except i on: absol ut eExpi r at i on must be Dat eTi me. MaxVal ue or sl i di ngExpi r at i on must be t i meSpan. Zer o. The error m essage t ells you t o use Dat eTi me. MaxVal ue or Ti meSpan. Zer o so t hat only an absolut e expirat ion or a sliding expirat ion is im plem ent ed. As an alt ernat ive, t he Cache. NoAbsol ut eExpi r at i on const ant can be used, which is equivalent t o Dat eTi me. MaxVal ue, and t he Cache. NoSl i di ngExpi r at i on const ant can be used, which is equivalent t o Ti meSpan. Zer o.
Re t r ie vin g Ca ch e d I t e m s Because all it em s ret urned from t he cache are of t he Obj ect t ype, you m ust cast it t o t he appropriat e t ype before assigning it , like t his: st r i ng someVal ue = Cache[ " someVal ue" ] . ToSt r i ng( ) ; / / C# or Di m someVal ue As St r i ng = Cache( " someVal ue" ) . ToSt r i ng( ) ' VB I f you do not cast it t o t he proper t ype and you are not assigning t he it em from Cache t o a variable of t he Obj ect t ype, you will get an error like t his:
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Compi l er Er r or Message: CS0029: Cannot i mpl i ci t l y conver t t ype ' obj ect ' t o ' st r i ng' I f you at t em pt t o ret rieve an it em from t he cache using a key t hat doesn’t exist , it does not generat e an error. I nst ead, it ret urns a nul l reference ( Not hi ng, in Visual Basic .NET) . I f t his is t he case, t hen when you at t em pt t o cast it t o t he proper t ype ( as you j ust saw) , you will get an error like t his: Except i on Det ai l s: Syst em. Nul l Ref er enceExcept i on: Val ue nul l was f ound wher e an i nst ance of an obj ect was r equi r ed. To get around t his, always verify t hat t he it em t hat you want t o ret rieve from t he cache exist s. The following code dem onst rat es t his: / / C# i f ( Cache[ “ someVal ue” ] ! ! = nul l ) { someVal ue = Cache[ “ someVal ue” ] . ToSt r i ng( ) ; } or ' Vi sual Basi c . NET I f Cache( " someVal ue" ) Not hi ng Then someVal ue = Cache( " someVal ue" ) . ToSt r i ng( ) End I f
Re m ovin g Ca ch e d I t e m s You can run int o t rouble if you at t em pt t o rem ove an it em from t he cache using an invalid key. This m ight happen m ore oft en t han you t hink because you can never t ell when a resource t hat t he cached it em is dependent on changes, t hereby evict ing it from t he cache. Norm ally, t he ret urn value of t he Remove m et hod of t he Cache class is t he it em t hat was rem oved from t he cache. I f t he key is invalid, however, t he ret urn value is nul l ( Not hi ng, in Visual Basic .NET) . Therefore, if you plan t o use t he it em t hat you are rem oving from t he cache, you should verify t hat it exist s first , using t he sam e m et hod dem onst rat ed previously.
Su m m a r y I n t his chapt er, we covered som e of t he m ore com m on problem s t hat you will encount er while leveraging caching in your web applicat ions. We st art ed wit h a look
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
at out put caching, using t he @Out put Cache direct ive at bot h t he page and user cont rol levels. Problem s associat ed wit h several of it s at t ribut es were discussed. We also covered t he error generat ed by m anipulat ing an out put cached user cont rol. Next , you learned how t o use validat ion callbacks t o m anually evict a page from t he out put cache. This capabilit y is key t o being able t o effect ively debug web applicat ions wit hout having t o worry about incorrect dat a being t rapped in cache. I t is also a useful feat ure t hat enables you t o m anually refresh an incorrect page t hat is in product ion. I ssues relat ed t o t he Caching API were discussed next . Specifically, you learned about t he int ricacies of bot h file- and key- based dependencies, as well as dat e and t im e expirat ions, and errors associat ed wit h ret rieving and rem oving it em s from t he cache. The next chapt er discusses Web Services in t he cont ext of debugging your ASP.NET web applicat ions.
Pa r t I V: D e bu gging Re la t e d Te ch n ologie s Part I V Debugging Relat ed Technologies 13 Debugging Web Services 14 Debugging .NET Com ponent s and Ht t pHandlers 15 COM+ I ssues 16 Debugging ADO.NET
Ch a pt e r 1 3 . D e buggin g W e b Se r vice s
WEB SERVI CES PROVI DE AN AMAZI NG NEW STRI DE forward in dist ribut ed archit ect ure. These new capabilit ies enable developers t o ext end t he reach of web applicat ions. They give you t he capabilit y t o reach any web server. But what about debugging a Web Service?
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
You probably have had t he pleasure of debugging a DLL. Debugging a Web Service m ight seem sim ilar, but t here are som e im port ant differences t o keep in m ind while doing t he debugging. This chapt er ident ifies t he key areas in building and debugging Web Services.We will show you what t ools are available and different t echniques t o assist you in finding t hose bugs.
W e b Se r vice s St u m blin g Block s Microsoft has done a great deal t o ease t he process of building Web Services, especially in Visual St udio .NET. But let ’s focus on using j ust t he .NET fram ework t ools here. First you’ll t ake a look at a sim ple Web Service. Then we’ll ident ify areas where you m ight have problem s. List ings 13.1–13.4 serve as exam ples of t he code t hat you will need t o get st art ed. List in g 1 3 .1 ASM X Code ( C# )
List in g 1 3 .2 Sim ple W e b Se r vice ( C# ) usi ng Syst em; usi ng Syst em. Web. Ser vi ces; namespace chap_13_c { / / Cr eat e a cl ass and i nher i t t he WebSer vi ce f unct i onal i t y publ i c cl ass Ti meSer vi ce : Syst em. Web. Ser vi ces. WebSer vi ce { / / Const r uct or publ i c Ti meSer vi ce( ) { } / / Thi s i s r equi r ed t o make t he f ol l owi ng met hod SOAP [ WebMet hod] publ i c st r i ng Get Ti me( ) { r et ur n Dat eTi me. Now. ToSt r i ng( ) ; } } }
enabl ed
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 3 .3 ASM X Code ( Visua l Ba sic .N ET)
List in g 1 3 .4 Sim ple W e b Se r vice ( Visua l Ba sic .N ET) I mpor t s Syst em I mpor t s Syst em. Web. Ser vi ces Publ i c Cl ass Ti meSer vi ce I nher i t s Syst em. Web. Ser vi ces. WebSer vi ce Publ i c Funct i on Get Ti me( ) As St r i ng Hel l oWor l d = Dat e. Now. ToSt r i ng( ) End Funct i on End Cl ass I f you look at List ings 13.1–13.4 , you will not ice t hat you have t o produce very lit t le code t o creat e a sim ple Web Service. Let ’s t ake a look at where you m ight run int o problem s and how t o resolve t hem .
Er r or M e ssa ge s You m ight run int o a variet y of error m essages, but we’ll t ry t o focus on som e of t he m ore com m on areas where problem s m ight arise. Let ’s st art off by looking at a couple com m on error m essages.You m ight run int o t his one right off t he bat : Syst em. I O. Fi l eI nf o cannot be ser i al i zed because i t does not have a def aul t publ i c const r uct or . I f you m anage t o get past t hat error, you m ight run int o t he following one: Syst em. Except i on: Ther e was an er r or gener at i ng t he XML document . – - > Syst em. Except i on: Syst em. I O. Fi l eI nf o cannot be ser i al i zed because i t does not have a def aul t publ i c const r uct or . at Syst em. Xml . Ser i al i zat i on. TypeScope. I mpor t TypeDesc( Type t ype, Bool ean canBePr i mi t i ve)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
at Syst em. Xml . Ser i al i zat i on. TypeScope. Get TypeDesc( Type t ype) at Syst em. Xml . Ser i al i zat i on. TypeScope. I mpor t TypeDesc( Type t ype, Bool ean canBePr i mi t i ve) at Syst em. Xml . Ser i al i zat i on. TypeScope. Get TypeDesc( Type t ype) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zat i onWr i t er . Cr eat eUnknownTypeEx cept i on( Type t ype) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zat i onWr i t er . Wr i t eTypedPr i mi t i ve( S t r i ng name, St r i ng ns, Obj ect o, Bool ean xsi Type) at n2499d7d93f f a468f bd8861780677ee41. Xml Ser i al i zat i onWr i t er 1. Wr i t e4_Ob j ect ( St r i ng n, St r i ng ns, Obj ect o, Bool ean i sNul l abl e, Bool ean needType) at n2499d7d93f f a468f bd8861780677ee41. Xml Ser i al i zat i onWr i t er 1. Wr i t e9_Ob j ect ( Obj ect o) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zer . Ser i al i ze( Xml Wr i t er xml Wr i t er , Obj ect o, Xml Ser i al i zer Namespaces namespaces) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zer . Ser i al i ze( Text Wr i t er t ext Wr i t er , Obj ect o) at Syst em. Web. Ser vi ces. Pr ot ocol s. Xml Ret ur nWr i t er . Wr i t e( Ht t pResponse r esponse, St r eam out put St r eam, Obj ect r et ur nVal ue) at Syst em. Web. Ser vi ces. Pr ot ocol s. Ht t pSer ver Pr ot ocol . Wr i t eRet ur ns( Obj ect [ ] r et ur nVal ues, St r eam out put St r eam) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . Wr i t eRet ur ns( Obj ect [ ] r et ur nVal ues) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . I nvoke( ) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . Cor ePr ocessRequest ( ) I f you get eit her of t hose m essages, whet her while your service is j ust st art ing or as you invoke t he m et hod t hat ret urns t he dat a t hat caused t he error, m ost likely you are t rying t o ret urn a com plex dat a set or array t hat t he syst em cannot serialize. I f you t ake a look at List ings 13.5 and 13.6, you can see t hat it would be easy t o overlook what t ype of dat a t he syst em can ret urn.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List ing 1 3 .5 Com ple x Re t ur n Type ( C# ) [ WebMet hod] publ i c Di r ect or yI nf o[ ] Di r ( st r i ng di r ) { Di r ect or yI nf o di = new Di r ect or yI nf o( di r ) ; Di r ect or yI nf o[ ] di Li st = di . Get Di r ect or i es( " * . * " ) ; r et ur n di Li st ; } List in g 1 3 .6 Com ple x Re t ur n Type ( Visua l Ba sic .N ET) Publ i c Funct i on Di r ( ByVal di r As St r i ng) As Di r ect or yI nf o( ) Di m di As New Di r ect or yI nf o( di r ) Di m di Li st as di . Get Di r ect or i es( " * . * " ) Ret ur n di Li st End Funct i on The code in List ings 13.5 and 13.6 looks fine, but it won’t work. So now what do you do? Well, one way t o work around t his is t o build your own array and t hen pass it back t o t he client . I f you do t his, you m ust m ake sure t hat t he array st ruct ure is published t o public so t hat t he users know what t hey are working wit h. This get s accom plished in List ings 13.7 and 13.8. List in g 1 3 .7 Cu st om Re t u r n Type ( C# ) usi ng Syst em; usi ng Syst em. Col l ect i ons; usi ng Syst em. Component Model ; usi ng Syst em. Dat a; usi ng Syst em. Di agnost i cs; usi ng Syst em. Web; usi ng Syst em. Web. Ser vi ces; usi ng Syst em. Xml . Ser i al i zat i on; usi ng Syst em. I O; namespace Di r ect or yTool s { / / /
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
/ / / Summar y descr i pt i on f or Ser vi ce1. / / / publ i c cl ass Ser vi ce1 : Syst em. Web. Ser vi ces. WebSer vi ce { publ i c Ser vi ce1( ) { / / CODEGEN: Thi s cal l i s r equi r ed by t he ASP. NET Web Ser vi ces Desi gner I ni t i al i zeComponent ( ) ; } #r egi on Component Desi gner gener at ed code / / / / / / Requi r ed met hod f or Desi gner suppor t - do not modi f y / / / t he cont ent s of t hi s met hod wi t h t he code edi t or . / / / pr i vat e voi d I ni t i al i zeComponent ( ) { } #endr egi on / / / / / / Cl ean up any r esour ces bei ng used. / / / pr ot ect ed over r i de voi d Di spose( bool di sposi ng ) { } / / WEB SERVI CE EXAMPLE / / The Hel l oWor l d( ) exampl e ser vi ce r et ur ns t he st r i ng Hel l o Wor l d / / To bui l d, uncomment t he f ol l owi ng l i nes and t hen save and bui l d t he pr oj ect / / To t est t hi s web ser vi ce, pr ess F5 [ WebMet hod] publ i c st r i ng Hel l oWor l d( ) { r et ur n " Hel l o Wor l d" ; } [ WebMet hod( ) ] [ Xml I ncl ude( t ypeof ( Di r Obj ect ) ) ] publ i c Di r Obj ect Test ( st r i ng sPat h)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
{ Di r ec t or yI nf o di = new Di r ect or yI nf o( sPat h) ; Di r ec t or yI nf o[ ] di Li st = di . Get Di r ect or i es( " * . * " ) ; Di r Obj ect t emp = new Di r Obj ect ( ) ; i nt x = 0; f or each ( Di r ect or yI nf o d i n di Li st ) { t emp[ x] = d; x++; } r et ur n t emp; } } [ Xml I ncl ude( t ypeof ( Di r I t em) ) ] publ i c cl ass Di r Obj ect { [ Xml El ement ( " I t em" ) ] publ i c Ar r ayLi st Dat a { get { r et ur n dat a; } set { dat a = val ue; } } pr ot ect ed Ar r ayLi st dat a = new Ar r ayLi st ( ) ; publ i c obj ect t hi s [ i nt i dx] { get { i f ( i dx > - 1 && i dx < dat a. Count ) { r et ur n ( dat a[ i dx] ) ; } el se r et ur n nul l ; } } set { i f ( i dx > - 1 && i dx < dat a. Count ) {
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
dat a[ i dx] = val ue; } el se i f ( i dx == dat a. Count ) { Di r I t em x = new Di r I t em( ) ; Di r ect or yI nf o t emp = ( Di r ect or yI nf o) val ue; x. Fi l eName = t emp. Ful l Name; dat a. Add( x) ; } el se { / / Possi bl y t hr ow an except i on her e. } } } } / / MyCl ass publ i c cl ass Di r I t em { pr ot ect ed st r i ng f i l ename; publ i c Di r I t em( ) { } [ Xml At t r i but e( " Fi l eName" ) ] publ i c st r i ng Fi l eName { get { r et ur n f i l ename; } set { f i l ename = val ue; } } } } / / Name space List in g 1 3 .8 Cu st om Re t u r n Type ( Visua l Ba sic .N ET) I mpor t s Syst em. Web. Ser vi ces I mpor t s Syst em. I O I mpor t s Syst em. Xml I mpor t s Syst em. Xml . Ser i al i zat i on
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Publ i c Cl ass Ser vi ce1 I nher i t s Syst em. Web. Ser vi ces. WebSer vi ce #Regi on " Web Ser vi ces Desi gner Gener at ed Code " Publ i c Sub New( ) MyBase. New( ) ' Thi s cal l i s r equi r ed by t he Web Ser vi ces Desi gner . I ni t i al i zeComponent ( ) ' Add your own i ni t i al i zat i on code af t er t he I ni t i al i zeComponent ( ) cal l End Sub ' Requi r ed by t he Web Ser vi ces Desi gner Pr i vat e component s As Syst em. Component Model . Cont ai ner ' Do not modi f y i t usi ng t he code edi t or . Pr i vat e Sub I ni t i al i zeComponent ( ) component s = New Syst em. Component Model . Cont ai ner ( ) End Sub Pr ot ec t ed Over l oads Over r i des Sub Di s pose( ByVal di sposi ng As Bool ean) ' Do not modi f y i t usi ng t he code edi t or . End Sub #End Regi on ' Publ i c Funct i on Test ( ByVal pat h As St r i ng) As Di r Obj ect Di m di As Di r ect or yI nf o = New Di r ect or yI nf o( pat h) Di m di Li st ( ) As Di r ect or yI nf o Di m d As Di r ect or yI nf o Di m t emp As Di r Obj ect = New Di r Obj ect ( ) Di m x As I nt eger = 0 di Li st = di . Get Di r ect or i es( " * . * " ) For Each d I n di Li st
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t emp( x) = d x = x + 1 Nex t Ret ur n t emp End Funct i on
Publ i c Cl ass Di r Obj ect Pr i vat e pdat a As Ar r ayLi st = New Ar r ayLi st ( ) Publ i c Pr oper t y Dat a( ) As Ar r ayLi st Get Ret ur n pdat a End Get Set ( ByVal Val ue As Ar r ayLi st ) pdat a = Val ue End Set End Pr oper t y Def aul t Publ i c Pr oper t y base( ByVal i dx As I nt eger ) As Obj ect Get I f ( i dx > - 1 And i dx < Dat a. Count ) Then Ret ur n pdat a( i dx) El se Ret ur n Not hi ng End I f End Get Set ( ByVal Val ue As Obj ect ) I f ( i dx > - 1 And i dx < pdat a. Count ) Then pdat a( i dx) = Val ue El seI f ( i dx = pdat a. Count ) Then Di m x As Di r I t em = New Di r I t em( ) Di m t emp As Di r ect or yI nf o t emp = CType( Val ue, Di r ect or yI nf o)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
x. Fi l eName = t emp. Ful l Name x. Last AccessDat e = t emp. Last AccessTi me pdat a. Add( x) El se ' Possi bl y t hr ow an except i on her e. End I f End Set End Pr oper t y End Cl ass Publ i c Cl ass Di r I t em Pr i vat e pf i l ename As St r i ng Pr i vat e pLast AccessDat e As Dat e Sub Di r I t em( ) End Sub Publ i c Pr oper t y Fi l eName( ) As St r i ng Get Ret ur n pf i l ename End Get Set ( ByVal Val ue As St r i ng) pf i l ename = Val ue End Set End Pr oper t y Publ i c Pr oper t y Last AccessDat e( ) As Dat e Get Ret ur n pLast AccessDat e End Get Set ( ByVal Val ue As Dat e) pLast AccessDat e = Val ue End Set End Pr oper t y
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
End Cl ass End Cl ass I n List ings 13.7 and 13.8, you will not ice a few new elem ent s t hat you m ight not have seen before: and . These addit ional feat ures define t he out put when t his class is serialized. This is a great way t o renam e elem ent s in t he XML st ruct ure t o som et hing m ore m eaningful.
Pr oble m s W or k in g w it h XM LSe r ia lize r You j ust saw one way t o pass back dat a, but you m ight say t hat it involves a bit of work; t here m ust be a sim pler way t o do it . Why not use t he XMLSer i al i zer class t o generat e t he ret urning dat a in an XML valid form at ? Well, if you t ry t his, you m ight get t he following error m essage: Syst em. Except i on: Ther e was an er r or r ef l ect i ng ' Syst em. I O. Di r ect or yI nf o' . –- > Syst em. Except i on: Syst em. I O. Di r ect or yI nf o cannot be ser i al i zed becaus e i t does not have a def aul t publ i c const r uct or . at Syst em. Xml . Ser i al i zat i on. TypeScope. I mpor t TypeDesc( Type t ype, Bool ean canBePr i mi t i ve) at Syst em. Xml . Ser i al i zat i on. TypeScope. Get TypeDesc( Type t ype) at Syst em. Xml . Ser i al i zat i on. Model Scope. Get TypeModel ( Type t ype) at Syst em. Xml . Ser i al i zat i on. Xml Ref l ect i onI mpor t er . I mpor t TypeMappi ng( Type t ype, Xml Root At t r i but e r oot , St r i ng def aul t Namespace) at Syst em. Xml . Ser i al i zat i on. Xml Ref l ect i onI mpor t er . I mpor t TypeMappi ng( Type t ype, Xml Root At t r i but e r oot , St r i ng def aul t Namespace) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zer . . ct or ( Type t ype) at chapt er 13_c. Ser vi ce1. Di r ( St r i ng di r ) i n c: \ document s and set t i ngs\ br ad\ vswebcache\ di gi t al - l apt op\ chapt er 13_c\ ser vi ce1. asmx. cs: l i ne 110 Let ’s look at t he line of code where t he error occurred and see why t his is happening. List ings 13.9 and 13.10 provide a fix. List in g 1 3 .9 Fix for t h e XM LSe r ia lize r pr oble m ( C# )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
[ WebMet hod] publ i c Obj ect [ ] Di r ( st r i ng di r ) { Xml Ser i al i zer ser i al i zer =
new
Xml Ser i al i zer ( t ypeof ( Di r ect or yI nf o) ) ; Ret ur n ser i al i zer ; } List in g 1 3 .1 0 Fix for t h e XM LSe r ia lize r pr oble m ( Visu a l Ba sic .N ET) Publ i c Funct i on Di r ( ByVal di r name As St r i ng) As Obj ect ( ) Di m s er i al i zer = new Xml Ser i al i zer ( t ypeof ( Di r ect or yI nf o) ) Ret ur n ser i al i zer End Funct i on The Xml Ser i al i zer cannot serialize t he st ruct ure int o XML. That is why you m ust define t he different classes t o m im ic t he Di r ect or yI nf o obj ect .
W or k in g w it h Er r or s in SOAP While working wit h Web Services, you event ually will need t o handle errors in a m ore const ruct ive way. The quest ion is, how do you want t o handle t he errors t hat pop up? The following error m essage is an exam ple of what you would see if you did not have any m echanism for handling errors: Syst em. I ndexOut Of RangeExcept i on: Except i on of t ype Syst em. I ndexOut Of RangeExcept i on was t hr own. at chap_13_c. Ti meSer vi ce. Er r or St r i ng( ) i n c: \ i net pub\ wwwr oot \ chap_13_c\ ser vi ce1. asmx. cs: l i ne 38 This error m essage is t ypical of what you would see if your Web Service ran int o an error. To keep t his from happening, List ings 13.11 and 13.12 show a sim ple exam ple t o cat ch t he error and ret urn it inside t he cont ent s of t he SOAP m essage. List in g 1 3 .1 1 W e bM e t h od Er r or ( C# ) [ WebMet hod] publ i c obj ect Ret ur nEr r or St r i ng( ) { / / Cat ch t he er r or t hen r et ur n i t i nsi de a SOAP message. st r i ng[ ] sr et = new st r i ng[ 3] ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
try { sr et [ 0] = " one" ; sr et [ 1] = " t wo" ; sr et [ 3] = " t hr ee" ; / / Er r or } cat c h( Except i on e) { sr et [ 0] = e. Message; } r et ur n sr et ; } List in g 1 3 .1 2 W e bM e t h od Er r or ( Visu a l Ba sic .N ET) Publ i c Funct i on Er r or St r i ngCat ch( ) As St r i ng( ) ' Cat ch t he er r or t hen r et ur n i t i nsi de a SOAP message. Di m sr et ( 3) As St r i ng Tr y sr et ( 0) = " Hel l o" sr et ( 1) = " Bye" sr et ( 13) = " Test i ng" ' Thi s wi l l gener at e an er r or
Cat ch e As Except i on sr et ( 0) = e. Message End Tr y Er r or St r i ngCat ch = sr et End Funct i on I f you look closely at t he code in List ings 13.11 and 13.12, you will not ice t hat we int ent ionally added a runt im e error while adding t he t hird it em t o t he array. Now when you run int o an error, it will be ret urned inside t he SOAP m essage. This is one way t o approach handling errors and sending t hem back t o t he client , but t his is not t he preferred m et hod for doing so. I nst ead, one of t wo t hings should be done. First , you cannot cat ch t he except ion t hat will send it back t o t he client t o handle. Second, you can ident ify what t he problem is inside t he cat ch and t ry t o resolve t he problem or t hrow anot her except ion t hat will be sent back t o t he client . This gives you t he capabilit y t o ident ify t he error inside your Web Service client and deal wit h
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
it t here. Ot herwise, if you j ust ret urned t he error m essage inside t he array, you would need t o check t he first it em of t he array and t ry t o ident ify whet her it is an error m essage. I f you did t his, t he ret urn m essage m ight look som et hing like List ing 13.13. List in g 1 3 .1 3 SOAP Re t u r n Va lue s
Except i on of t ype Syst em. I ndexOut Of RangeExcept i on was t hr own. Bye xml ns: xsd=" ht t p: / / www. w3. or g/ 2001/ XMLSchema" n1: ni l =" t r ue" />
What if you are working only wit h num bers? Then how do you go about sending back error m essages? I f you look at List ings 13.14 and 13.15, you will see t hat you can use t he t r y- cat ch m et hod and t hen ret hrow t he error. List in g 1 3 .1 4 Th r ow Ex ce pt ion ( C# ) [ WebMet hod] publ i c obj ect Ret ur nEr r or St r i ng( ) { / / Cat ch t he er r or t hen r et ur n i t i nsi de a SOAP message. st r i ng[ ] sr et = new st r i ng[ 3] ; try { sr et [ 0] = " one" ; sr et [ 1] = " t wo" ; sr et [ 3] = " t hr ee" ; / / Er r or } cat c h( Except i on e) { Thr ow( e) ; / / Ret ur n t he except i on t o t he cl i ent } r et ur n sr et ; } List in g 1 3 .1 5 Th r ow Ex ce pt ion ( Visu a l Ba sic .N ET)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Publ i c Funct i on Er r or St r i ngCat ch( ) As St r i ng( ) ' Cat ch t he er r or t hen r et ur n i t i nsi de a SOAP message. Di m sr et ( 3) As St r i ng Tr y sr et ( 0) = " Hel l o" sr et ( 1) = " Bye" sr et ( 13) = " Test i ng" ' Thi s wi l l gener at e an er r or
Cat c h e As Except i on Thr ow( e) ' Ret ur n t he except i on t o t he cl i ent End Tr y Er r or St r i ngCat ch = sr et End Funct i on I f you look at t he Cat ch st at em ent , t he Throw m et hod is being called t o pass t he error on t o t he client . By adding t his line of code, you change t he behavior of t he Web Service dram at ically. A sim ple change in one line of code can m ake a world of difference when it com es t o debugging. Don’t forget t hat you need t o use t he t r y- cat ch st at em ent on t he client side as well, t o be able t o handle t he except ion being passed back by t he server. To show how t he client should be im plem ent ed, t ake a look at t he code in List ings 13.16 and 13.17. List in g 1 3 .1 6 Th e t r y- ca t ch St a t e m e n t on t h e Clie n t Side ( C# ) pr i vat e voi d But t on2_Cl i ck( obj ect sender , Syst em. Event Ar gs e) { try { l ocal hos t . Ser vi ce1 s = new l ocal host . Ser vi ce1( ) ; s. Er r or St r i ngCat ch ( ) ; } cat ch( Except i on ex) { Text Box1. Text = ex. Message; } }
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 3 .1 7 Th e t r y- ca t ch St a t e m e n t on t h e Clie n t Side ( Visua l Ba sic .N ET) Pr i vat e Sub But t on1_Cl i ck( ByVal sender As Syst em. Obj ect , ByVal e As Syst em. Event Ar gs) Handl es But t on1. Cl i ck Tr y l ocal host . Ser vi ce1( s = New l ocal host . Ser vi ce1( ) ) s. Er r or St r i ngCat ch( ) cat ch( Except i on ex) Text Box1. Text = ex. Message End Tr y End Sub I n List ings 13.16 and 13.17, t he user clicks t he but t on t o invoke t he m et hod of t he Web Service. I f t here is an error on t he server side, t he Web Service passes back t he error inform at ion, and it can be received in t he cat ch st at em ent .When an error does get caught , it is displayed in t he t ext box t hat is on t he page.
Er r or Re t u r nin g Ce r t a in Type s of D a t a One of t he errors we ran int o was sim ple because we were not paying at t ent ion t o t he det ails of t he code. The code com piled fine—we’re not sure whet her it was a com piler issue or, as a soft ware developer would say, it is a problem “ as designed,” m eaning t hat t his is t he way it is supposed t o be. Take a look at t he following error m essage and see if you can ident ify why we received t his m essage: Syst em. Except i on: Ther e was an er r or gener at i ng t he XML document . –- > Syst em. Except i on: The t ype Syst em. Obj ect [ ] may not be used i n t hi s cont ext . . at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zat i onWr i t er . Wr i t eTypedPr i mi t i ve( S t r i ng name, St r i ng ns, Obj ect o, Bool ean xsi Type) at n2499d7d93f f a468f bd8861780677ee41. Xml Ser i al i zat i onWr i t er 1. Wr i t e1_Ob j ect ( St r i ng n, St r i ng ns, Obj ect o, Bool ean i sNul l abl e, Bool ean needType) at n2499d7d93f f a468f bd8861780677ee41. Xml Ser i al i zat i onWr i t er 1. Wr i t e3_Ob j ect ( Obj ect o)
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zer . Ser i al i ze( Xml Wr i t er xml Wr i t er , Obj ect o, Xml Ser i al i zer Namespaces namespaces) at Syst em. Xml . Ser i al i zat i on. Xml Ser i al i zer . Ser i al i ze( Text Wr i t er t ext Wr i t er , Obj ect o) at Syst em. Web. Ser vi ces. Pr ot ocol s. Xml Ret ur nWr i t er . Wr i t e( Ht t pResponse r esponse, St r eam out put St r eam, Obj ect r et ur nVal ue) at Syst em. Web. Ser vi ces. Pr ot ocol s. Ht t pSer ver Pr ot ocol . Wr i t eRet ur ns( Obj ect [ ] r et ur nVal ues, St r eam out put St r eam) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . Wr i t eRet ur ns( Obj ect [ ] r et ur nVal ues) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . I nvoke( ) at Syst em. Web. Ser vi ces. Pr ot ocol s. WebSer vi ceHandl er . Cor ePr ocessRequest ( ) This m essage cont ains a lot of repet it ive inform at ion here, but it also has som e very specific bit s t hat narrow down where t he problem is com ing from .You’ll not ice t hat Obj ect and Ser i al i ze are used several t im es. Now you know from t he error m essage at t he beginning t hat t he problem originat es wit h t he Syst em. Obj ect class. Passing sim ple t ypes back and fort h is very sim ple t o do. Now you are t aking t he next st ep t o passing arrays in Web Services.When working wit h any sort of array, you m ust m ake sure t o define your WebMet hod as ret urning an array, not j ust a single value or obj ect . List ings 13.18–13.21 give som e exam ples of problem s t hat you m ight run int o when ret urning array’s of obj ect s. List in g 1 3 .1 8 Code w it h Er r or ( C# ) [ WebMet hod] publ i c obj ect Er r or St r i ngCat ch( ) / / Mi ssi ng [ ] f r om obj ect List in g 1 3 .1 9 Cor r e ct Synt a x ( C# ) [ WebMet hod] publ i c obj ect [ ] Er r or St r i ngCat ch( ) List in g 1 3 .2 0 Code w it h Er r or ( Visua l Ba sic .N ET) Publ i c Funct i on Er r or St r i ngCat ch( ) As Obj ect
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g 1 3 .2 1 Cor r e ct Synt a x ( Visu a l Ba sic .N ET) Publ i c Funct i on Er r or St r i ngCat ch( ) As Obj ect ( ) This m ight seem like a t rivial it em , but don’t forget t hat m ost errors t hat you will run int o probably are sim ple errors t hat you overlooked.
W or k in g w it h St r e a m s While playing around wit h Web Services, you m ight have experim ent ed wit h different t ypes of dat a t hat could be ret urned by a Web Service. I f you t ried t o do som e basic funct ions such as get t ing a direct ory list ing or finding out som e inform at ion on a file, you m ight have run int o som e problem s. List ings 13.22 and 13.23 give a sim ple exam ple of how you m ight at t em pt t o pass back a Fi l eSt r eam obj ect . List in g 1 3 .2 2 Ge t File W e bM e t h od ( C# ) [ WebMet hod] publ i c Fi l eSt r eam Get Fi l e( ) { Fi l eSt r eam f s = new Fi l eSt r eam( " c: \ \ wi nnt \ \ gr eenst one. bmp" , Fi l eMode. Open) ; byt e[ ] buf ; / / = new byt e[ f s. Lengt h] ; buf = new Byt e[ f s. Lengt h] ; f s. Read( buf , 0, ( i nt ) f s. Lengt h) ; r et ur n f s; } List in g 1 3 .2 3 Ge t File W e bM e t h od ( Visua l Ba sic .N ET) publ i c f unct i on Get Fi l e( ) as Fi l eSt r eam Fi l eSt r eam f s = new Fi l eSt r eam( " c: \ \ wi nnt \ \ gr eenst one. bmp" , Fi l eMode. Open) ; Di m buf ( ) as byt e( ) ; / / = new byt e[ f s. Lengt h] ; buf = new Byt e( f s. Lengt h) ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
f s. Read( buf , 0, f s. Lengt h) ; r et ur n f s; End Funct i on The code in List ings 13.22 and 13.23 looks like it should work. But when you t ry t o use it , you end up get t ing an error. Take a look at t he error shown in Figure 13.1 t o see what t he end result will be. Figur e 1 3 .1 . Se r ia liza t ion pr oble m s.
This error seem s t o be very popular wit h Web Services, but each case needs t o be handled in a different way because Web Services need t o pass t he dat a in one of t wo basic form s: t ext or binary. As for t he t ext form at it , needs t o be in an XML form at of som e sort . The dat a form at can be binary or, in t his case, an array of byt es. There is a sim ple resolut ion t o t his problem . Because you are already dealing wit h an array of byt es, j ust pass t hat array back t o t he client . Take a look at List ings 13.24 and 13.25 t o see how t his would be done in t he code. List in g 1 3 .2 4 Re t ur n in g Bina r y D a t a ( C# ) [ WebMet hod] publ i c Byt e[ ] Get Fi l e( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
{ Fi l eSt r eam f s = new Fi l eSt r eam( " c: \ \ wi nnt \ \ gr eenst one. bmp" , Fi l eMode. Open) ;
byt e[ ] buf ; buf = new Byt e[ f s. Lengt h] ; br . Read( buf , 0, ( i nt ) f s. Lengt h) ; f s. Cl ose( ) ; r et ur n buf ; } List in g 1 3 .2 5 Re t ur n in g Bina r y D a t a ( Visua l Ba sic .N ET) publ i c Funct i on Get Fi l e( ) as Byt e( ) Fi l eSt r eam f s = new Fi l eSt r eam( " c: \ \ wi nnt \ \ gr eenst one. bmp" , Fi l eMode. Open)
Di m buf as byt e( ) buf = new Byt e( f s. Lengt h) br . Read( buf , 0, f s. Lengt h) f s. Cl ose( ) r et ur n buf ; End Funct i on Wit h a sim ple change t o t he way t he m et hod ret urns t he dat a, t he problem is solved. As you can see, you sim ply need t o change t he ret urn t ype of t he m et hod t o an array of byt es. Not all your problem s will be t his sim ple t hough. I f you st art playing around wit h t he writ ing of t he array of byt es, you m ight run int o t he error m essage shown in Figure 13.2, as we did. Figur e 1 3 .2 . W r it in g t o a bina r y file .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you t ake a close look at List ings 13.26 and 13.27, you will not ice t hat we were t rying t o change t he offset of where t he file st art ed t o writ e. List in g 1 3 .2 6 Offse t Er r or ( C# ) pr i vat e voi d But t on1_Cl i ck( obj ect sender , Syst em. Event Ar gs e) { l ocal host . Ser vi ce1 svc = new l ocal host . Ser vi ce1( ) ; Byt e[ ] ba = svc. Get Pi ct ur e( ) ; Fi l eSt r eam f s = new Fi l eSt r eam( " c: \ \ downl oad\ \ my. bmp" , Fi l eMode. Cr eat e, Fi l eAccess. Wr i t e) ; f s. Wr i t e( ba, 1, ba. Lengt h) ; / / er r or on t he of f set f s. Cl ose( ) ; } List in g 1 3 .2 7 Offse t Er r or ( Visu a l Ba sic .N ET) pr i vat e Funct i on But t on1_Cl i ck( sender as obj ect , e as Syst em. Event Ar gs ) di m svc as new l ocal host . Ser vi ce1( ) di m ba as byt e( ) ba = svc. Get Pi ct ur e( ) Di m f s as new Fi l eSt r eam( " c: \ \ downl oad\ \ my. bmp" , Fi l eMode. Cr eat e, Fi l eAccess. Wr i t e) f s. Wr i t e( ba, 1, ba. Lengt h) ‘ Er r or on t he of f set f s. Cl ose( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
end Funct i on
Tools Microsoft has provided som e addit ional t ools t o sim plify t he process of consum ing or building client applicat ions for Web Services. I f you are using Visual St udio .NET, som e of t hese t ools won’t be necessary t o use because Visual St udio .NET has m ost of t hese com m and- line t ools built int o t he I DE.
W h a t Sh ou ld I Use —W SD L.e x e or Soa pSu ds.e x e ? I f you are having problem s using t he WSDL.exe t ool t o generat e a proxy class for you, t ry using t he Soapsuds.exe program . Because SOAP and rem ot ing are basically t he sam e t hing, t he Soapsuds t ool also can generat e t he source code t o com m unicat e wit h t he Web Service. Soa psu ds.e x e The Soapsuds t ool helps you com pile client applicat ions t hat com m unicat e wit h Web Services using a t echnique called rem ot ing. Soapsuds.exe perform s t he following funct ions: • •
I t creat es XML schem as describing services exposed in a com m on language runt im e assem bly. I t creat es runt im e assem blies t o access services described by XML schem as. A schem a definit ion can be a local file, or it can be dynam ically downloaded from t he I nt ernet .
W SD L.e x e The Web Services Descript ion Language t ool generat es code for ASP.NET Web Services and Web Service client s from WSDL cont ract files, XSD schem as, and .discom ap discovery docum ent s.
W e b Se r vice D e scr ipt or La n gu a ge The WSDL file provides you wit h all t he necessary int erface inform at ion t o consum e a Web Service. One problem t hat you m ight run int o is t hat t here are different versions of WSDL float ing around. So far, t he lat est version is WSDL 1.1 , but we’ll t ake a look here at how t hese differences can affect your client ’s com m unicat ion wit h t he Web Service.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Many sit es on t he web prom ot e Web Services, but if you t ry t o run t he WSDL.exe t ool t o generat e a proxy st ub for yourself, it m ight give you one of m any errors. This is because t here are several versions of WSDL or SDL or even SDC. The WSDL t ool is designed t o work wit h wsdl 1.1. I f you t ry t o use t he WSDL.exe t ool on a WSDL file and it gives you an error, t hat is probably because t he files versions are different . Er r or s W h ile Usin g W SD L.e x e One of t he m ost com m on problem s t hat you m ight run int o involves t rying t o generat e t he proxy code for a rem ot e Web Service. Because t his is an evolving t echnology, people are building Web Services and put t ing t hem on t he web as fast as t hey can m ake t hem . This is great in som e cases because t his provides developers wit h m any consum able resources. But , on t he flip side, t he t echnology and st andards for SOAP are evolving j ust as fast . As soon as you get a new Web Service out t here, a newer version of t he st andard m ight have been released. So now t here is t he issue of different form at s ( SDC, SDL,WSDL- 1.0/ 1.1) float ing around on t he web.
Un ive r sa l D iscove r y D e scr ipt or I n t e r fa ce ( UD D I ) You will st art t o run int o t he Universal Discovery Descript or I nt erface ( UDDI ) m ore oft en. This is yet anot her new st andard being developed for SOAP- enabled users t o find and use ot her SOAP- enabled users—or, m ore likely, businesses. The best way t o look at UDDI is as t he Yellow Pages for Web Services.
Ba sic W e b Se r vice s D e bu ggin g As wit h any program , you can use som e com m on m et hods, no m at t er what t ype of environm ent you are in. The m ost basic of t hese involves logging all your debugging inform at ion t o a file t hat can be reviewed lat er. Because t he Web Service has very lit t le int eract ion wit h t he user int erface, t his is one approach t o t ake. The ot her approach is t o build your own except ion class t hat you can cust om ize. Then, whenever an error occurs ,you can t hrow your cust om except ion.
Com m on SOAP Er r or s You m ight encount er t his com m on error: The under l yi ng connect i on was cl osed: Unabl e t o connect t o t he r emot e ser ver . "
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
This is t ypically t he result of problem s on t he net work, not necessarily in your code. But don’t rule out your code—have som eone else look at it t o see if you have overlooked som et hing. A second pair of eyes is always beneficial. Anot her error is t he SoapExcept i on error, which looks like t his: The r equest r eached t he ser ver machi ne, but was not pr ocessed successf ul l y . I f you run int o t his one, you m ight be wondering, what wasn’t processed successfully? Why didn’t it t ell m e what wasn’t processed? I f you are using t he st andard except ion class t o handle errors, you could be m issing out on som e im port ant inform at ion provide by t he SoapExcept i on class. Let ’s t ake a closer look at t his class in t he next sect ion.
Ge t t in g t h e M ost Ou t of Soa pEx ce pt ion Up t o t his point , you have looked at various problem s t hat m ight arise and learned how t o work around t hem . But one of t he key elem ent s of debugging Web Services is t he SoapExcept i on class. Not only does t he class handle except ions t hat were t hrown, but , wit hin t he propert ies of t he except ion, t here are som e very useful pieces of dat a t hat can help t o ident ify what t he problem is. Take a look at List ings 13.28 and 13.29 t o see how you can use t he SoapExcept i on class t o cat ch errors. List in g 1 3 .2 8 Using Soa pEx ce pt ion ( C# ) pr i vat e voi d But t on2_Cl i ck( obj ect sender , Syst em. Event Ar gs e) { try { l ocal host . Ser vi ce1 s = new l ocal host . Ser vi ce1( ) ; s. Hel l oWor l d( 2) ; / / Thi s wi l l t hr ow an except i on
} cat ch( SoapExcept i on ex) { / / Di spl ay t he mai n message Text Box 2. Text = ex. Message; / / Get any addi t i onal det ai l ed i nf or mat i on Syst em. Xml . Xml Node xn = ex. Det ai l ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
/ / How many At t r i but es ar e t her e Text Box 3. Text = xn. At t r i but es. Count . ToSt r i ng( ) ; / / The name of t he app or obj ect t hat caused t he pr obl em Text Box4. Text = ex. Sour ce; / / Di spl ay t he pi ec e of code t hat caused t he pr obl em Text Box5. Text = ex. Act or ; / / Get t he t ype of SOAP f aul t code Syst em. Xml . Xml Qual i f i edName qn = ex. Code; / / Get t he XML qual i f i ed name Text Box6. Text = qn. Name; / / Get t he XML namespace Text Box7. Text = qn. Namespace; / / Get t he met hod t hat t hr ows t he except i on Syst em. Ref l ect i on. Met hodBase r = ex. Tar get Si t e; Syst em. Type st = r . Decl ar i ngType; / / Get t he assembl y name wher e t he except i on came f r om Text Box8. Text = st . Assembl yQual i f i edName;
}
} List in g 1 3 .2 9 Using Soa pEx ce pt ion ( Visu a l Ba sic .N ET) Pr i vat e Sub But t on2_Cl i ck( ByVal sender As Obj ect , ByVal e As Syst em. Event Ar gs) Tr y l ocal host . Ser vi ce1( s = New l ocal host . Ser vi ce1( ) ) s. Hel l oWor l d( 2) ' Thi s wi l l t hr ow an except i on
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
cat ch( SoapExcept i on ex) ' Di spl ay t he mai n message Text Box2. Text = ex. Message ' Get any addi t i onal det ai l ed i nf or mat i on Syst em. Xml . Xml Node( xn = ex. Det ai l ) ' How many At t r i but es ar e t her e Text Box3. Text = xn. At t r i but es. Count . ToSt r i ng( ) The name of t he app or obj ect t hat caused t he pr obl em Text Box4. Text = ex. Sour ce ' Di spl ay t he pi ece of code t hat c aused t he pr obl em Tex t Box5. Tex t = ex. Act or ' Get t he t ype of SOAP f aul t code Di m qn As Syst em. Xml . Xml Qual i f i edName qn = ex. Code ' Get t he XML qual i f i ed name Text Box6. Text = qn. Name ' Get t he XML namespace Text Box7. Text = qn. Namespace ' Get t he met hod t hat t hr ows t he except i on Di m r As Syst em. Ref l ect i on. Met hodBase r = ex. Tar get Si t e Di m st As Syst em. Type s t = r . Decl ar i ngType ' Get t he as sembl y name wher e t he exect i on came f r om Text Box8. Text = st . Assembl yQual i f i edName End Tr y End Sub
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List ings 13.28 and 13.29 dem onst rat e how t o ext ract t he addit ional elem ent s t hat are part of t he SoapExcept i on class. These addit ional propert ies could help you ident ify t he problem , eit her direct ly or indirect ly.
Pr oble m s D e ployin g You r W e b Se r vice ? When you are ready t o deploy your Web Service, t here is not very m uch t hat you need t o do. But you st ill m ight run int o som e problem s. Aft er you have developed you Web Service, copy all t he files and subdirect ories t o t he server t hat t he service will be host ed on. One of t he first t hings t hat you should check is t hat t he .NET fram ework is inst alled on t he server where you are deploying your Web Service. I f it is not on t hat server, your Web Service will not work.
Su m m a r y Web Services are an excit ing new developm ent in t he dist ribut ed applicat ion space. As you can see, creat ing a Web Service can be very sim ple, but as soon as you st art t o push t he lim it s of t he t echnology, you need t o roll up your sleeves and do t he rest of t he work. This becom es m ore apparent when you st art t rying t o ret urn com plex st ruct ures of dat a such as Fi l eSt r eams and Di r ect or yI nf o obj ect s. Many com ponent s can be serialized int o XML, but t hat ’s not t rue for everyt hing yet . You have t o adm it t hat Microsoft has done a good j ob so far, t hough. I f you really look at t he am ount of work t hat m ust have been put int o .NET t o m ake all of t his work, it is really ast onishing. I n Chapt er 14 we m ove on int o debugging of t he .NET com ponent s.
Ch a pt e r 1 4 . D e buggin g .N ET Com pon e n t s a n d H t t pH a n dle r s
COMPONENTS ARE THE HEART OF THE .NET fram ework. Sooner or lat er you will need t o creat e a com ponent t o accom plish a unique t ask. But how do you debug a com ponent ? Let ’s t ake a look at som e t echniques t hat you can use and som e com m on pit falls t hat you m ight run int o.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Th e Com pon e n t You’ll st art by creat ing a sim ple com ponent wit h a m et hod t hat ret urns t he dat e. This is t he m inim al am ount of code t o creat e a basic com ponent in t he .NET fram ework. As you look at t he list ings t hat follow, t ake not ice of which class was inherit ed, and keep your eyes open for areas in t he code t hat use t he Cont ai ner class; t his plays an im port ant role in a com ponent . Also t ake a closer look at t he Component Model nam espace—t his will give you a bet t er idea of t he core pieces t hat m ake up a com ponent , not j ust a class ( See List ings 14.1 and 14.2) . List in g 1 4 .1 Ba sic Com pon e n t ( C# ) usi ng Syst em; usi ng Syst em. Component Model ; usi ng Syst em. Col l ect i ons; usi ng Syst em. Di agnost i cs; namespace WebPr oj ect 1 { / / / / / / Summar y descr i pt i on f or Dat eSt uf f . / / / publ i c cl ass Dat eSt uf f : Syst em. Component Model . Component { / / / / / / Requi r ed desi gner var i abl e. / / / pr i vat e Syst em. Component Model . Cont ai ner component s = nul l ; publ i c Dat eSt uf f ( Syst em. Component Model . I Cont ai ner cont ai ner ) { / / / / / / Requi r ed f or Wi ndows. For ms Cl ass Composi t i on Desi gner suppor t / / / cont ai ner . Add( t hi s) ; I ni t i al i zeComponent ( ) ; // / / TODO: Add any const r uct or code af t er I ni t i al i zeComponent cal l // } publ i c Dat eSt uf f ( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
{ / / / / / / Requi r ed f or Wi ndows. For ms Cl ass Composi t i on Desi gner suppor t / / / I ni t i al i zeComponent ( ) ; / / TODO: Add any const r uct or code af t er I ni t i al i zeComponent cal l } / / / / / / Requi r ed met hod f or Desi gner suppor t - do not modi f y / / / t he cont ent s of t hi s met hod wi t h t he code edi t or . / / / pr i vat e voi d I ni t i al i zeComponent ( ) { component s = new Syst em. Component Model . Cont ai ner ( ) ; } publ i c st r i ng Get Today( ) { r et ur n Dat eTi me. Now. ToSt r i ng( ) ; } } } List in g 1 4 .2 Ba sic Com pon e n t ( Visua l Ba sic .N ET) Publ i c Cl ass get dat e I nher i t s Syst em. Component Model . Component
Publ i c Over l oads Sub New( Cont ai ner As Syst em. Component Model . I Cont ai ner ) MyCl ass. New( ) ' Requi r ed f or Wi ndows. For ms Cl ass Composi t i on Desi gner suppor t Cont ai ner . Add( me) End Sub Publ i c Over l oads Sub New( ) MyBase. New( ) ' Thi s cal l i s r equi r ed by t he Component Desi gner . I ni t i al i zeComponent ( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
' Add any i ni t i al i zat i on af t er t he I ni t i al i zeComponent ( ) cal l End Sub ' Requi r ed by t he Component Desi gner Pr i vat e component s As Syst em. Component Model . Cont ai ner ' NOTE: The f ol l owi ng pr ocedur e i s r equi r ed by t he Component Desi gner ' I t can be modi f i ed usi ng t he Component Desi gner . ' Do not modi f y i t usi ng t he code edi t or . Pr i vat e Sub I ni t i al i zeComponent ( ) component s = New Syst em. Component Model . Cont ai ner ( ) End Sub
Publ i c Funct i on Get Dat e( ) As St r i ng Get Dat e = Dat eTi me. Now End Funct i on End Cl ass Added in t his com ponent is a sim ple m et hod t o ret urn t oday’s dat e and t im e in a st ring. I t ’s not m uch, but it ’s a st art for now. You can use several different classes in t he Syst em .Diagnost ic nam espace, including St ackt r ace, Tr aci ng, t he gui - debugger , Debug, and Debugger . Let ’s t ake a look at how you can use t hese classes t o help t rack down bugs. I f you are working on t he server in which t he com ponent is running, t hen you can use t he Debugger class. The Debugger class enables you t o see whet her your process is at t ached t o an exist ing debugger. I f your process is already at t ached t o an inst ance of a debugger, t hen t here is no need for you t o st art a new inst ance; j ust use t he exist ing one. Ot herwise, st art a new inst ance of t he debugger and t hen st ep t hrough your code using t hat inst ance. Next you’ll look at how you can use t his in your code. Here is a sam ple of how t o check whet her t he process is already at t ached t o a debugger. I f it is not , t hen you can st art t he debugger and begin st epping t hrough t he process ( See List ings 14.3 and 14.4) . List in g 1 4 .3 Che ck for Ex ist ing D e bu gge r ( C# ) / / Check t o see i f t hi s pr ocess i s at t ached t o a debugger i f ( Debugger . I sAt t ached( ) == Fal se) { / / Chec k i f debugger st ar t ed successf ul l y
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
i f ( Debugger . Launch( ) == Tr ue) { / / The debugger was st ar t ed successf ul l y } el se { / / Ther e was a pr obl em l aunchi ng t he debugger } } el se { / / t he pr ocess i s cur r ent l y at t ached t o a debugger } List in g 1 4 .4 Che ck for Ex ist ing D e bu gge r ( Visu a l Ba sic .N ET) Di m db As New Debugger ( ) ' Check i f t hi s pr ocess i s at t ached t o a debugger I f Not db. I sAt t ached Then ' Now st ar t a new debugger i nst ance f or t hi s pr ocess I f db. Launch Then ' The debugger was successf ul l y st ar t ed El se i f ' Ther e was an er r or l aunchi ng t he debugger End I f El se ' The debugger i s al r eady at t ached t o t hi s pr ocess End I f Anot her very useful class is St ackTr ace, which enables you t o look at t he st ack fram e by fram e, or by each st ep t hat has been execut ed. Now t wo different St ackTr ace com ponent s can be used. Syst em. Di agnost i c. St ackTr ace can be used only if an except ion is t hrown. I f you want t o look at t he st ack before an except ion is t hrown or j ust t o see what is going on, t hen you need t o use t he Syst em. Envi r onment . St ackTr ace m et hod. This m et hod ret urns a st ring t hat represent s t he st ack. I f you need m ore inform at ion, you can use t he St ack Tr ace class in t he Syst em .Diagnost ic nam espace because it enables you t o dig deeper int o
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
t he st ack. The Envi r onment class has som e great feat ures t hat you can use t o look at t he syst em ’s environm ent before an except ion occurs. Next we’ll cover a few m ore feat ures t hat are useful in debugging. List ings 14.5 and 14.6 provide a couple of sim ple exam ples of how you can im plem ent t his int o your code. List in g 1 4 .5 St a ck Tr a ce D um p ( C# ) Usi ng Syst em; st r i ng s t ackdump; st ackdump = Envi r onment . St ackTr ace; Res ponse. Wr i t e( st ackdump) ; List in g 1 4 .6 St a ck Tr a ce D um p ( Visu a l Ba sic .N ET) I mpor t s Syst em Di m st ackdump As St r i ng st ackdump = Envi r onment . St ackTr ace( ) Res ponse. Wr i t e( st ackdump) Now if an except ion is t hrown, you will probably want t o use t he Syst em. Di agnost i cs. St ackTr ace class. This class works different ly t han t he Environm ent Class: you get t he St ackTr ace and t hen navigat e t hrough t he st ack fram e by fram e. Take a look at List ings 14.7 and 14.8 t o see how t o accom plish t his. List in g 1 4 .7 Ge t Ea ch St a ck Fr a m e ( C# ) try { i nt a=0; i nt b=1; i nt c; c = b/ a; Response. Wr i t e ( c) ; } c at ch( Except i on ex) { St ackFr ame sf ; i nt i ; St ackTr ace st = new St ackTr ace( ) ; f or ( i = 1; i " >
List in g 1 6 .1 7 D a t a bind m e t h od ( C# ) pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e) { / / Put user code t o i ni t i al i ze t he page her e Sql Connect i on Conn = new Sql Connect i on( ) ; Conn. Connect i onSt r i ng = " ser ver =l ocal host ; i ni t i al cat al og = nor t hwi nd; user i d= sa; pwd=" ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Conn. Open( ) ; Dat aSet ds = new Dat aSet ( ) ; Sql Dat aAdapt er dA = new Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , Conn) ; dA. Fi l l ( ds, " Pr oduct s" ) ; Dat aGr i d1. Al l owSor t i ng=t r ue; Dat aGr i d1. BackCol or = Syst em. Dr awi ng. Col or . Al i ceBl ue; Dat aGr i d1. Dat aSour ce = ds; Dat aGr i d1. Dat aBi nd( ) ; Conn. Cl ose( ) ; } List in g 1 6 .1 8 D a t a bind m e t h od ( Visu a l Ba sic .N ET) pr i vat e voi d Page_Load( obj ect sender , Syst em. Event Ar gs e)
'
Put user code t o i ni t i al i ze t he page her e
Di m Conn = new Sql Connect i on( ) Conn. Connect i onSt r i ng = " ser ver =l ocal host ; i ni t i al cat al og = nor t hwi nd; user i d= sa; pwd=" '
Open t he connect i on
Conn. Open( ) ' Cr eat e a new dat aset t o hol d t he r ecor ds Di m ds = new Dat aSet ( ) Di m dA = new Sql Dat aAdapt er ( " Sel ect * f r om pr oduct s" , Conn) ' Popul at e t he dat aset by usi ng t he dat aAdapt er s Fi l l met hod dA. Fi l l ( ds, " Pr oduct s" ) Dat aGr i d1. Al l owSor t i ng=t r ue Dat aGr i d1. BackCol or = Syst em. Dr awi ng. Col or . Al i ceBl ue Dat aGr i d1. Dat aSour ce = ds Dat aGr i d1. Dat aBi nd( ) Conn. Cl ose( ) This applies only t o aspx pages, not windows wit hin windows applicat ions.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Pr oble m s w it h Con n e ct ion s One of t he problem s t hat you m ight run int o first involves working wit h connect ions. Microsoft has designed t he .NET fram ework t o funct ion a lit t le different ly t han previous versions of ADO. Figure 16.4 provides an exam ple of an error t hat you m ight get when t rying t o work wit h m ult iple connect ions. Figur e 1 6 .4 . Er r or t ha t ca n r e sult w he n w or k in g w it h m u lt iple con n e ct ions.
This is a good sign t hat your connect ion is in use and t hat you need t o eit her com plet e t he current dat abase operat ion or close t he connect ion. I f you are get t ing t his error, check t o see if you have closed t he Dat aReader obj ect before execut ing anot her operat ion on t he sam e connect ion. This m ight occur when you are t rying t o read from one t able and t hen t rying t o perform an operat ion on anot her t able. Solut ions include closing t he Dat aReader before cont inuing or creat ing a second connect ion obj ect and running your process against t hat . You will not ice in List ings 16.19 and 16.20 t hat one dat a reader is open and t hat we have read t he first row of inform at ion from it . Then a second com m and obj ect is creat ed and m ore dat a is read from a different t able. As soon as t he com m and is execut ed against t he dat abase, however, we get an except ion. This is because t he
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
connect ion is right in t he m iddle of reading dat a from t he first SELECT st at em ent . At t his point , t he only t hing t hat can be done is t o finish reading t he dat a or close t he Dat aReader obj ect . List in g 1 6 .1 9 D a t a Re a de r pr oble m ( C# ) Sql Connect i on Conn = new Sql Connect i on( ) ; Conn. Connect i onSt r i ng = " ser ver =l ocal host ; i ni t i al cat al og = nor t hwi nd; user i d= sa; pwd=" ; Conn. Open( ) ; / / Cr eat e a Sql Command usi ng t he connect i on t hat was j ust cr eat ed Sql Command com1 = new Sql Command( " sel ect * f r om pr oduct s" , Conn) ; / / Cr eat e a dat ar eader Sql Dat aReader dr ; dr = com1. Execut eReader ( ) ; / / Now st ar t r eadi ng a r ow at a t i me dr . Read( ) ; / / Now cr eat e a second command t hat usi ng t he same connect i on Sql Command com2 = new Sql Command( " sel ect * f r om j obs" , Conn) ; / / Cr eat e a second dat ar eader Sql Dat aReader dr 2; / / now t r y t o execut e t hi s command on t he exi st i ng connect i on i n use dr 2 = com2. Execut eReader ( ) ; / / Thi s l i ne wi l l t hr ow and except i on! dr 2. Read( ) ; List in g 1 6 .2 0 D a t a Re a de r pr oble m ( Visu a l Ba sic .N ET) Di m Conn = new Sql Connect i on( ) Conn. Connect i onSt r i ng = " ser ver =l ocal host ; i ni t i al cat al og = nor t hwi nd; user i d= sa; pwd=" Conn. Open( ) / / Cr eat e a Sql Command usi ng t he connect i on t hat was j ust cr eat ed Di m com1 = new Sql Command( " sel ect * f r om pr oduct s" , Conn) / / Cr eat e a dat ar eader Di m dr as Sql Dat aReader dr = com1. Execut eReader ( ) / / Now st ar t r eadi ng a r ow at a t i me dr . Read( )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
/ / Now cr eat e a second command t hat usi ng t he same connect i on Di m com2 = new Sql Command( " sel ect * f r om Or der s" , Conn) / / Cr eat e a second dat ar eader Di m dr 2 as Sql Dat aReader / / now t r y t o execut e t hi s command on t he exi st i ng connect i on i n use dr 2 = com2. Execut eReader ( ) / / Thi s l i ne wi l l t hr ow and except i on! dr 2. Read( ) I f you need t o persist t he dat a t o work wit h it , you will need t o pull it int o a dat aset or som e ot her form . That way you can keep it in m em ory while you m ake anot her connect ion t o t he dat abase.
Com m on Pit fa lls This sect ion looks at som e com m on issues t hat you m ight encount er when developing and t ells how t o work around t hem .
W or k in g
w it h
M u lt iple
Con n e ct ion s
and
Usin g
Con n e ct ion Poolin g Connect ion pooling is built int o t he .NET Fram ework. I f you creat e all your connect ions wit h t he sam e connect ion st ring, t he syst em aut om at ically pools t he connect ions for you. But if t he connect ion st rings differ, you will get a new nonpooled connect ion. Keep t his in m ind when you are developing. I f you creat e connect ions all over your code and t hey all point t o t he sam e locat ion, keep a global connect ion st ring around so t hat you don’t st art creat ing unm eaningful dat abase connect ions and wast ing resources. A good place t o st ore your connect ion st ring would be in t he Web.Config file under a cust om sect ion called appset t ings. List ings 16.21 and 16.22 illust rat e when a new connect ion will be m ade and when an exist ing connect ion will be used or pooled. List in g 1 6 .2 1 Conn e ct ion Pooling ( C# ) Sql Connect i on conn = new Sql Connect i on( ) ; conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=St or e" ; conn. Open( ) ;
/ / Pool 1 i s cr eat ed.
Sql Connect i on conn = new Sql Connect i on( ) ;
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=Or der s" ; conn. Open( ) ;
/ / Pool 2 i s cr eat ed
/ / The second pool i s cr eat ed due t o t he di f f er ences i n connect i on st r i ngs Sql Connect i on conn = new Sql Connect i on( ) ; conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=St or e" ; conn. Open( ) ;
/ / pool 1 i s used.
List in g 1 6 .2 2 Conn e ct ion Pooling ( Visua l Ba sic .N ET) Di m conn = new Sql Connect i on( ) ; conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=St or e" ; conn. Open( ) ;
'
Pool 1 i s cr eat ed.
Di m conn = new Sql Connect i on( ) ; conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=Or der s" ; conn. Open( ) ;
'
Pool 2 i s cr eat ed
/ / The second pool i s cr eat ed due t o t he di f f er ences i n connect i on st r i ngs Di m conn = new Sql Connect i on( ) ; conn. Connect i onSt r i ng = " I nt egr at ed Secur i t y=SSPI ; I ni t i al Cat al og=St or e" ; conn. Open( ) ;
'
pool 1 i s used.
I n som e cases, you will need t o creat e t wo separat e connect ions t o perform an operat ion. This m ight occur when you are in t he m iddle of reading inform at ion from a dat a reader and want t o m ake changes t o t he dat abase as you it erat e t he dat a.
Sh ou ld I Use a D a t a Re a de r or D a t a Ada pt e r ? You should ask yourself a few basic quest ions before you st art grabbing dat a from t he dat abase. First , what do you need t o do wit h t he dat a? Do you need t o change it , add t o it , read it , or display it in a dat a grid? These are im port ant quest ions t o consider because t hey det erm ine which com ponent you can use, as opposed t o which one you want t o use. I f you want t o display dat a in a dat a grid, your only opt ion is t o use t he Dat aAdapt er . This is because t he Dat aAdapt er is used t o populat e a dat aset , which is t he preferred m et hod of populat ing a dat a grid.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I f you j ust need t o read t he dat a row by row, t hen, by all m eans, use a Dat aReader obj ect . Also not e t hat t his is a forward, read- only m echanism ; if you want t o edit dat a as you are navigat ing t hrough t he rows, you won’t be able t o. The Dat aReader is st rict ly for reading dat a—hence, t he nam e Dat aReader .
H ow M a n y Tim e s D o You Re a lly N e e d t o Ta lk t o t h e D a t a ba se ? So what is t he big deal about calling t he dat abase a bazillion t im es? You don’t see any im pact while developing it . And som e of t he st ress t est ing seem ed t o be fine, so it m ust be okay t o do. I n m y experience, t he num ber of t rips t hat you m ake t o t he dat abase can have a significant im pact on t he perform ance—not t o m ent ion t he scalabilit y—of your web sit e. I t doesn’t m at t er if it is a very sm all am ount of dat a t hat is being ret rieved from t he dat abase; if it is in a high- t raffic page, it can—and usually will—com e back t o bit e you lat er. Let ’s say t hat you have a web st ore, and you sell books. On t he front page, you want t o rot at e books from a preselect ed group of books on sale. Current ly all t he inform at ion t hat you need is cont ained in a dat abase. So you figure t hat you will j ust query t he dat abase every t im e som eone request s t he page. But what happens when you st art t o receive a lot of hit s on your web sit e? I have seen t his happen lit erally overnight ! The next day t raffic doubles and cont inues t o clim b day by day. These are t he sit uat ions t hat you t hought you saw only in TV com m ercials. But t hey are real, t rust m e! I f you st op t o look at t his sit uat ion, you m ight be only rot at ing 30 different books. So, aft er t he 30t h t im e t o t he dat abase, you st art doing redundant work. One solut ion is t o keep on t he web server an XML file of t he books t hat are current ly on sale. Then your server only needs t o look on it s own hard drive t o ret rieve t he dat a t hat it needs. Now j ust writ e som e cust om code behind t he web page t o do t he rot at ing and reading t he dat a from t he XML file. I f you are worried about new books going on sale and having t o updat e t he XML file, don’t worry. On MS SQL Server, you can use a t rigger or schedule a t ask t o check for new books on sale. I f t here are new it em s, t he syst em can export t he result s t o an XML file, and, prest o—your web page aut om at ically picks up t he new XML file. This is j ust one creat ive way t o accom plish t his t ask, but t here are m any ot her ways t o accom plish t he sam e t hing. Just bear in m ind t he following suggest ions: •
Keep it sim ple.
New Riders - Debugging ASP.NET
•
•
•
m ade by dot net er@t eam fly
Persist com m on dat a elem ent s in m em ory or t o a local file. Keep t he num ber of t rips t o t he dat abase m inim al. Keep t he num ber of connect ion t o a m inim um .
Keep t hese point s in m ind when you are developing your web sit e, and t hink t hrough what you are t rying t o accom plish. As m uch as you m ight want t o j um p in and st art coding, it is always beneficial t o have a plan can be called in a few different ways wit hout using t he param et er com ponent s. Here we focus on t he issues wit h t he com m and obj ect and param et er collect ions, t hough.We could never underst and why people used t he param et er obj ect t o add param et ers t o t heir query when t hey could sim ply form at a t ext st ring t o do t he sam e t hing and use less code t o accom plish t he t ask. So what is t he benefit of using param et ers? Let ’s t ake a look at t he t ype of problem s you m ight run int o and how t o avoid t hem . Using Pa r a m e t e r s w it h SqlCom m a n d When using param et ers wit h Sql Command, t he nam es of t he param et ers m ust m at ch t he nam es of t he param et er placeholders in t he st ored procedure. The SQL Server .NET Dat a Provider t reat s t hese as nam ed param et ers and searches for t he m at ching param et er placeholders. The SQLCom m and class does not support t he quest ion m ark ( ?) placeholder for passing param et ers t o a SQL st at em ent or a st ored procedure call. I f you accident ally use t he quest ion m ark, you will probably get t he error shown in Figure 16.5. Figur e 1 6 .5 . Er r or ge n e r a t e d by u se of a qu e st ion m a r k .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n t his case, nam ed param et ers m ust be used. Take a look at List ings 16.22 and 16.23 t o see how you would properly im plem ent a param et er using t he Sql Command class. List in g 1 6 .2 2 I m ple m e n t in g a Pa r a m e t e r Using t h e SqlCom m a n d Cla ss ( C# ) Sql Connect i on conn = new Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=yes" ) ; conn. Open( ) ; / / Bui l d t he Command usi ng a named par amet er Sql Command myCommand2 = new Sql Command( " SELECT Cat egor yI D, Cat egor yName FROM Cat egor i es wher e Cat egor yI D > @par am1" , conn) ; / / Add t he par amet er and val ue t o t he command obj ect myCommand2. Par amet er s. Add( " @par am1" , 3) ; Sql Dat aReader myReader = myCommand2. Execut eReader ( ) ; List in g 1 6 .2 3 I m ple m e n t in g a Pa r a m e t e r Using t h e SqlCom m a n d Cla ss ( Visu a l Ba sic .N ET) Di m conn = New Sql Connect i on( " ser ver =( l ocal ) ; dat abase=nor t hwi nd; Tr ust ed_Connect i on=y es" ) conn. Open( ) ' Bui l d t he Command usi ng a named par amet er Di m myCommand2 = New Sql Command( " SELECT Cat egor yI D, Cat egor yName FROM Cat egor i es wher e Cat egor yI D > @par am1" , conn) ' Add t he par amet er and val ue t o t he command obj ect myCommand2. Par amet er s. Add( " @par am1" , 3) Di m myReader = myCommand2. Execut eReader ( ) I n t hese list ings, you will not ice t hat when we creat ed Sql Command, we included a nam ed param et er called @par am1. The next line of code added t he param et er value t o t he com m and st at em ent by adding it t o t he param et er collect ion and specifying t he param et er nam e and value t hat should replace it . Just rem em ber t hat t he Ol eDBCommand obj ect does not operat e t he sam e way. Let ’s t ake a look at t he differences in t he next sect ion. Using Pa r a m e t e r s w it h Ole D bCom m a nd
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
When using param et ers wit h Ol eDbCommand, t he nam es of t he param et ers added t o Ol eDbPar amet er Col l ect i on m ust m at ch t he nam es of t he param et er in t he st ored procedure. The OLE DB .NET Dat a Provider t reat s t hese as nam ed param et ers and searches for t he m at ching param et er m arker. The OLE DB .NET Dat a Provider does not support nam ed param et ers for passing param et ers t o a SQL st at em ent or a st ored procedure called by a com m and obj ect . I n t his case, t he quest ion m ark ( ?) placeholder m ust be used. Take a look at t he following exam ple: SELECT * FROM Pr oduct s WHERE Pr oduct I D = ? and pr i ce = ? I t is im port ant t hat t he order in which param et er obj ect s are added t o t he Par amet er sCol l ect i on m ust direct ly correspond t o t he posit ion of t he quest ion m arks in t he SQL st at em ent . Unlike t he Sql Command obj ect , in which t he param et ers have nam es associat ed wit h t hem , you don’t have t hat opt ion here.
SQL AD O.N ET Obj e ct s Ve r su s Ole D b AD O.N ET Obj e ct s So what is t he big difference? And why are t here t wo different com ponent s t o m anipulat e dat a? The biggest difference is not apparent on t he out side. I t is inside where t he differences are t rem endous. I f you look at how t he t wo com ponent s differ, SQLCl i ent is nat ive t o .NET and MS SQL Server. I t com m unicat es t o SQL using it s own prot ocol. This enables it t o work m ore quickly and t o avoid having t o use t he ODBC layer or Ol eDB t o com m unicat e t o legacy dat abase drivers. When debugging, you need t o keep in m ind t he difference bet ween t he t wo nam espaces. Even t hough m ost of t he feat ures look and act alike, you m ight run int o som e problem s. For inst ance, t he connect ion st rings differ slight ly; if you are working wit h param et ers, you need t o m ake sure t hat you are form at t ing t he st ring correct ly. When connect ing t o a Microsoft SQL Server dat abase, you m ight want t o increase your overall perform ance by using Sql Dat aAdapt er along wit h it s associat ed Sql Command and Sql Connect i on.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
D a t a Con n e ct ion Pe r for m a n ce N ot e I f you are concerned about perform ance, keep in m ind t he t ype of connect ion you will be using. When you are developing a dat abase com ponent , you m ight t hink about keeping it flexible enough t o work on— say, wit h Oracle and SQL Server. To get t he best perform ance, you could det ect which dat abase you are using and t hen use t he classes t hat best suit your needs. This would fall under m ore of a com m ercial soft ware product feat ure, but t hat is one bit of inform at ion t o t hink about .
Su m m a r y Let ’s t ake a look at what we have covered so far. First we looked at som e of t he new feat ures Microsoft has added and showed where you m ight st um ble in your t ransit ion t o .NET. Next we dug int o how t he syst em used t he SQLExcept i on class t o handle errors t hat are t hrown by t he syst em . This is a very powerful t ool for debugging, so get used t o using it in your code. Then t he chapt er m oved int o possible problem s t hat you m ight run int o wit h t he SQLConnect i on class and showed how t o avoid com m on m ist akes. We also covered som e t ypical error m essages and how t o fix t he errors t hat t hey represent . Rem em ber, t hose dat a grid cont rols are a powerful t ool, so t ake advant age of t hem t o do as m uch work for you as possible.
Appe n dix A. I ssu e s t h a t Ar ise W h e n M igr a t in g fr om ASP t o ASP.N ET
SO NOW THAT YOU HAVE DECI DED TO st art writ ing all your web- based applicat ions in ASP.NET, you m ust be wondering what issues you will encount er while m igrat ing from ASP t o ASP.NET. Unfort unat ely, t his can be a lengt hy list , depending on t he sit uat ion you are in. I f you are port ing an exist ing applicat ion t o t he ASP.NET fram ework, a variet y of changes will need t o be m ade t o your exist ing VBScript code.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
However, of you are st art ing a proj ect from scrat ch, you will need t o rem em ber only t he language and logic changes t hat are now in t he Visual Basic language. I n t he next few sect ions, we discuss t he synt act ical changes t hat have been m ade t o Visual Basic. We will also t ake a look at C# and why you m ight want t o use it for your server- side program m ing language. Keep in m ind t hat t his is not an exhaust ive list of changes bet ween t he t wo versions. This appendix at t em pt s t o look at only feat ures t hat exist ed in t he previous version t hat have been m igrat ed t o t he new version. Feat ures in .NET t hat were not in a previous version will not be discussed here.
M oving fr om ASP t o ASP.N ET Alt hough ASP.NET is based on t he ASP t echnology, a lot of t he fundam ent als have changed. Here we explore som e of t he basic changes t hat you will encount er when m igrat ing from ASP t o ASP.NET.
< % % > Ve r su s < scr ipt > I n ASP, all server- side code is writ t en bet ween < % and % > t ags. This t ells t he ASP int erpret er t hat everyt hing bet ween t he t wo t ags is program code and should be execut ed on t he server. I n ASP.NET, t he rules have changed a bit . Now, all variable and funct ion declarat ions are placed bet ween and t ags, while im plem ent at ion logic is cont ained in bet ween t he < % and % > t ags. List ing A.1 shows an exam ple ASP page, and List ing A.2 and List ing A.3 show t he sam e page writ t en in ASP.NET, using Visual Basic .NET and C# , respect ively. List in g A.1 ASP Pa ge ( C# )
New Riders - Debugging ASP.NET
List in g A.2 ASP.N ET Pa ge ( Visua l Ba sic .N ET)
Sub My Funct i on( psSt r i ng as St r i ng) I f psSt r i ng " " t hen Response. Wr i t e( psSt r i ng) End I f End Sub
List in g A.3 ASP.N ET Pa ge ( C# )
voi d MyFunct i on( St r i ng psSt r i ng) { i f ( psSt r i ng ! = " " ) Response. Wr i t e( psSt r i ng) ; }
m ade by dot net er@t eam fly
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
You should not ice a few t hings here. First , not e t he form at of t he t ag, depending on which language you are using as your server- side code. You will want t o use t he l anguage param et er t o specify t his. For Visual Basic .NET, you set t he language param et er t o vb; in C# , you set it t o c#. Second, not ice t hat t he funct ion definit ion is placed bet ween t he t ags, as described previously, but t he act ual call t o it , t he im plem ent at ion logic, is placed bet ween t he st andard ASP < % % > t ags. I n ASP.NET, you m ust define all funct ions wit hin t ags. However, calls t o t he funct ion m ust be placed wit hin t he st andard < % % > t ags. Finally, not ice t hat inst ead of calling Request . For m( " t xt Text " ) t o get t he value of t he t ext box upon subm ission, you use a m et hod of t he For m obj ect called Get . This m et hod exist s off t he Quer ySt r i ng and Cooki e collect ions also. Be sure t o explicit ly specify t his in your code when t rying t o access any of t he m em bers of t hese collect ions; ot herwise, your code will not com pile.
Pa ge D ir e ct ive s The page direct ives t hat you are fam iliar wit h in ASP are st ill available in ASP.NET. However, a few new ones are wort hy of m ent ion. Table A.1 list s t he new direct ives and what t hey can do for you. Tabl e A. 1. ASP. NET Page Di r ect i ves
Directive
Description
@ Page
Specifies page- specific at t ribut es
@ Cont r ol
Specifies cont rol- specific at t ribut es
@ I mpor t
I m port s a nam espace int o t he page
@ Regi st er
Associat es aliases wit h nam espaces and class nam es for concise not at ion in Cust om Server Cont rol Synt ax
@ Assembl y
Links an assem bly wit h t he current page
@
Cont rols t he caching of t he page
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Out put Cache
Re spon se .Re dir e ct
Ve r su s
Pa ge .N a viga t e
Ve r su s
Se r ve r .Tr a n sfe r To send t he browser t o a new page in ASP, t he Redi r ect m et hod of t he Response obj ect is used as shown: Response. Redi r ect " Ot her Page. aspx" I n ASP.NET, you have t wo alt ernat ives t o t his m et hod. The first is t he Navi gat e m et hod of t he Page obj ect . The funct ion t akes t he sam e param et er as Response. Redi r ect : t he URL t o redirect t o. The difference bet ween t he t wo m et hods is t hat Page. Navi gat e calls Response. Redi r ect , unloads all cont rols in t he t ree, and t hen calls Response. End. The second m et hod, Ser ver . Tr ansf er t erm inat es execut ion of t he current ASP.NET page and t hen begins execut ion of t he request on t he page specified. I t t akes t he following form : Ser ver . Tr ansf er " Ot her Page. aspx" At t his point in t he code, what ever script was being execut ed st ops and t hen st art s at t he t op of Ot her Page. asp. You should use Page. Navi gat e when you want t o com plet ely st op execut ion of one page and im m ediat ely m ove t o t he ot her, discarding t he result s of t he current page. The Ser ver . Tr ansf er m et hod should be used when you want t o st art execut ion on anot her page wit hout discarding any of t he previously com put ed inform at ion.
Cook ie s The use of cookies is very different in ASP.NET. I nst ead of a cookie collect ion being part of t he Response and Request obj ect s, cookies are now obj ect s t hat are m anipulat ed individually and t ossed int o a m ast er collect ion. Previously, t o add a cookie t o t he client m achine, your code would look sim ilar t o List ing A.4. List in g A.4 ASP Cook ie Code
The cooki e i s:
The sam e code in ASP.NET is quit e different .What m akes it different is t hat cookies are now t reat ed as obj ect s.You creat e and inst ant iat e a cookie obj ect , set it s value, and t hen append it ont o t he cookie collect ion. Request ing it back out of t he collect ion is very sim ilar t o doing so in ASP. Just rem em ber t o use t he Get m et hod, as was shown in t he previous sect ion. List ing A.5 illust rat es t he procedure in Visual Basic .NET, and List ing A.6 illust rat es t he sequence in C# . List in g A.5 Cook ie s ( Visua l Ba sic .N ET)
List in g A.6 Cook ie s ( C# )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Eve n t s Anot her m aj or change t o t he way ASP.NET works is t hat it is based on an event m odel m uch like a t ypical Visual Basic program . I nst ead of your ASP script being execut ed from t op t o bot t om , you can respond t o event s such as but t on clicks, t ext box changes, and so on. Of course, all t hese event s will occur on t he server side, so you will not be able t o hook int o every possible event , such as a m ouse m ove or a key- down event .
M oving fr om VBScr ipt t o Visu a l Ba sic You should be aware of quit e a few synt act ical changes t o t he Visual Basic program m ing language before you st art any proj ect in t his language. This sect ion looks at m ost of t he changes in Visual Basic .NET.
Se t Let ’s st art out wit h t he keyword Set . I n short , it is gone. The st andard obj ect inst ant iat ion in Visual Basic is shown here: Set obj MyObj = obj SomeOt her Obj I n Visual Basic .NET, t his code has been short ened t o m ore closely m at ch t he C# program m ing language. The sam e code in Visual Basic .NET looks like t his: obj MyObj = obj SomeOt her Obj
Pr ope r t ie s Propert ies have been great ly sim plified in t he world of t he new Visual Basic. Previously, a series of propert ies looked like t he code in List ing A.7.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g A.7 Visua l Ba sic Pr ope r t y Code Pr i vat e gsSt r i ng As St r i ng Pr i vat e goObj ect as Obj ect Publ i c Pr oper t y Let St r i ngPr op( ByVal psDat a as St r i ng) gsSt r i ng = psDat a End Pr oper t y Publ i c Pr oper t y Get St r i ngPr op( ) As St r i ng St r i ngPr op = gsSt r i ng End Pr oper t y Publ i c Pr oper t y Set Obj ect Pr op( ByVal poObj as Obj ect ) Set goObj ect = poObj End Pr oper t y I n Visual Basic .NET, t his is m uch short er; an exam ple is given in List ing A.8. List in g A.8 Visua l Ba sic .N ET Pr ope r t y Code Pr i vat e gsSt r i ng as St r i ng Pr i vat e goObj ect as Obj ect Publ i c Pr oper t y St r i ngPr op as St r i ng Get St r i ngPr op = gsSt r i ng End Get Set gsSt r i ng = St r i ngPr op End Set End Pr oper t y As you can see, t here is no longer a dist inct ion bet ween a Set and a Let because of t he change m ent ioned in t he last sect ion.
Ca llin g Su bs Calls of all t ypes ( funct ion, m et hod, and sub) m ust use parent heses around t he param et ers, regardless of whet her you are doing som et hing wit h t he ret urn value. For exam ple, t he code in List ing A.9 would work in Visual Basic or VBScript . List in g A.9 Visua l Ba sic Fu n ct ion Ca lls
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
dt Dat e = Dat e MyFunct i on " Val ue1" , 2, pl Val However, in Visual Basic .NET, you would need t o change t hese sam e calls t o t he code shown in List ing A.10. List in g A.1 0 Visu a l Ba sic .N ET Fu n ct ion Ca lls dt Dat e = Dat e( ) MyFunct i on( " Val ue1" , 2, pl Val )
Pa r a m e t e r s A m aj or change t o t he ways param et ers are passed has been int roduced int o Visual Basic .NET. Previously, all param et ers were passed ByRef if no m et hod was specified. Now, all int rinsic t ypes are passed ByVal . So, t he funct ion in List ing A.11 would no longer work in Visual Basic .NET. List in g A.1 1 Visu a l Ba sic Fu n ct ion w it h ByRe f Pa r a m e t e r s Sub MyFunct i on( pl Lng1 As Long, pl Lng2 As Long, pl Lng3 As Long) pl Lng3 = pl Lng1 + pl Lng2 End Sub I n Visual Basic .NET, t his subrout ine would have t o be rewrit t en as shown in List ing A.12. List in g A.1 2 Visu a l Ba sic .N ET Fu n ct ion w it h ByRe f Pa r a m e t e r s Sub MyFunct i on( pl Lng1 As Long, pl Lng2 As Long, ByRef pl Lng3 as Long) pl Lng3 = pl Lng1 + pl Lng2 End Sub
D a t a t y pe s Unlike VBScript , Visual Basic support s a wide range of variable t ypes. The sam e can be said of Visual Basic .NET. I n previous server- side code you have writ t en, all variables were declared as t ype Var i ant . Wit h your server- side code writ t en in Visual Basic .NET, it is highly recom m ended t hat , when you’re declaring variables, you define t hem appropriat ely so t hat t hey will not use excess m em ory and will be far m ore efficient . List ing A.13 shows a few exam ples of how t o declare variables of specific t ypes. List in g A.1 3 Visu a l Ba sic .N ET Va r ia ble D e cla r a t ions
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Di m psSt r i ng As St r i ng Di m pl Long as Long Di m bByt e as Byt e Also be aware t hat t he Currency dat at ype has been rem oved. Som et hing else t o not e is t hat t he sizes of cert ain int rinsic dat at ypes have changed. Refer t o Table A.2 for m ore inform at ion. Tabl e A. 2. Vi sual Basi c . NET I nt r i nsi c Dat at ypes
Datatype
Size
Byt e
1 byt e ( 8 bit s)
Short
2 byt es ( 16 bit s)
I nt eger
4 byt es ( 32 bit s)
Long
8 byt es ( 64 bit s)
Single
4 byt es ( 32 bit s)
Double
8 byt es ( 64 bit s)
Decim al
12 byt es ( 96 bit s)
Not e here t hat t he sizes for I nt eger and Long dat at ypes have changed. Long is now 64 bit s inst ead of 32 bit s, and I nt eger is now 32 bit s rat her t han 16 bit s.
Va r ia n t The Variant dat at ype no longer exist s in Visual Basic .NET. I t has been replaced wit h t he universal Obj ect t ype. Also rem oved from Visual Basic .NET is t he Var Type funct ion. Now, t o get t he t ype of a specific variable, you can use t he following propert y t hat is a m em ber of all t he int rinsic dat at ypes: SomeObj . Get Type. Get TypeCode. val ue
D e cla r a t ion s A new feat ure of Visual Basic .NET is t he capabilit y t o init ialize variables and arrays at t he t im e of declarat ion, as shown in List ing A.14. List in g A.1 4 Visu a l Ba sic .N ET Va r ia ble I n it ia liza t ion s Di m psSt r i ng As St r i ng = " Hel l o! " Di m pi I nt as I nt eger = 123 Const cSTRI NG = " Goodbye! " Di m psAr r ay( 2) As St r i ng = ( " Br i an" , " Jon" )
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Not e, however, t hat t he capabilit y t o declare st rings of a predefined lengt h is m issing in Visual Basic .NET. Therefore, t he st at em ent Di m ps St r i ng As St r i ng * 5 is no longer valid.
Sh or t h a n d Syn t a x Visual Basic .NET now support s short hand assignm ent m uch like C, C+ + , and Java. The code in List ing A.15 illust rat es a few exam ples of t he short hand not at ion. List in g A.1 5 Shor t h a n d Assignm e n t s in Visu a l Ba sic .N ET pl Val = 100 pl Val += 10 '
pl Val now equal s 110
pl Val - = 10 '
pl Val now equal s 100
pl Val * = 5 '
pl Val now equal s 500
pl Val / = 5 '
pl Val now equal s 100
Er r or H a n dlin g Alt hough t he st andard On Er r or GoTo XXX and On Er r or Resume Next exist in Visual Basic .NET, you also m ight want t o t ake advant age of it s built - in st ruct ured error handling, which is sim ilar t o t hat of languages such as C+ + and Java. The code in List ing A.16 shows an exam ple of st ruct ured error handling in Visual Basic .NET. List in g A.1 6 St r u ct u r e d Er r or H a n dlin g in Visua l Ba sic .N ET Tr y '
Some code
Cat ch '
What t o r un when an er r or occur s
Fi nal l y '
Code t hat al ways execut es af t er t r y or cat ch
End Tr y
St r u ct u r e D e cla r a t ion I n Visual Basic, st ruct ures were defined using t he Type…End Type, as shown in List ing A.17. List in g A.1 7 Visu a l Ba sic .N ET St r u ct ur e Type Empl oyee EmpName As St r i ng
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
EmpNumber As Long EmpAge As I nt eger End Type I n t he new Visual Basic .NET, t his sam e st ruct ure would be declared using t he St r uct ur e…End St r uct ur e keywords, as shown in List ing A.18. List in g A.1 8 Visu a l Ba sic .N ET St r u ct ur e St r uct ur e Empl oyee EmpName As St r i ng EmpNumber As Long EmpAge As I nt eger End St r uct ur e
Va r ia ble Scope The scope of variables in Visual Basic .NET is slight ly different from t hat of Visual Basic. I n Visual Basic, t he code in List ing A.19 would be valid. List in g A.1 9 Va r ia ble Scope in Visu a l Ba sic .N ET For pl Count = 0 t o 10 Di m pl Val as Long pl Val = pl Val + pl Count Next pl Val 2 = 2 ^ pl Val I n Visual Basic .NET, however, because t he variable pl Val is declared inside t he For …Next loop, it s scope is inside t hat block. Therefore, it cannot be seen out side t he loop in t he previous exam ple.
Obj e ct Cr e a t ion I n Visual Basic, t he following st at em ent would declare an obj ect and set it t o Not hi ng unt il it was used. At t hat point , it would reference a new inst ance of MyObj ect . Di m poObj ect as New MyObj ect I n Visual Basic .NET, however, t his st at em ent is act ually short hand for t he following:
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Di m poObj ect As MyObj ect = New MyObj ect I n t his st at em ent , t he obj ect is creat ed and references a new inst ance of t he obj ect .
I sM issin g I ronically, in Visual Basic .NET, I sMi ssi ng is, well, m issing. This m eans t hat all opt ional param et ers t o a funct ion m ust be declared wit h a default value, as follows: Sub MySub( Opt i onal psSt r = " Def aul t val ue! " )
Con t r ol- of- Flow St a t e m e n t s Cert ain cont rol- of- flow t at em ent s have been rem oved from Visual Basic .NET, including t hese: •
• •
GoSub On…GoSub On…GoTo ( Er r or …GoTo is st ill valid)
A change also has been m ade t o t he Whi l e loop. Previously, Whi l e…Wend was valid; however, now t he synt ax has changed t o Whi l e…End Whi l e.
An d t h e Re st To wrap t his all up, here is a list of everyt hing t hat has been rem oved from t he Visual Basic .NET program m ing language: • •
As Any keyword phrase
•
Cal endar propert y
•
Currency dat at ype
•
At n funct ion
•
Ci r cl e st at em ent
•
Dat e funct ion and st at em ent
•
Debug. Pr i nt m et hod
•
DoEvent s funct ion
•
Eqv operat or
•
Debug. Asser t m et hod
•
Def t ype st at em ent s
•
Empt y keyword
•
GoSub st at em ent I mp operat or
New Riders - Debugging ASP.NET
• •
I ni t i al i ze event
•
I sEmpt y funct ion
•
I sNul l funct ion
•
Let st at em ent
•
LSet st at em ent
•
Nul l keyword
•
On … GoTo const ruct ion
•
Opt i on Pr i vat e Modul e st at em ent
m ade by dot net er@t eam fly
•
I nst anci ng propert y
•
I sMi ssi ng funct ion
•
I sObj ect funct ion
•
Li ne st at em ent
•
MsgBox funct ion
•
On … GoSub const ruct ion
•
Opt i on Base st at em ent
•
Pr oper t y Get , Pr oper t y Let , and Pr oper t y Set st at em ent s
•
Rnd funct ion
•
RSet st at em ent
•
Set st at em ent
•
Sqr funct ion
•
Ter mi nat e event
•
Type st at em ent
•
PSet m et hod
•
Round funct ion
•
Scal e m et hod
•
Sgn funct ion
•
St r i ng funct ion
•
Ti me funct ion and st at em ent
•
Variant dat at ype
•
Var Type funct ion Wend keyword
Opt ing for C# I f you are m ore fam iliar wit h t he synt ax of C, C+ + or Java, you m ight be int erest ed in using C# ( pronounced “ C sharp” ) as your server- side program m ing language. I f you are current ly a Visual Basic program m er want ing t o m ove t o C# , you should be aware of a few synt act ic changes. We will look at som e of t hese differences in t he next sect ions; however, be aware t hat t his is not a com prehensive look at t he ent ire C# program m ing language—it ’s m erely a guide t o ease you int o t he C# language.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
Ca se Se n sit ivit y One of t he m ain differences bet ween t he languages is t hat C# is case- sensit ive, while Visual Basic is not . Therefore, alt hough t he code in List ing A.20 is accept able in Visual Basic, t he code in List ing A.21 would be needed in C# . List in g A.2 0 Va lid Code ( Visua l Ba sic .N ET) psSt r = psst r & " Hel l o" pl VAL1 = pl val 1 + pl val 2 List in g A.2 1 Va lid Code ( C# ) psSt r = psSt r & " Hel l o" pl Val 1 = pl Val 1 + pl Val 2
Se m icolon s One of t he very first t hings t o be aware of is t he use of sem icolons t o end program m ing st at em ent s. I n Visual Basic, st at em ent s are t erm inat ed by a carriage ret urn; in C# , t hey are t erm inat ed wit h a ; charact er. List ing A.22 shows a few lines of code in Visual Basic, and List ing A.23 shows t he equivalent code in C# . List in g A.2 2 Som e St a t e m e n t s ( Visu a l Ba sic .N ET) n += 10 MyFunct i on( " Br i an" , " Jon" ) MyLonger Funct i on( " Br i an" , _ " Jon" ) List in g A.2 3 The Sa m e St a t e m e n t s ( C# ) n += 10; MyFunct i on( " Br i an" , " Jon" ) MyLonger Funct i on( " Br i an" , " Jon" ) ;
Br a ck e t s Anot her synt act ical change is t he t ype of bracket s t hat are used for collect ion and array indexers. I n Visual Basic, parent heses—( and ) —are used around t hese values; in C# , square bracket s— [ and ] —are used. List ing A.24 shows t he use of bracket s in Visual Basic.
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
List in g A.2 4 Use of Br a ck e t s ( Visu a l Ba sic .N ET) MyAr r ay( 0) = " Br i an" MyAr r ay( 1) = " Jon" MyCol l ect i on( " Br i an" ) = " Cool " MyCol l ect i on( " Jon" ) = " Not So Cool " I n C# , t hese sam e st at em ent s would be writ t en as shown in List ing A.25. List in g A.2 5 Use of Br a ck e t s ( C# ) MyAr r ay[ 0] = " Br i an" ; MyAr r ay[ 1] = " Jon" ; MyCol l ect i on[ " Br i an" ] = " Cool " ; MyCol l ect i on[ " Jon" ] = " Not So Cool " ;
Fu n ct ion s Funct ions are declared very different ly in C# t han in Visual Basic. List ing A.26 illust rat es a t ypical funct ion im plem ent at ion in Visual Basic. List in g A.2 6 Fun ct ion ( Visu a l Ba sic .N ET) Publ i c Funct i on MyFunct i on( psSt r As St r i ng) As St r i ng MyFunc t i on = psSt r End Funct i on Now let ’s look at t hat sam e funct ion in C# . List ing A.27 is a list ing of t he sam e funct ion in C# . List in g A.2 7 Fun ct ion ( C# ) publ i c St r i ng MyFunct i on( St r i ng psSt r ) { r et ur n psSt r ; } Let ’s t alk about t he differences. First , not e t he case difference in each of t he languages. I t is ext rem ely im port ant t hat you rem em ber t hat C# is a case- sensit ive language. Second, you will not ice t hat , in Visual Basic, t he t ype of t he funct ion is not ed at t he end of t he funct ion line wit h t he words As St r i ng. I n C# , however, t he t ype of t he funct ion is declared before t he nam e of t he funct ion as St r i ng. Third, you will see t hat t he Visual Basic funct ion is closed wit h t he End Funct i on st at em ent .
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n C# , all st at em ent s of a funct ion are enclosed around curly braces—{ and } . Fourt h, you’ll see t hat t he param et ers passed in t he Visual Basic version are t yped aft er t he variable nam e, j ust like t he funct ion. I n C# , t he variables are t yped before t he variable nam e, again like t he t ype of t he funct ion. Finally, t he Visual Basic version of t he funct ion ret urns t he value of psSt r by assigning it t o t he nam e of t he funct ion, MyFunct i on. I n C# , however, t o ret urn a value, you use t he r et ur n st at em ent , which does t he sam e t hing.
Con t r ol- of- Flow St a t e m e n t s All t he st andard flow- cont rol st at em ent s t hat you are fam iliar wit h in Visual Basic exist in C# and have t he sam e funct ionalit y; however, t heir synt ax is different . I n t his sect ion, we look at all t he flow- cont rol st at em ent s and t heir synt ax in C# . I f St a t e m e n t I n Visual Basic, t he st andard I f st at em ent t akes t he form of t he code in List ing A.28. List in g A.2 8 I f St a t e m e n t ( Visu a l Ba sic .N ET) I f pl Val < 10 Then ... El se ... End I f I n C# , t his form at is som ewhat m odified. List ing A.29 shows t he sam e st at em ent in C# . List in g A.2 9 if St a t e m e n t in ( C# ) i f ( pl Val < 10) { ... } el se { ... } Alt hough it isn’t drast ically different , you should pay at t ent ion t o t he parent heses around t he t est st at em ent and t he use of curly braces t o enclose t he code
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
st at em ent s. Also you will see t hat t he End I f clause is m issing. Finally, not e t he case of t he words i f and el se. For St a t e m e n t The For loop is writ t en very different ly in C# t han it is in Visual Basic. List ing A.30 shows a Visual Basic for loop, and List ing A.31 shows t he sam e loop writ t en in t he C# program m ing language. List in g A.3 0 For St a t e m e n t ( Visu a l Ba sic .N ET) For pl Count = 0 t o 100 pl Val = pl Val + 1 Next List in g A.3 1 For St a t e m e n t ( C# ) f or ( pl Count = 0; pl Count < 100; pl Count ++) { pl Val = pl Val + 1; } Bot h of t hese loops perform t he exact sam e funct ion; however, t hey each have a very different synt ax. Generically, t he C# version of t he f or loop is writ t en as shown in List ing A.32. List in g A.3 2 Ge n e r ic C# for Loop f or ( i ni t i al i zat i on; t est ; i ncr ement ) { ... st at ement s; ... } W h ile Loop The whi l e loop is very sim ilar in bot h program m ing languages. List ing A.33 shows a t ypical whi l e loop in Visual Basic. List in g A.3 3 W h ile Loop ( Visu a l Ba sic .N ET) Whi l e pl Val 1 < pl Val 2 pl Val 1 = pl Val 1 + 1 Loop
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
I n t he C# program m ing language, t his sam e loop would be writ t en as shown in List ing A.34. List in g A.3 4 W h ile Loop ( C# ) whi l e( pl Val 1 < pl Val 2) { pl Val 1 = pl Val 1 + 1 } This synt ax is very sim ilar t o t hat of t he f or loop discussed previously. The t wo t hings t o rem em ber are t he parent heses around t he t est st at em ent and t he curly braces in place of t he Loop st at em ent t o enclose t he st at em ent s t o be execut ed while t he condit ional is t rue. Sw it ch Ve r sus Se le ct I n t he world of Visual Basic, one of t he m ost useful flow- cont rol st at em ent s is t he Sel ect . . . Case. . End Sel ect st at em ent . I t looks like t he code in List ing A.35. List in g A.3 5 Se le ct …Ca se …End Se le ct St a t e m e n t ( Visu a l Ba sic .N ET) Sel ect Case pl Val Case 1 psSt r = " Br i an" Case 2 psSt r = " Jon" Case El se psSt r = " El se! " End Sel ect I n C# , t his sam e st at em ent is called a swi t ch and is writ t en like t he code in List ing A.36. List in g A.3 6 sw it ch St a t e m e nt ( C# ) swi t ch( pl Val ) { case 1: psSt r = " Br i an" ; br eak; case 2: psSt r = " Jon" ; br eak; def aul t :
New Riders - Debugging ASP.NET
m ade by dot net er@t eam fly
psSt r = " Def aul t ! " ; br eak; }
Su m m a r y This appendix looked at t he ways in which t he Visual Basic program m ing language has changed from t he language t hat you know and love, for bet t er or worse. I t also discussed som e of t he very basic synt act ical changes t hat exist bet ween t he Visual Basic and C# program m ing languages. Wit h t his inform at ion, you will be prepared t o convert any exist ing Visual Basic code t o Visual Basic .NET—or even pot ent ially int o t he C# program m ing language. You will also be ready t o st art writ ing Visual Basic .NET or C# code from scrat ch wit hout having t o bat t le wit h t he new synt ax changes inherent in bot h languages. This will cert ainly help you when you’re t rying t o figure out why your new program s aren’t com piling properly.