dotNet - 2006 - 01

Embed Size (px)

Citation preview

  • 8/8/2019 dotNet - 2006 - 01

    1/52W W . D O T N E T D E V E L O P E R S J O U R N A L . C

    Presented by

    THE WORLDS LEADING .NET RESOURTHE WORLDS LEADING .NET RESOUR

    THE SHAPE OFi-TECHNOLOGY TO COME

    2005 Volume3 Issue12

    Create XML Easily with FOR XML PATHNew FOR XML features simplify XML creation

    Creating Composite Server

    Controls in ASP.NET 2.0Make new components from old

    PresortedStandard

    US PostagePAID

    St. Croix Press

    Coming...

    March 13, 2006New York Citywww.ajaxseminar.com

    Marriott Marquis

    Times Square, NYC

    SEEPAGE

    25

    FORDETAIL

    S

    Building a custom server control

    The OO Database AdvantagePainless object-oriented databases

  • 8/8/2019 dotNet - 2006 - 01

    2/52

  • 8/8/2019 dotNet - 2006 - 01

    3/52

    Want to accelerate resolution

    of Web performance problems?

    You can with WebLOAD Analyzerthe only load testing tool

    with root cause analysis for .NET and Microsoft Web applications.

    WebLOAD Analyzer employs unique black box software to

    capture actual problems at multiple synchronized levels, enabling

    users to drill down to the individual component. By pinpointing

    the root cause of all kinds of application problems, WebLOAD

    Analyzer reduces problem resolution time by 60%significantly

    improving application performance and eliminating finger pointing

    once and for all.

    The Smart Choice in Web Application Testing RadView Software,Limited.All rights reserved.

    Eliminate the finger pointing with WebLOAD Analyzer.0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 0 1 0 1

    0 0 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 0 0 1 0 1 1 0 1

    1 0 1 0 1 1 0 1 0 0 0 1 0 1 1 0 1 0 0 0 1 1 1 0 1 0 0 1 0 1 0 1 0 1 0 1 1

    Get a FREE No more finger pointing T-shirt. > > > > Learn more at www.radview.com/analyze

    App Dev: It must be a database problem.

    DBA: I suspect its your application server

    code thats causing the problem.

  • 8/8/2019 dotNet - 2006 - 01

    4/524January 2006 dotnetdevelopersjournal.co

    EDITORIAL

    Five Development Tools I Wish I HadBy Derek Ferguson ...................................................................7

    BOOK REVIEW

    Amazon.com Top 10 .NET BooksProvided by Amazon.com........................................................8

    SQL SERVER 2005

    Create XML Easily with FOR XML PATHBy Jerry Dixon............................................................................22

    PERFORMANCE

    The OO Database AdvantageBy Rick Grehan and Eric Falsken ...........................................26

    ASP.NET

    When Design andDevelopment First MetBy Nina Meiers...........................................................................34

    TIPS & TRICKS

    DataWindow.NET How To:DataWindow FormattingBy Bruce Armstrong .................................................................42

    BOOK REVIEW

    .NET 2.0 GenericsBy Dennis Hayes .......................................................................48

    MONO

    Mono Releases Version 1.1.10and New RoadmapBy Dennis Hayes .......................................................................50

    InsideDNDJ10

    38

    J a n u a r y 2 0 0 6 V o l u m e 4 I s s

    30

    MAKE NEW COMPONENTS FROM OLD

    BY WES WEEKS

    Creating Composite Server Controls

    in ASP.NET 2.0

    The Shape of i-Technologyto Come

    BY JEREMY GEELAN

    BUILDING A CUSTOM SERVER CONTROL

    BY JEEVAN MURKOTH

    Google Maps and ASP.NET

  • 8/8/2019 dotNet - 2006 - 01

    5/52

  • 8/8/2019 dotNet - 2006 - 01

    6/52

    4

    4

    4

    4

  • 8/8/2019 dotNet - 2006 - 01

    7/527dotnetdevelopersjournal.com January 2006

    ve been doing a lot of cod-

    ing lately. This has been a

    bit of a departure from my

    usual work as a technology

    evangelist or a development manager,

    but as you might imagine it has

    been quite a lot of fun! Having said this,

    the process of actually sitting down

    and coding for 12 hours a day over the

    past few months has left me wishing

    that Visual Studio .NET shipped witha handful of additional capabilities in

    the box.

    Track Changes

    If youve ever written a book oreven an article you have probably

    encountered the track changes fea-

    ture of Microsoft Word. By turning on

    change tracking, every modification

    that is made to a document is recorded

    and a history of changes is kept. This

    may sound a lot like source control and,

    in fact, it is.

    There are two important differ-

    ences. The first is that, whereas source

    control specializes in storing multiple

    historical versions of a given document

    at a central location where multiple

    developers can access them via a check-

    in/check-out process, change tracking

    in Microsoft Word doesnt do any of this.It just stores additional metadata in a

    single, local copy of a document.

    The second difference which is

    what I would like to see added to Visual

    Studio to work in conjunction with

    source control is the way in which

    these historical changes are displayed.

    By looking at a document in Word that

    is under change control, I can instantly

    see (via annotations in the margin) who

    made changes to each bit of it, when

    they changed it, etc. Wouldnt it be great

    to be able to tell instantly by looking

    at a piece of code who added a certain

    line of it, and when? It would make it

    so much easier to figure out whose

    butt needed kicking when you see rank

    stupidity.

    Automated File Use Request

    In keeping with the topic of sourcecontrol for a moment we have been

    using Source Safe. There are quite afew of us on the team and we have not

    (because it never works out right) turned

    on multiple check-outs. This means

    that I have to e-mail people two or three

    times a day every day to ask them if I

    could please use their files. Id like to be

    able to ask Visual Studio to do this for

    me, right off the dialog where it tells me

    that a given file is currently in use.

    Remote Desktop for Two Monitors

    If you have two monitors at theoffice, drag some of your windows

    (like Solution Explorer) onto your

    second monitor, and then try to

    Remote Desktop into your worksta-

    tion when you get home. You will dis-

    cover that Remote Desktop only gives

    you access to your primary monitor

    and that it is very hard to get back

    the windows that are on your second

    monitor.

    Mock Environment Generator/

    Automatic Expand-and-Collapse-All

    for Solution Explorer

    I lump these two together at the endbecause I am aware of third-party solu-

    tions that do both of these things. Im

    cheap, though so Id like it for free in

    the box.

    What tools would you like to see as a

    part of Visual Studio .NET? Let me know

    at [email protected]!

    Editorial

    EDITORIAL [email protected]

    Editor-in-ChiefDerek Ferguson [email protected]

    Executive EditorSeta Papazian [email protected]

    Group PublisherJeremy Geelan [email protected]

    Mobility EditorJon Box [email protected]

    Security EditorPatrick Hynds [email protected]

    Open Source EditorDennis Hayes [email protected]

    Product Reviews EditorDoug Holland d [email protected]

    VB EditorKeith Franklin [email protected]

    Smart Client EditorTim Huckaby [email protected]

    BizTalk EditorBrian Loesgen [email protected]

    ADVISORY [email protected]

    Derek Ferguson [email protected] Papazian [email protected]

    Jeremy Geelan [email protected] Robbins [email protected] Gomez [email protected] Hanselman [email protected]

    Dean Guida [email protected] Sharp [email protected]

    Jacob Cynamon [email protected] Mayo [email protected] Cornell [email protected] Stagner [email protected] DeBetta [email protected]

    EditorNancy Valentine n [email protected]

    Online EditorRoger Strukhoff [email protected]

    WRITERS IN THIS ISSUEBruce Armstrong, Jerry Dixon, Eric Falsken, Derek Ferguson,

    Jeremy Geelan, Rick Grehan, Dennis Hayes, Nina Meiers,Jeevan Murkoth, Wes Weeks

    SUBSCRIPTIONSFor subscriptions and requests for bulk orders,

    please send your letters to Subscription Department

    Subscription Hotline: [email protected] Price: $6.99/issueDomestic: $69.99/yr. (12 issues)

    Canada/Mexico: $99.99/yr. Overseas: $129.99/yr.(U.S. banks or money orders). Back issues: $12/ea.,

    plus shipping and handling.

    EDITORIAL OFFICESSYS-CON Media 135 Chestnut Ridge Rd.,

    Montvale, NJ 07645Telephone: 201 802-3000 Fax: 201 782-9638.NET Developers Journal (ISSN#1541-2849) is

    published monthly (12 times a year) for $69.99 bySYS-CON Publications, Inc.,135 Chestnut Ridge Road,

    Montvale, NJ 07645.Postmaster: Send address changes to:

    .NET Developers Journal,SYS-CON Publications, Inc.,135 Chestnut Ridge Road

    Montvale, NJ 07645

    Copyright 2004 by SYS-CON Publications, Inc.All rights reserved. No part of this publication may be reproduced ortransmitted in any form or by any means, electronic or mechanical,including photocopy or any information storage and retrieval system,without written permission. For promotional reprints, contact ReprintCoordinator Dorothy Gil, [email protected].

    Worldwide Newsstand DistributionCurtis Circulation Company, New Milford, NJ

    Newsstand Distribution Consultant:Gregory Associates / W.R.D.S.732 607-9941 - [email protected]

    For list rental information:Kevin Collopy: 845 731-2684,[email protected];Frank Cipolla: 845 731-3832,[email protected]

    All brand and product names used on these pages are trade names,service marks, or trademarks of their respective companies. SYS-CONPublications, Inc., is not affiliated with the companies or productscovered in .NET Developers Journal. .NET and .NET-based marks aretrademarks or registered trademarks of Microsoft Corporation in the UnitedStates and other countries.

    SYS-CON Publications, Inc., reserves the right to revise,

    republish and authorize its readers to use the articlessubmitted for publication.

    Five Development Tools

    I Wish I Had BY DEREK FERGUSONEDITOR-IN-CHIEFAUTHOR BIO:

    Derek Ferguson is an

    associate director in the

    Information Technology Group

    at Bear Stearns, a leading global

    investment banking, securities,

    trading, and brokerage firm.

    [email protected]

    i

    It would make it so much easier to figureout whose butt needed kicking when you

    see rank stupidity

  • 8/8/2019 dotNet - 2006 - 01

    8/528January 2006 dotnetdevelopersjournal.co

    Book Review

    President and CEO

    Fuat Kircaali [email protected]

    President, SYS-CON Events

    Grisha Davida [email protected]

    Group Publisher

    Jeremy Geelan [email protected]

    ADVERTISINGSenior Vice President, Sales and Marketing

    Carmen Gonzalez [email protected]

    Vice President, Sales and Marketing

    Miles Silverman [email protected]

    Advertising Director

    Robyn Forma [email protected]

    Advertising Sales & Marketing Manager

    Dennis Leavey [email protected]

    Advertising Sales Manager

    Megan Mussa [email protected]

    Associate Sales Managers

    Dorothy Gil [email protected]

    Kim Hughes [email protected]

    PRODUCTIONProduction Consultant

    Jim Morgan [email protected]

    Lead Designer

    Tami Lima [email protected]

    Art Director

    Alex Botero [email protected]

    Associate Art Directors

    Louis F. Cuffari [email protected]

    Andrea Boden [email protected]

    Video Editor

    Frank Moricco [email protected]

    WEB SERVICESInformation Systems Consultant

    Robert Diamond [email protected]

    Web Designers

    Stephen Kilmurray [email protected]

    Shawn Slany [email protected]

    Vincent Santaiti [email protected]

    ACCOUNTINGFinancial Analyst

    Joan LaRose [email protected]

    Accounts Payable

    Betty White [email protected]

    Accounts Receivable

    Gail Naples [email protected]

    SYS-CON EVENTSPresident, SYS-CON Events

    Grisha Davida [email protected]

    National Sales Manager

    Jim Hanchrow [email protected]

    201 802-3012

    888 303-5282

    [email protected]

    CUSTOMER RELATIONSCirculation Service Coordinators

    Edna Earle Russell [email protected]

    Linda Lipton [email protected]

    JDJ Store Manager

    Brunilda Staropoli [email protected]

    Amazon.com Top 10 .NET Books

    PROVIDED BY

    MCAD/MCSD

    Self-Paced

    Training Kit:

    Developing

    Web

    Applications

    with Microsoft Visual Basic

    .NET and Microsoft Visual C#

    .NET, Second Edition

    by Microsoft Corporation

    Microsoft

    Visual Basic

    .NET Step byStep Version

    2003

    by Michael Halvorson

    Applied

    Microsoft .NET

    Framework

    Programming

    by Jeffrey Richter

    MCSD .NET

    Solution

    Architectures

    Exam Cram 2

    (Exam 70-300)

    by Randy Cornish

    Programming

    ASP.NET

    by Jesse Liberty

    Developing

    Application

    Frameworks in

    .NET

    by Xin Chen

    10MCAD/MCSD

    Training Guide

    (70-320):

    Developing

    XML Web

    Services and

    Server Components with

    Visual C# .NET and the .NET

    Framework

    by Amit Kalani

    MCAD/MCSD

    Training Guide

    (70-315):Developing

    and

    Implementing

    Web Applications with Visual

    C# and Visual Studio.NET

    by Amit Kalani

    Programming

    Microsoft

    Visual Basic

    .NET Version

    2003 (Book &

    CD-ROM)

    by Francesco Balena

    9

    8

    7

    5

    4

    2

    6

    3

    MCAD/MCSD Self-Paced

    Training Kit: Microsoft

    .NET Core Requirements

    by Microsoft Corporation1

  • 8/8/2019 dotNet - 2006 - 01

    9/52

    W E H E L P Y O U D E L I V E R

    T H E W H O L E P A C K A G E

    V E R I O S U P P L I E S T H E B E S T T E C H N O L O G Y , R E S O U R C E A N D E X P E R T I S E T O S U P P O R T Y O U R . N E T S O L U T I O N

    When you partner with Verio, you

    deliver complete solutions for you

    customers business needs. As you

    trusted expert advisor for manage

    hosting, we support your applicat

    development with our managed

    services and infrastructure from

    state-of-the-art Verio data center

    As a viaVerio partner, youll enha

    your solutions portfolio and add v

    to your business by gaining access

    to our suite of global products an

    services, including managed stora

    and security. Youll also gain peac

    of mind in knowing that Verio

    is backed by the financial and

    operational excellence of NTT

    Communications, the world's large

    telecommunications company.

    BUILD YOUR BUSINESS BY

    PARTNERING WITH THE MANAGE

    HOSTING INFRASTRUCTURE EXPE

    Nothing turns on the power of

    the Internet like Verio products

    and services.

    CALL 866.237.4121 today to find

    out more about how a viaVerio

    partnership can complete yourbusiness offering. Or visit:

    www.verio.com/partners

    Power. Performance. Results.

    Verio, viaVerio and the Verio logo are trademarks andservice marks of Verio Inc. in the United States and ocountries. All other names are trademarks or registeremarks of their respective owners. 2005 Verio Inc.All rights reserved.

  • 8/8/2019 dotNet - 2006 - 01

    10/5210January 2006 dotnetdevelopersjournal.co

    am sure that most of

    you have heard about or

    have had a chance to use

    Google Maps. Its a greatservice and I was really impressed

    by the responsiveness of the appli-

    cation and the ease with which

    users could drag and zoom maps

    from a Web browser. It has in many

    ways heralded the arrival of AJAX

    (Asynchronous JavaScript and XML),

    which I am sure will revitalize Web

    development in the days to come.

    What makes the service even bet-

    ter is the availability of the Google

    Maps API (Application Programming

    Interface) as a free Beta service. The

    API allows developers to embed

    Google Maps in their custom

    applications. It also allows them to

    overlay information on the map and

    customize the map to their needs.

    As I write this article there are quite

    a few sites that utilize Google Maps,

    and more and more of them are

    appearing by the day.

    The API by itself is pretty

    straightforward and easy to use;

    however, it requires the developer to

    have a good command of JavaScript

    because it extensively relies on cli-

    ent-side Java scripting. In this article

    we will be looking at building acustom ASP.NET server control that

    would allow a .NET developer to

    harness the power of Google Maps

    in the code-behind model. We will

    see how to accomplish most of the

    functionality exposed by Google

    Maps using this control, and well

    also see how to data bind the con-

    trol, thereby allowing developers to

    easily build data-driven custom ASP.

    NET Web applications. The control

    would eliminate the need for the

    developer to write any JavaScript to

    accomplish most of the Google Map

    functionality.

    Some Google Maps Basics

    Before we get into the details of

    the ASP.NET control, lets look at the

    basics of the Google Maps API. A

    detailed description of the API can

    be found at www.google.com/apis/

    maps/documentation/ . The first

    step before using Google Maps is to

    register for a key with Google (www.

    google.com/apis/maps/signup.

    html). This is absolutely free and

    hardly takes a few minutes. Each

    Web site that uses Google Maps has

    to have its own key. Make sure that

    you go through Googles Terms of

    Use (www.google.com/apis/maps/

    terms.html) before you start using

    Google Maps in your application.

    Google represents an instance

    of the map as a GMap object. It is

    rendered as a div tag on the page.

    Once you have the map, it is pos-

    sible to add controls to the map.

    Some of the available controls arethe GMapType control that helps to

    toggle between the different views,

    namely map view, satellite view,

    and finally, the hybrid view that is

    a combination of map and satel-

    lite views. The other controls that

    are usually seen on the map are

    the ones used to add scrolling and

    zooming capability to the map. At

    the time of writing of this article,

    there are three different controls

    available:

    GLargeMapControl: A large con-

    trol for scrolling and zooming

    GSmallMapControl: Similar to

    the previous one, but eliminates

    the zoom scale bar

    GSmallZoomControl: Includes

    only Zooming controls

    Once the map has been set up, i

    is possible to overlay information on

    the map. The information can be in

    the form of points or lines, though

    points are the most common ones.

    In order to overlay a point on the

    Google Map, its necessary to know

    its longitude and latitude. At this

    time, Google does not provide anygeo-coding services that give the

    co-ordinates corresponding to an

    address, but there are a couple of

    free services available on the inter-

    net that do so. www.Geocoder.us is

    one of them and given a US address

    it returns the longitude and latitude

    for the same. Once the longitude

    and latitude have been obtained,

    create an instance of a GPoint

    (which is Googles representation

    of a point on the map), then create

    i

    Building a custom server contro

    BY JEEVAN MURKOTH

    Figure 1: GMap control on the toolbar

    in Visual Studio .NETf1

    ASP.NET

    Google Maps and ASP.NET

  • 8/8/2019 dotNet - 2006 - 01

    11/52

  • 8/8/2019 dotNet - 2006 - 01

    12/5212January 2006 dotnetdevelopersjournal.co

    ASP.NET

    a GMarker using this point and add

    the marker to the instance of the

    Google Map. In order to Center and

    Zoom on a point, the GMap Object

    exposes a method ZoomandCenter

    that takes the point and the level of

    zoom required as the parameter. Just

    like points, it is possible to overlay

    lines on the Map. Those of you who

    have used Google Maps for direc-

    tions will be familiar with the lines

    used to depict the route. In order

    to add a line to the Google Map,

    we need to create an instance of

    a GPolyLine object and pass in an

    array of GPoints to plot it. It is also

    possible to assign color, width, and

    opacity to the line. Another useful

    feature in Google Maps is the abilityto show a pop-up window when the

    user clicks on a Marker. Google Calls

    this pop-up window by the name

    InfoWindow.

    The Google Maps ASP.NET

    Control (GMAP Control)

    The main aim of this control is

    to allow .NET developers to utilize

    the functionality of Google maps as

    a server-side control by writing little

    to almost no JavaScript at all. It is

    more of a .NET wrapper around the

    Google API; however, because it is

    a full-fledged ASP.NET server-side

    control, it is possible to bind data

    to the control, thereby increasing

    the usability of Google Maps. In the

    following sections we will see how

    to use this control to implement

    most of the common functionality

    of Google Maps. Before we do so,

    lets take a look at the control. The

    principal class of the control is the

    GMapControl class. This class in

    turn references the following classes

    (most of these classes are the .NET

    equivalents of the classes used by

    Google):

    GPoint: This is the class represen-

    tation of a geographical point andexposes latitude and longitude as

    its two properties.

    GPoints: This class represents a

    collection of GPoint objects.

    GIcon: Represents a custom

    icon that is used as an overlay

    on the map. The GIcon class

    exposes the following proper-

    ties: the Image URL, which as the

    name suggests, is the URL of the

    image used to represent the icon;

    ShadowImageURL is the URL of

    the shadow associated with the

    icon; IconSize and ShadowSize

    represent the size of the icon

    and the shadow, and the last two

    properties are IconAnchor and

    InfoWindowAnchor, which specif

    the point where the icon should

    be anchored to the map relative

    to its top-left corner and the poin

    where the Info window should be

    anchored to the map.

    GLine: This is a line that the user

    wishes to overlay on the map.

    By default it takes a collection

    of points (GPoints) as an argu-

    ment in its constructor. It is also

    possible to set the color of the

    line as well as its weight and

    opacity through an overloadedconstructor.

    GMarker: This is the .NET repre-

    sentation of the Google Maps clas

    GMarker. The default constructor

    accepts an instance of a GPoint

    class. It also has an overloaded

    constructor that takes a GIcon

    along with the GPoint in case the

    developer wishes to use a custom

    icon to represent the marker.

    GSize: Represents a two-dimen-

    sional size measurement.

    Figure 2: Output in the Web browser for Listing 2f2 Figure 3: Output in the Web browser for Listing 3f3

  • 8/8/2019 dotNet - 2006 - 01

    13/52

  • 8/8/2019 dotNet - 2006 - 01

    14/5214January 2006 dotnetdevelopersjournal.co

    ASP.NET

    JScriptGenerator: This is an inter-

    nal class and has more of a helper

    function. It generates most of

    the JavaScript functions that are

    needed by the control.

    HelperColorConvertor: This class

    is used to convert a color into its

    equivalent Hex value. This class is

    marked as internal.

    HelperDataResolver: This is an

    internal class that helps in data

    binding and has just one method.

    The method casts a datasource

    object into an object that imple-

    ments the IEnumerable interface.

    The help file that describes in

    detail the different methods and

    properties of the classes involved

    is available as a download.

    Getting Started in ASP.NET

    Before we use the ASP.NET con-

    trol in our application, there are a

    few things that need to be taken

    care of to ensure that it works as

    desired.

    Web.config File

    The GMAP control renders itself

    as a DIV tag, however for non

    Internet Explorer Browsers, ASP.

    NET renders the div tag as tables. If

    you want the page to render the

    GMAP control properly in other

    browsers such as Netscape and

    Firefox, include the browser cap

    section shown in Listing 1 into

    the Web.config file of your

    application.

    Page Configuration

    Google has certain recommen-

    dations for the HTML standards

    on pages that contain the map to

    make sure that the layout is pre-

    dictable across different browsers.

    A detailed description of the same

    can be found in the Google maps

    documentation. It is imperative

    that you follow these standards,

    especially if you plan to overlay

    lines on your map. For lines to berendered on the map, you need to

    include the VML namespace in the

    HTML page for Internet Explorer

    browsers. Make sure that you dont

    forget to do this, because otherwise

    the lines will not be displayed in

    Internet Explorer. The HTML tag of

    your page should at the minimum

    look like the snippet below:

    Adding to the Toolbar

    This step is optional; however if

    you are using Visual Studio .NET as

    your IDE, I would recommend that

    you go ahead and add the GMap

    control to your toolbox. The advan-

    tage of doing so is that you can easil

    drag and drop the GMap control

    onto an ASPX page like any other

    ASP.NET control, and Visual Studio

    will automatically register the con-

    trol on your page. Figure 1 shows th

    GMap control on the toolbar.

    Creating a Basic Map Using

    the Control

    Since we are done with the setup

    lets go ahead and create a simple

    example using the control. We will

    add the GMap control to the page,set its dimensions, and make it cen-

    ter and zoom at a particular point.

    For the sample application used in

    this article, I have saved the map key

    in the Web.config file and will be set

    ting the GoogleMapKey property of

    the control from the config file. I wil

    be setting the map type of the con-

    trol to be that that of Map. In case

    no map type is specified, the contro

    defaults to the preset Map. The

    GMap Control also supports satellit

    Figure 4: Output in the Web browser for Listing 4f4 Figure 5: Output showing the custom markersf5

  • 8/8/2019 dotNet - 2006 - 01

    15/52

    Security should never be an inhibitor to new opportunity: Forum XWall Web Services

    Firewall has been enabling Fortune 1000 companies to move forward with XML Web

    services confidently. Forum XWall regulates the flow of XML data, prevents unwanted

    intrusions and controls access to critical Web services.

    Visit us at www.forumsys.com to learn more about how you can take your next leap

    forward without increasing the risks to your business.

    forum systems the leader in web services security

    Forum XWall Web Services Firewall - Reinventing Security

    None of the Risk.

    XMLs Endless Possibilities,

  • 8/8/2019 dotNet - 2006 - 01

    16/5216January 2006 dotnetdevelopersjournal.co

    and hybrid map types. Make sure

    that you center and zoom at a point,

    otherwise all that will show up will

    be a grey area. Listing 2 shows the

    code for this example and Figure 2

    shows the output.

    Setting the GMap Control

    Properties

    Lets go ahead and set some

    properties to the basic example

    we just created. The GMap control

    exposes a set of properties that

    allows the developer to customize

    the control to his or her needs. If

    we wish to give the user the flex-

    ibility to change the view, we set

    the ShowMapTypeControl property

    of the control to true. By default,

    the user is able to drag the map,however, if we do not wish the

    user to drag the map around, we

    can set the EnableDragging prop-

    erty to false. To allow the user to

    be able to scroll or zoom, set the

    ScrollControlType property of the

    control. There are three different

    options: large, small, and zoom

    only, to correspond to the controls

    offered by Google. Listing 3 shows

    the source code and Figure 3 shows

    the output in the browser.

    Overlaying Markers and Pop-Up

    Windows

    Another cool feature of Google

    Maps is the ability to display mark-

    ers on the map and attach pop-up

    windows to these markers on the

    click event. It is possible to dis-

    play formatted HTML containing

    links and images in these pop-up

    windows. Let us see how to do

    the same using the GMap ASP.

    NET control. Lets take the previ-

    ous example and modify it to add

    two markers. One would be a plain

    marker and the other would have

    a pop-up window that would dis-

    play some text. The GMap ASP.NET

    control has an overloaded method

    called OverlayMarker that takes the

    formatted HTML as a string param-eter. If the overloaded method is

    called and some HTML is passed

    to the method, a click event is

    automatically passed to the marker

    and the info window is displayed.

    Listing 4 shows the code to overlay

    two markers and Figure 4 shows the

    output of the same.

    Overlaying Custom Markers

    Google gives us the flexibility

    to replace their standard marker

    icon with any custom icon that we

    specify. The same functionality is

    provided by the GMap ASP.NET con

    trol. In order to do so, we need to

    define a GIcon class with at least th

    following properties:

    URL of the image that would rep

    resent the GIcon

    URL of the shadow image

    Size of the image

    Size of the shadow

    The point at which the icon is to

    be anchored to the icon

    In case info windows are used,

    it is also necessary to specify the

    point where the info window is to

    be anchored to the map. For this

    example we will be borrowing the

    icons from the Google Ride Finderapplication. Lets take the same two

    points that we used in the marker

    example and replace the standard

    marker icons with these custom

    icons. The code in Listing 5 is same

    as that of Listing 4, except for the

    use of custom icons. Figure 5 shows

    the output.

    Overlaying Lines

    In this section we will see how

    to overlay a line on a Google Map.

    ASP.NET

    Figure 6: Rendering of the line in the browserf6 Figure 7: Multiple Google Map controls outputf7

  • 8/8/2019 dotNet - 2006 - 01

    17/52

  • 8/8/2019 dotNet - 2006 - 01

    18/5218January 2006 dotnetdevelopersjournal.co

    Lines can be overlaid on maps to

    denote routes, boundaries, or some

    other specific purpose a developer

    may deem necessary. As in the

    Google Maps API, the GMap ASP.

    NET control also allows overlay

    of lines. In the GMap control, the

    GLine class represents a line and

    takes a collection of GPoints to plot

    a line through them. It is also pos-

    sible to set the color, width, and

    opacity of the line. While the Google

    Maps API requires color to be

    passed in as a Hex value, the GMap

    control takes in a System.Drawing.

    Color structure, thereby making

    it easier to set the color by name.

    Listing 6 shows the code and Figure6 shows the rendering.

    Using Multiple Google Map

    Controls in a Page

    So far in all of the examples, we

    have dealt with one instance of the

    control in a page. It is possible to

    have any number of GMap controls

    in a single page and have granular

    control over each one of them. In

    this example, we have four instanc-

    es of the control and will center and

    zoom them on four different cities.

    Listing 7 shows the code and Figure7 shows the output in the browser. It

    is possible to have markers or lines

    on any of these controls.

    Binding Data to the Control

    The GMap ASP.NET control sup-

    ports data binding and it is possible

    to bind it to any data source that

    implements the IEnumerable inter-

    face, hence it can bind to most of

    the commonly used sources such as

    data tables, datasets, and collections.

    As of now the control only supports

    overlaying of standard markers via

    data binding. The control exposes

    the following properties that need to

    be set before data binding:

    MarkerLatitudeField: Property

    used to specify which field from

    the data source will bind to the

    latitude field of each marker in th

    control

    MarkerLongitudeField: Property

    used to specify which field from

    the data source will bind to thelongitude field of each marker in

    the control

    MarkerText: Property used to

    specify which field from the data

    source will bind to the Text field o

    each marker in the control (this is

    optional)

    DataSource: Property used to set

    the source of data

    In this example we will first

    populate a table with a point and

    then bind it to the GMap control.

    Listing 8 shows the code involved inthe example and Figure 8 shows the

    output.

    Conclusion

    The Google Maps API is very ver-

    satile. I hope this control will make it

    easier for .NET developers to harness

    the potential of this API.

    References

    Google Maps API documentation

    www.google.com/apis/maps/

    documentation/

    Google Maps news groups: www.

    google.com/apis/maps/

    documentation/

    Onion, F. (2003). Essential ASP.

    NET (Custom Controls). Addison-

    Wesley Professional.

    ASP.NET

    Figure 8: Output from Listing 8f8

    Listing 1: Browser Cap Section

    browser=Netscape

    frames=true

    tables=true

    cookies=true

    javascript=true

    javaapplets=true

    cmascriptversion=1.5

    w3cdomversion=1.0

    css1=true

    css2=true

    xml=true

    tagwriter=System.Web.UI.HtmlTextWriter

    version=6.0

    majorversion=6

    minorversion=0

    beta=true

    version=7.0

    majorversion=7

    minorversion=0

    beta=true

  • 8/8/2019 dotNet - 2006 - 01

    19/5219dotnetdevelopersjournal.com January 2006

    Listing 2: Basic Map

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {GMapControl1.Width=400;

    GMapControl1.Height=400;

    GMapControl1.MapType=MapControl.GMapType.MAP;

    GMapControl1.GoogleMapKey=Configuration-

    Settings.AppSettings[DevKey];

    GMapControl1.CenterAndZoom

    (new GPoint(36.224264,-86.628273),9);

    }

    Listing 3: Setting Properties

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    GMapControl1.Width=400;

    GMapControl1.Height=400;

    GMapControl1.MapType=MapControl.GMapType.MAP;

    GMapControl1.ScrollControlType=MapControl.

    GMapScrollControl.LARGE ;

    GMapControl1.EnableDragging=false;

    GMapControl1.ShowMapTypeControl=true;

    GMapControl1.GoogleMapKey=Configuration-

    Settings.AppSettings[DevKey];

    GMapControl1.CenterAndZoom

    (new GPoint(36.224264,-86.628273),9);

    }

    Listing 4: Overlaying Markers

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    GMapControl1.Width=400;

    GMapControl1.Height=400;

    GMapControl1.MapType=MapControl.GMapType.MAP;

    GMapControl1.ScrollControlType=MapControl.

    GMapScrollControl.LARGE ;

    GMapControl1.ShowMapTypeControl=true;

    GMapControl1.GoogleMapKey=Configuration-

    Settings.AppSettings[DevKey];

    GPoint myPoint= new GPoint(36.1645,-86.7811);

    GPoint myPoint2= new GPoint(36.224264,-

    85.928273);string sFormattedHtml=Nashville


    Visit Nashville ;

    GMarker myMarker= new GMarker(myPoint);

    GMarker myMarker2= new GMarker(myPoint2);

    //Overloaded constructor

    GMapControl1.OverlayMarker(myMarker,sFormatted

    Html);

    GMapControl1.OverlayMarker(myMarker2);

    GMapControl1.CenterAndZoom(myPoint,9);

    }

    Listing 5: Custom Markers

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    GMapControl1.Width=400;

    GMapControl1.Height=400;

    GMapControl1.MapType=MapControl.GMapType.MAP;

    GMapControl1.ScrollControlType=MapControl.

    GMapScrollControl.LARGE ;

    GMapControl1.ShowMapTypeControl=true;

    GMapControl1.GoogleMapKey=Configuration-

    Settings.AppSettings[DevKey];

    GPoint myPoint= new GPoint(36.1645,-86.7811);

    GPoint myPoint2= new GPoint(36.224264,-

    85.928273);

    string sFormattedHtml=

    Nashville

    Visit

    Nashville ;

    GMarker myMarker= new GMarker(myPoint);

    //Creating our custom icon

    GIcon myIcon = new GIcon();

    myIcon.ImageURL=http://labs.google.com/

    ridefinder/images/mm_20_blue.png;

    myIcon.ShadowImageURL=http://labs.google.com/

    ridefinder/images/mm_20_shadow.png;

    myIcon.ShadowSize= new GSize(22,20);

    myIcon.IconSize = new GSize(12,20);

    myIcon.IconAnchor= new GPoint(6,20);

    myIcon.InfoWindowAnchor= new GPoint(5,1);

    GMarker myMarker2= new GMarker(myPoint2);

    myMarker.Icon=myIcon;

    GMapControl1.OverlayMarker(myMarker,sFormatted

    Html);

    myMarker2.Icon=myIcon; myMarker2.Icon.

    ImageURL=http://labs.google.com/ridefinder/

    images/mm_20_green.png;

    GMapControl1.OverlayMarker(myMarker2);GMapControl1.CenterAndZoom(myPoint,9);

    }

    Listing 6: Overlaying Lines

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    GMapControl1.Width=400;

    GMapControl1.Height=400;

    GMapControl1.MapType=MapControl.

  • 8/8/2019 dotNet - 2006 - 01

    20/5220January 2006 dotnetdevelopersjournal.co

    ASP.NET

    GMapType.MAP;

    GMapControl1.ScrollControlType=

    MapControl.GMapScrollControl.LARGE ;

    GMapControl1.ShowMapTypeControl=true;

    GMapControl1.GoogleMapKey=Configura-

    tionSettings.AppSettings[DevKey];

    // Creating the 3 points through which

    the line passes

    GPoint pt1 = new GPoint(40.631096,-

    75.488627);

    GPoint pt2= new GPoint(35.113813,-

    85.321043);

    GPoint pt3= new GPoint(33.590040,-

    101.866815);

    //Adding it to the points collections

    GPoints ptList= new GPoints();

    //Adding it to the points collections

    ptList.Add(pt1);

    ptList.Add(pt2);

    ptList.Add(pt3);

    //Adding the points collection to the

    line

    GLine myline = new GLine(ptList);

    //Setting the Color , weight and

    Opacity

    myline.LineColor=Color.Blue;

    myline.Weight =3;

    myline.Opacity=1;

    GMapControl1.OverlayLine(myline);

    GMapControl1.CenterAndZoom(pt2,14);

    }

    Listing 7: Multiple Controls in a Page

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    //First Control

    GMapControl1.Width=200;

    GMapControl1.Height=200; GMapControl1.

    GoogleMapKey=ConfigurationSettings.

    AppSettings[DevKey];

    GMapControl1.CenterAndZoom(new GPoint

    (36.224264,-86.628273),9); //Second Control

    GMapControl2.Width=200;

    GMapControl2.Height=200; GMapControl2.

    GoogleMapKey=ConfigurationSettings.

    AppSettings[DevKey];

    GMapControl2.CenterAndZoom

    (new GPoint(35.07,-85.27),9);

    //Third Control

    GMapControl3.Width=200;

    GMapControl3.Height=200; GMapControl3.

    GoogleMapKey=ConfigurationSettings.

    AppSettings[DevKey];

    GMapControl3.CenterAndZoom(new GPoint

    (30.32,-97.77),9);

    //Fourth ControlGMapControl4.Width=200;

    GMapControl4.Height=200; GMapControl4.

    GoogleMapKey=ConfigurationSettings.

    AppSettings[DevKey];

    GMapControl4.CenterAndZoom

    (new GPoint(39.57,-75.10),9);

    }

    Listing 8: Data Binding in GMap Control

    privatevoid Page_Load(object sender, System.

    EventArgs e)

    {

    GMapControl1.Width=400;GMapControl1.Height=400;

    //create the datatable

    DataTable dt = new

    DataTable(Databind);

    dt.Columns.Add( new DataColumn

    (latitude,typeof(double)));

    dt.Columns.Add( new DataColumn

    (longitude,typeof(double)));

    dt.Columns.Add( new DataColumn

    (htmltext,typeof(string)));

    //Filling the datatable

    for( int i=0; i

  • 8/8/2019 dotNet - 2006 - 01

    21/52

  • 8/8/2019 dotNet - 2006 - 01

    22/5222January 2006 dotnetdevelopersjournal.co

    BY JERRY DIXON

    SQL Server 2005

    Create XML Easily with FOR XML PATH

    o you love XML? Have

    you been using XML with

    SQL Server? Many people

    have, starting way back

    when with SQL Server 7.0. Back then,

    there was no support for XML in the

    database, so we had to write external

    programs to convert the relational

    data into an XML format. This was

    time-consuming and often inef-

    ficient. When SQL Server 2000 came

    out, with its integrated support for

    XML, there were a lot of high expec-tations. Unfortunately, XML still

    couldnt be easily stored in the data-

    base, although it could be created

    and consumed. XML couldbe stored

    in the database as a large string of

    text, but this was problematic at

    best. Large VARCHAR and TEXT

    strings are hard to manipulate. This

    worked, though, and programmers

    managed to create great systems.

    Still, something more was needed.

    Many people looked forward to

    the next version of SQL Server, and

    hoped for a better solution.

    SQL Server 2005 is now here, and

    with it comes a new XML data type

    and support for the new XQuery

    language. XML can now be stored

    directly in the database, queried, and

    even edited in place. In addition,

    the existing creation and consump-

    tion capabilities from SQL 2000 have

    been enhanced. XML can be created

    and consumed much more easily

    than ever before. With all of these

    enhancements, how should one pro-

    ceed?

    Last year, I couldnt wait for the

    ability to store XML in the database.I was sure that this capability would

    be the answer to all of my XML-relat-

    ed problems. Because SQL Server

    2005 now has an XML data type, we

    can store entire documents directly

    in a column of a table. I was posi-

    tive that this would be the first new

    feature that I would use. However,

    an unexpected thing occurred along

    the way: Microsoft enhanced the

    FOR XML clause. It is much easier to

    create XML from relational data than

    it ever was before. Ive found that

    I havent been using the XML data

    type nearly as often as I expected.

    Instead, Ive been storing data

    relationally, creating the XML as

    needed. I believe that this gives my

    applications the best features of both

    worlds. Therefore, I wish to pass this

    information on to you.

    This article will introduce some

    of the new XML-creation features in

    SQL Server 2005 and provide some

    guidance regarding their use. It willdemonstrate how much easier it is

    to create XML in SQL Server 2005

    that it ever was in SQL Server 2000.

    Well walk through the creation of a

    small XML document and discuss

    each step in detail. Because of space

    limitations, the XML data type and

    the related XQuery language will be

    covered in a future column.

    FOR XML EXPLICIT Refresher

    In order to fully appreciate the

    new SQL Server 2005 features, you

    must first understand the difficulties

    faced by SQL Server 2000 develop-

    ers. These are best illustrated with an

    example. Lets examine a simple XML

    document that I created from data in

    the new AdventureWorks database

    (see Listing 1). The document has

    a single root element that contains

    multiple Category elements. These

    elements, in turn, contain multiple

    SubCategory elements. (Ellipses

    are used to indicate sections where

    similar elements have been removed

    for space reasons.) The Category and

    SubCategory elements each have a

    Name attribute. This small, straight-

    forward document is complex enoug

    for our purposes.

    In Listing 2, Ive created a FOR

    XML EXPLICIT query that creates

    the demonstration document. This

    query is representative of those com-monly created with SQL Server 2000.

    Notice that there are three individual

    SELECT statements joined together

    via UNION ALL clauses. Each SELEC

    statement corresponds to a node in

    the resulting XML document. Each

    column in the SELECT statements is

    named according to a special scheme

    which helps define the structure of

    the resulting document. There are

    also columns (Tag and Parent)

    that exist for no other purpose than

    to define the document schema. To

    make matters worse, the ORDER BY

    clause must be carefully designed

    in order to make the resulting docu-

    ment nest properly. While this proces

    works, with larger documents it can

    quickly become too complex to be

    practical. In addition, because of the

    fact that it is based on UNION claus-

    es, it is highly repetitive. Maintenanc

    of such queries can become very diff

    cult. (I once created such a query wit

    12 individual SELECT statements.

    What a nightmare that was!)

    FOR XML Enhancements

    SQL Server 2005 has a solutionto these shortcomings. There is a

    new PATH directive in the FOR XML

    clause. This directive allows much of

    the structure, or schema, of the resul

    ing XML document to be specified

    via XPath. Take the code in Listing 3

    for example. The SELECT statement

    returns a single column whose alias

    is an XPath expression. The expres-

    sion indicates that the column result

    should become an attribute called

    Name. (In XPath, the @ symbol

    d

    New FOR XML features simplify XML creation

  • 8/8/2019 dotNet - 2006 - 01

    23/5223dotnetdevelopersjournal.com January 2006

    indicates an attribute. The lack of this

    symbol indicates an element. See an

    XPath reference for more information.)

    When executed, this code will create

    the XML document shown in Listing

    4. As you can see, this creates an ele-ment for each row, with the attribute

    name that we specified; however, each

    element is named row. This is prob-

    ably not what we would want in our

    actual document. Fortunately, there is

    a solution for this too. In Listing 5, Ive

    altered the SELECT statement so that

    the resulting elements will be named

    Category. The results are shown in

    Listing 6.

    If you glance back at Listing 1,

    youll notice that weve managed to

    reproduce the Category elements

    contained in that document. Next,well need to write some code for the

    SubCategory elements. This code,

    along with its results, is shown in

    Listing 7. This SELECT statement is

    very similar to the one for the Category

    elements, except that the data is

    retrieved from a different table and

    the results get placed in different ele-

    ments.

    Now that we have the data for both

    sets of elements, we need a way to

    combine them together appropriately.

    The new TYPE directive can be used for

    this. The TYPE directive specifies that

    the XML created in a FOR XML query

    should be returned as an instance of

    the XML data type. The data can then

    be stored in an XML variable, placed in

    an XML column in a table, or further

    manipulated in T-SQL statements. It

    is this last capability that we will use.

    With the TYPE directive, we now have

    the ability to nest FOR XML PATH que-

    ries. This allows us to create XML docu-ments of almost any depth. You can see

    this technique in use in Listing 8. Ive

    combined the queries for the Category

    and SubCategory elements, linking

    them together with an appropriate

    WHERE clause. The XML produced is

    shown in Listing 9.

    Although the XML document is

    now well formed and properly nested,

    it is not yet valid. XML documents

    should have only one root element.

    If you look at our document, youll

    see that we have four instances of the

    Category element, all at the root level.We need to change our last query so

    that it produces one root element and

    includes the Category elements under-

    neath this new root. To do this, we can

    take advantage of one final enhance-

    ment. The FOR XML clause now has a

    ROOT directive, which indicates that

    a root element should be created for

    us. By default, this root element will be

    given the name root. If we so desire,

    we can also specify the name of this

    root element. In Listing 10 you can see

    the query with this directive added.

    The final XML document is shown in

    Listing 11.

    Weve now come full circle. If you

    compare Listing 1 (produced with FOR

    XML EXPLICIT) and Listing 11 (pro-

    duced with FOR XML PATH), youll

    see that they are identical. However,

    the new syntax is much cleaner and

    easier to create (compare Listings 2

    and 10 to see this). The performance

    of the two implementations is similar,although the execution plan for the

    FOR XML PATH query is noticeably

    smaller. Because of this, FOR XML

    PATH queries should edge out FOR

    XML EXPLICIT queries when larger

    or more complicated documents are

    created. When you factor in readability

    and maintenance, the new method

    wins hands down.

    Summary

    When I started using the XML

    support in SQL Server 2005, I fully

    expected that I would be storing datainside tables as XML. I thought that

    this would be the easiest way to send

    XML to applications outside the server.

    As Ive learned more about the prod-

    uct, I have seen how the improved

    FOR XML clause makes the creation of

    XML documents easier to accomplish

    and maintain. This has changed my

    perceptions. With the new FOR XML

    PATH clause, we can store our data

    relationally and easily produce the

    XML when needed. In this way, we can

    take advantage of the capabilities of

    both data formats. We can use the rela-

    tional data in a JOIN, for example, and

    produce the XML whenever necessary.

    With SQL Server 2005, the choice is

    now ours.

    Listing 1: XML Document

    ...

    ...

    ...

    Listing 2: SQL 2000 FOR XML EXPLICIT

    SELECT

    1 AS Tag,NULL AS Parent

    ,NULL AS XML!1

    ,NULL AS Category!2!Name

    ,NULL AS SubCategory!3!Name

    UNION ALL

    SELECT DISTINCT

    2 AS Tag

    ,1 AS Parent

    ,NULL AS XML!1

    ,Name AS Category!2!Name

    ,NULL AS SubCategory!3!Name

    AUTHOR BIO:

    Jerry Dixon is a senior devel-

    oper and architect for ACH

    Food Companies in Memphis,

    Tennessee. Over the past 16 year

    he has led development projects

    for a number of enterprise, mid-

    level, and small business organiza

    tions. While he has fulfilled multiple

    roles as an infrastructure designer

    database administrator, and soft-

    ware developer, he specializes in

    XML, SQL and ASP.NET. He is a

    co-leader and frequent presenter

    at the Memphis .NET User Group

    Jerry holds the following Microsoft

    certifications: MCSD (VB 6.0

    and .NET), MCDBA (SQL 2000),

    MCSA (Windows 2000 and 2003)

    MCSE (Windows 2000), MCAD(.NET), MCT. He resides in Olive

    Branch, MS with his wife and son

    4 [email protected]

  • 8/8/2019 dotNet - 2006 - 01

    24/5224January 2006 dotnetdevelopersjournal.co

    SQL Server 2005

    FROM Production.ProductCategory

    UNION ALL

    SELECT

    3 AS Tag,2 AS Parent

    ,NULL AS XML!1

    ,c.Name AS Category!2!Name

    ,sc.Name AS SubCategory!3!Name

    FROM Production.ProductCategory c

    INNER JOIN Production.

    ProductSubCategory sc

    ON c.ProductCategoryID =

    sc.ProductCategoryID

    ORDER BY

    Category!2!Name

    ,SubCategory!3!Name

    FOR XML EXPLICIT

    Listing 3: FOR XML PATH

    SELECT Name AS @Name

    FROM Production.ProductCategory

    FOR XML PATH

    Listing 4: FOR XML PATH Results

    Listing 5: Named Element

    SELECT Name AS @Name

    FROM Production.ProductCategory

    FOR XML PATH(Category)

    Listing 6: Named Element Results

    Listing 7: SubCategory Example

    SELECT Name AS @Name

    FROM Production.ProductSubCategory

    FOR XML PATH(SubCategory)

    ...

    Listing 8: Combining the Queries

    SELECT c.Name AS @Name,

    (SELECT sc.Name AS @Name

    FROM Production.ProductSubCategory sc

    WHERE sc.ProductCategoryID =

    c.ProductCategoryID

    FOR XML PATH(SubCategory), TYPE)

    FROM Production.ProductCategory c

    FOR XML PATH(Category)

    Listing 9: Combined Results

    ...

    ...

    ...

    Listing 10: Adding a Root Element

    SELECT c.Name AS @Name,

    (SELECT sc.Name AS @Name

    FROM Production.ProductSubCategory sc

    WHERE sc.ProductCategoryID =

    c.ProductCategoryID

    ORDER BY sc.Name

    FOR XML PATH(SubCategory), TYPE)

    FROM Production.ProductCategory c

    ORDER BY c.Name

    FOR XML PATH(Category), ROOT(XML)

    Listing 11: Final Results

    ...

    ...

    ...

  • 8/8/2019 dotNet - 2006 - 01

    25/52

    RIGHT 2006 SYS-CON MEDIA ALL RIGHTS RESERVED NOTE: SPEAKER LINE-UP SUBJECT TO CHANGE WITHOUT NOTICE

    23

  • 8/8/2019 dotNet - 2006 - 01

    26/5226January 2006 dotnetdevelopersjournal.co

    Performance

    The OO Database AdvantagePainless object-oriented databases

    BY RICK GREHAN

    eres a question: If you write

    your applications code in

    an OO language such as

    C#, VB.NET, or managed

    C++ why not write database query

    and update code in the same language?

    It would certainly make life simpler,

    wouldnt it? At the very least, youd only

    have to hold one language in your head

    not your programming language and

    SQL.

    Thats the very least of the advan-

    tages youd gain by choosing an OOdatabase instead of an RDBMS. The

    metaphor impedance mismatch

    has frequently been used to illustrate

    the problems that arise from using a

    relational database as the back end to

    an OO application. Admittedly, its a

    somewhat overused metaphor, but it

    still serves its purpose. It illustrates the

    fact that relationships among objects

    referencing, containment, polymor-

    phism, and so on must be translated

    into relational constructs when those

    objects are stored in the database.

    Furthermore, the translations require

    developer intervention at some point:

    either explicitly in executable code, by

    creating schema mapping files that a

    translation layer reads and interprets, or

    through some other mechanism.

    The upshot is that you have to

    explain the object structure of your

    application to a relational database

    and in terms that the relational data-

    base understands. Sometimes this even

    requires you to add elements to one or

    more of your objects elements that

    translate to additional columns in one

    of the RDBMS tables, and serve no

    purpose other than to support objectrelationships.

    Specifically, suppose you have an

    OO application whose objects struc-

    tures exhibit a tree-like or networked

    arrangement. With regard to entities

    that your program can treat as a single

    (albeit complex) object, the back-end

    RDBMS must distribute across multiple

    rows and (likely) multiple tables. For

    example, deleting a single tree which

    in OO code would be the mere drop-

    ping of a reference turns into multiple

    delete operations on multiple tables.

    (Source code for this article is avail-

    able from www.everylittlething.net/

    PartsAssembly/.)

    Illustration by Example

    Suppose you must write an applica-

    tion for an assemblies database that

    is, a database whose content tracks

    items that are assembled from parts.

    A part. in this case, could be just

    about anything: a screw, a light bulb, a

    spring, or even a software component.It doesnt really matter: the idea is that

    assemblies are constructed by connect-

    ing parts together, and in turn, more

    complex assemblies can be fabricated

    by connecting assemblies together.

    The aggregation of lower-level

    assemblies continues until a top-level

    assembly (or a finished product)

    is reached. Therefore for example, a

    motherboard assembly consisting of

    circuit board, CPU, and memorypart

    objects is combined with a power-

    supply assembly, a disk-drive assembly,

    and a chassis assembly to create a desk-

    top system. This structure is illustrated

    in Figure 1.

    This kind of database is nicely

    portrayed in an object-oriented struc-

    ture. The Part class is the fundamental

    building block. From it, one derives a

    PartAssembly class (which models an

    Assembly from Figure 1, but which we

    renamed in order to sidestep any con-

    fusion with .NETs meaning of the word

    assembly). The PartAssembly class

    extends the Part class by adding an

    ArrayList collection of components.

    Members of the components col-

    lection are required to assemble this

    PartAssembly.

    If we strip away the method defini-

    tions for these classes, the structure

    becomes transparently obvious (see

    Listing 1). When implemented in a

    relational database, the class structure

    in Listing 1 would require two or three

    tables, depending on how a person

    modeled the inheritance relation.

    In a three-table arrangement, Partobjects would be stored in one table,

    PartAssembly objects in a second,

    and the contents of the components

    ArrayList in a third. (This kind of map-

    ping from OO to relational is referred t

    as horizontal mapping.) The column

    structure of the Part and PartAssembly

    tables would be identical, because the

    only difference between the two the

    components element in PartAssembly

    would be stored in the third table. Th

    components dictionary table would

    hold two columns, one for the Part, an

    a second to reference the PartAssembly

    identifier. This second column is a for-

    eign key, and provides the connection

    between the components and their

    owning PartAssembly object.

    In a two-table solution, Part and

    PartAssembly would share the same

    table (this is known as filtered map-

    ping). That table would include

    columns for category, name, manufac-

    turer, and manufacturerPartNumber.

    An extra column would be added cal

    it classID that would be used to dis-

    tinguish rows that correspond to Part

    objects from rows that correspond to

    PartAssembly objects.The advantage of the three-table

    mapping strategy is its conceptual sim

    plicity. Each concrete class gets its own

    table. It is also more easily extended. If

    for example, a new class were defined

    that extended PartAssembly, the devel

    oper would need only to construct a

    new table.

    On the other hand, the two-table

    strategy has the advantage of minimiz-

    ing the number of tables required.

    However, adding a new descendant

    i

    AND ERIC FALSKEN

    Assembly

    Assembly Assembly

    Part Part Part Part Part

    Figure 1: The structure of the

    assembly database fits nicely into

    object-oriented grooves. Parts

    belong to assemblies, and both are

    derived from the same base class.

    f1

  • 8/8/2019 dotNet - 2006 - 01

    27/52

    23

  • 8/8/2019 dotNet - 2006 - 01

    28/5228January 2006 dotnetdevelopersjournal.co

    Performance

    class to either Part or PartAssembly

    (with new data members) would

    require adding new columns to the

    table, as well as new logic to identify the

    additional class type.

    Simplicity Calls

    Wouldnt it be nice if all this discus-

    sion of mapping strategies were unnec-

    essary? As weve stated already, this sort

    of class structure is easily modeled in

    an OO language. It follows that the ideal

    situation would be if that easy modeling

    were simply extended to the database.

    Put another way, our object structures

    schema is built into the very architec-ture of our class definitions. Why should

    we have to create yet another schema

    for the back-end database, and then

    build a mapping layer to translate data

    from one schema to another? Wouldnt

    it be nice if we could simply design our

    classes, write our application, and store

    objects right into the database as-is?

    With an OO database, we can.

    For the remainder of this article well

    demonstrate how to do this by using an

    open source database, db4o. Microsoft

    .NET and Mono versions of db4o are

    freely available from www.db4objects.

    com.

    Assuming that we have defined the

    Part and PartAssembly classes as above,

    and that the path to our database file is

    in string variable filename, we can store

    Part objects into a db4o database with

    the code in Listing 2.

    This is more like it. Rather than

    clutter our application with SQL code

    flanked by assignment statements

    that pass object contents into bind

    variables, we have a single call to a

    set() method. Most important: notice

    that we did not have to describe thestructure of a Part object to the db4o

    database engine; it deduced that infor-

    mation itself, via reflection.

    Also notice that db4o invisibly

    began a transaction for us. The db4o

    engine supports the ACID database

    concepts (atomicity, consistency, isola-

    tion, and durability). We need merely

    close the transaction with a call to

    commit(). Had something gone awry

    during the transaction, we could have

    called abort(), and all operations that

    had occurred since the last commit() o

    open() would be rolled back.

    Retrieving an object from this OO

    database is just as easy as storing it. We

    dont have to assemble an objects piec

    es from multiple tables; instead, we capull it from the database with a single

    call. All we need is a query mechanism

    to identify the specific object we want.

    db4o provides this mechanism via

    its QBE (query by example) API. QBE,

    as implemented by db4o, is an easy-

    to-understand query technique that

    uses a template object to define the

    query. We fill the template objects field

    with those values we want the query to

    match. Fields that should not partici-

    pate in the query are set to null or zero

    (depending on the datatype).

    Therefore, if we wanted to fetchthe Part object we had just stored into

    the database, we could use the code

    in Listing 3. The query in Listing 3

    matches all Part objects whose name

    field is Desktop Board D945GNT (we

    presume there is only one). Matching

    objects are placed in the ObjectSet

    result. The ObjectSet class provides ha

    Next() and next() methods, which allow

    navigation-through-iteration on the

    sets contents.

    The query fetched a Part object

    from the database. As defined, the

    Part object is relatively simple that

    is, it contains only strings as member

    variables. The PartAssembly class,

    however, contains a collection, and th

    collection contains objects. One would

    expect that fetching a PartAssembly

    object collection and all would be

    more difficult.

    Actually, it is only slightly more

    difficult. Although db4o lets us pull

    an entire object tree into memory, we

    might not want to. For example, we ma

    want to fetch one or more PartAssemb

    objects from the database, without

    fetching the contained collection.

    We can control how deeply db4oreaches into an object tree (when it

    retrieves a complex object from the

    database) by adjusting db4os activa-

    tion depth. By default, the activation

    depth is set to 5, which means that

    retrieving a PartAssembly object would

    also retrieve the collection. (So, fetch-

    ing a wholePartAssembly would use

    code that is virtually identical to the

    code in Listing 3.) To retrieve only the

    PartAssembly without the compo-

    nents collection we can set the globa

    category name manufacturer manufacturerPartNumbermemory

    cpu

    hard drive

    PC-2 5400 DDR

    Pentium 4

    DiamondMax

    Generic

    Intel

    Maxtor

    25400 DDR

    BX8O547PG32OOF

    6Y25OMO6Y25OMO

    category name manufacturer manufacturerPartNumber

    Desktop Sys. Desk Mod 01 My Computers DTM0D01

    PartAssembly Table

    Components Table

    Part Table

    parent partDTMODO1

    DTMODO1

    PC-2 5400 DDR

    Pentium 4

    DTMODO1 DiamondMax

    (a)

    (b)

    categoryc lass name manufacturer manufacturerPartNumbermemory

    cpu

    hard drive

    Desktop Sys.

    P

    P

    P

    A

    PC-2 5400 DDR

    Pentium 4

    DiamondMax

    Desk Mod 01

    Generic

    Intel

    Maxtor

    My Computers

    25400 DDR

    BX8O547PG32OOF

    6Y25OMO6Y25OMO

    DTMOD)1

    PartAndAssembly Table

    Components Table

    parent part

    DTMODO1

    DTMODO1

    PC-2 5400 DDR

    Pentium 4

    DTMODO1 DiamondMax

    Figure 2: Two techniques for mapping objects to relational databases. (a) Each class receives its own table.

    The components collection (in the PartAssembly class) is stored in a separate table, with a foreign key reference

    back to the parent item in the PartAssembly table. (b) Both Part and PartAssembly classes are stored in a

    single table. A column is added to identify the class to which a particular row of data belongs.

    f2

  • 8/8/2019 dotNet - 2006 - 01

    29/5229dotnetdevelopersjournal.com January 2006

    activation depth to 0, prior to opening

    the database as follows:

    Db4o.configure().activationDepth(0);

    Any database opened after theabove call would have its activation

    depth set to 0.

    Finally, deleting objects is as

    straightforward as fetching them. If

    we wanted to delete the Part object

    retrieved in the Listing 3, it requires a

    single line (placed where the ellipses are

    in the listing):

    Database.delete(mb);

    followed at some point, of course, with

    a commit().

    Changes on the Fly

    Suppose that a change in the

    applications requirements demands a

    change in an objects structure per-

    haps something as simple as a new

    field. For example, suppose that you

    decided the Part class needed an alter-

    nateSupplier field.

    With an RDBMS back end, you

    would have to modify one or more

    tables, plus make additions to the

    translation code, update the schema

    mapping file, and so on. However, with

    db4o, the alteration requires absolutely

    nothing beyond the change to the Part

    class definition (plus any added or

    modified methods you would have to

    write in any case):

    public class Part {

    private string category;

    private string name;

    private string manufacturer;

    private string manufacturerPart-

    Number;

    private string alternateSupplier;

    . . .

    }

    Everything else remains the same.

    When db4o fetches a Part object from

    the database, it will find no content foralternateSupplier, and set that field to

    null. However, if we then assign a value

    to that field and return the object to the

    database, the effect will be to turn the

    old Part object into a new one (see

    Listing 4).

    Thus, after the execution of the code

    in Listing 4, any time we fetch from the

    database the Part object associated with

    Desktop Board D945GNT, it will have

    an alternateSupplier field of Dougs

    Board Outlet.

    OO All the Way

    An object-oriented database makes

    a great deal of sense for a database

    application whose content is easily

    modeled in OO fashion. The mapping

    code required to move data betweenobjects in the application and tables on

    the RDBMS is eliminated. Furthermore,

    such an application is simply easier to

    work with, because there is no concep-

    tual boundary that must be crossed

    between the object model and the rela-

    tional model.

    The open-source database engine

    db4o made our illustration of these prin-

    ciples all the easier thanks to db4os API,

    which is both easy to grasp and func-

    tionally powerful. In one sense, db4o

    hits a kind of sweet spot in that it is not

    overly complex, nor under-powered.

    A complete .NET application that lets

    you create and manipulate a database

    identical to what weve described in this

    article is available from www.everylit-

    tlething.net/PartsAssembly/ . The appli-

    cation was written using Visual Studio

    2005, and includes everything you need

    to experiment with the Assembly data-

    base structure. We encourage you to

    explore the application, and discover the

    benefits of OO all the way.

    AUTHOR BIOs:

    Rick Grehan is a QA engineer at

    Compuwares NuMega Labs, whe

    he has worked on Java and .NET

    projects. He is also a contributing

    tor for InfoWorld Magazine. His ar

    have appeared in Embedded Sys

    Programming, EDN, The Micropro

    Report, BYTE, Computer Design,

    other journals. He is also the coau

    three books on computer program

    [email protected]

    Eric Falsken recently joined the db

    team as technical evangelist aft

    spending a few years working on

    embedded medical devices as a d

    user. He has been a staunch supp

    of Microsoft .NET (much to the chof his open sourceloving co-work

    and enjoys coming up with new id

    elegantly usable software, and me

    fellow students of software. You c

    read his blog at www.everylittlethin

    net/blog/.

    [email protected]

    Listing 1public class Part {

    private string category;private string name;private string manufacturer;private string manufacturerPartNumber;. . .

    }

    public class PartAssembly : Part {private System.Collections.ArrayList components;. . .

    }

    Listing 2

    // Open the ObjectContainerObjectContainer Database = Db4o.OpenFile(fileName);

    // Create a new Part objectPart mb = new Part ( Motherboard,

    Desktop Board D945Gnt,Intel,BOXD945GNT);

    // Put it in the databaseDatabase.set(mb);

    // Commit the transaction and// close the databaseDatabase.commit();Database.close();

    Listing 3

    // Create a Part template object

    Part PartTemplate = new Part (null,Desktop Board D945GNT,null, null);

    // Execute the queryObjectSet result = Database.get(PartTemp);

    // Retrieve the matching objectif(Result.hasNext()) {

    Part mb = (Part) result.next();// Do something with the Part. . .

    }

    Listing 4

    // Create a Part template objectPart PartTemplate = new Part (

    null,Desktop Board D945GNT,null, null, null);

    // Execute the queryObjectSet result = Database.get(PartTemp);

    // Retrieve the matching objectif(Result.hasNext()) {

    Part mb = (Part) result.next();// Update the alternateSuppliermb.AlternateSupplier = Dougs Board Outlet;

    // Return the object to the databaseDatabase.set(mb);

    }

  • 8/8/2019 dotNet - 2006 - 01

    30/5230January 2006 dotnetdevelopersjournal.co

    ne underutilized tech-

    nique for maximizing

    code reuse and increas-

    ing developer produc-

    tivity is the creation and utilization

    of ASP.NET Server controls. Even

    when the problem domain is well

    known and understood, each

    new project has many developers

    starting at square one, dragging

    and dropping the common Visual

    Studio.NET controls onto a blank

    form and having to manually

    repeat the same processes that

    other developers in the company

    have had to perform in the past.

    Server controls are an in-depth

    topic and it would take an entire

    book to do the subject justice.

    In this article I will explain the

    basics of how to create a type of

    server control called a Composite

    control, and to highlight some of

    the differences between ASP.NET

    1.x and ASP.NET 2.0 server con-

    trols. (Source code is available by

    viewing this article online in the

    .NETDJarchives, http://dotnet.

    sys-con.com/read/issue/archives/ ,[Vol: 4, iss: 1].)

    The Case for Server Controls

    Most businesses have certain

    sets or types of information that

    are ubiquitous to most of the

    applications being developed.

    Addresses, phone numbers, and

    customer names are just a few

    examples of common input col-

    lections that are often duplicated

    each time a new application is

    being developed. Much of this can

    of course be copied and pasted

    from one application to another,

    but when changes occur, these

    changes must then be made in

    multiple applications. An example

    of this type of change would be

    to an address for a company that

    has recently gone international

    and now must start capturing the

    country where their customers

    are located. By utilizing a server

    control, the display and client-side

    logic to handle this new data can

    be coded once, with developers

    now focusing on updating the busi-

    ness logic.

    The server control in our

    example creates a simple user

    interface (UI) for entering phone

    numbers. It is composed of a

    Labelcontrol, a TextBoxcontrol,

    and two validator controls: one is

    a RequiredFieldValidatorand the

    other is a RegularExpressionValida

    tor. One of the advantages of using

    composite controls is that you

    can utilize the ASP.NET controls

    built-in behavior to minimize theamount of code you have to write.

    For example, you will be able to

    utilize the validator controls to per-

    form their native functions without

    having to write any control-specific

    code.

    Defining a Composite Control

    One of the first things you

    will probably notice if you are

    familiar with developing server

    controls under the ASP.NET 1.x

    model is that our control inherits

    from System.Web.UI.WebControls

    CompositeControl(see Listing 1).

    In previous versions of the .NET

    Framework, you inherited from

    Control and had to implement

    the INamingContainerinterface.

    These steps, along with other

    functionality, are now taken care

    of by the CompositeControlbase

    class. The CompositeControlclass

    also has an associated control

    designer that ensures that child

    controls are displayed on the

    design surface.

    You will also notice several attr

    butes attached to the class defini-

    tion. These help define various

    characteristics of our control:

    AspNetHostingPermission: This

    is required to ensure that code

    that links to the control has the

    appropriate security permission

    DefaultProperty: Specifies the

    property to highlight in the

    property browser when the pag

    developer selects the control on

    the design surface

    ToolboxData: Used to specifythe format string for the design

    environment created when the

    control is added to a page

    Define Composite Control

    Properties

    The next step in our compos-

    ite control is to define the public

    properties that will be accessible

    via the property browser in Visua

    Studio.NET. Most of the proper-

    ties are a direct pass through to

    o

    BY WES WEEKS

    Creating Composite Server Controlsin ASP.NET 2.0

    Make new components from old

    ASP.NET

  • 8/8/2019 dotNet - 2006 - 01

    31/5231dotnetdevelopersjournal.com January 2006

    properties inherent of the controls

    that make up our composite control

    example. The code snippet in Listing

    2 demonstrates this pass-through

    technique.

    One of the nice features of ASP.

    NET 2.0 is the ability to assign a

    group name to a set of validators to

    ensure that validation occurs only for

    controls in the specified group. This

    enables you to have multiple sepa-rately-validated forms on a single

    page. In our property example above,

    the validation group is assigned to

    both of our validation controls dur-

    ing the set operation. It doesnt mat-

    ter which validator controls property

    we returned for the ValidationGroup

    get operation and our arbitrary

    choice was the value from the

    phoneRequired control.

    There are also several attributes

    on the property worth mentioning:

    Bindable: Indicates that the prop-

    erty supports data binding

    Category: Determines which cat-

    egory this property will be associ-

    ated with on the PropertyGrid

    Description: Tells the developer

    who is using the control what the

    property does

    Adding the Controls to the

    Controls Collection

    The next step in the process

    is to add the controls that make

    up our composite control to the

    Controls collection of the base

    CompositeControlsclass. This is a

    fairly straightforward process andsimply involves initializing our

    controls, setting any default prop-

    erties, and then utilizing the Add

    method to add them to the con-

    trols collection by overriding the

    CreateChildControls() method (see

    Listing 3).

    Define Style Properties

    Defining and using styles under

    ASP.NET 1.x took a considerable

    amount of work. Simply exposing

    the Style property of the controls

    within the composite control

    didnt work as expected, and though

    you would see the Style settings

    displayed in the property grid, set-

    ting them did not translate into

    run-time functionality. One of the

    reasons for this is that the ASPX

    page didnt have a location to store

    the values of the style settings.

    This has been remedied in 2.0 andmultiple style properties can be

    exposed and recorded in the ASPX

    page to allow styles to easily be set

    at design time. Our property for

    each style sheet resembles any of

    the other properties we have cre-

    ated. The way ASP.NET handles the

    Style properties can be viewed by

    looking at the HTML view in Visual

    Studio.NET.

    In this example we have set a

    specific style for the Label by set-

    ting the LabelStyleproperty in the

    property grid. This was translated

    into the LableStyleelement as a

    sub element of the phone control

    itself.

    Creating Custom Functionality

    Although creating a composite

    control in and of itself provides aconsiderable benefit in terms of

    code reuse and faster development,

    it is always nice to provide some

    additional functionality to enhance

    the controls usefulness. For our

    example we are going to provide the

    ability for our control to automati-

    cally put the phone number that

    is entered into a standard format.

    In order to accomplish this, we are

    going to render some JavaScript on

    the client that will be called when

    our control loses focus to provide

    the formatting (see Listing 4).

    The call to this method to render

    the JavaScript occurs during the

    OnPreRenderevent. The neces-

    sary control attribute to call the

    JavaScript function when the text-

    box loses focus was rendered in our

    CreateChildControls() method.

    AUTHOR BIO:

    Wes Weeks is president and CEO

    of AgileWise, a software develop-

    ment and consulting firm based

    in Topeka, KS. Wes has extensiv

    experience in object-oriented

    technologies, enterprise applicati

    architecture, and service-oriented

    architecture design and develop-

    ment. He is currently consulting f

    Security Benefit, an organization

    named one ofCIO Magazines

    Agile 100 in 2004 that has suc-

    cessfully employed numerous Ag

    methods and processes.

    4 [email protected]

    There were several changes to the ASP.NET server control model that improve upon

    the server control object model and to make control development easier. The list below

    highlights some of the most notable changes:

    ControlState: This is an alternative way for developers to persist control properties

    in the page without using ViewState. The advantage is that while ViewState can be

    turned off at the page level by the developer, ControlState cant, so the control devel-

    oper can be assured that data that has to be persisted for proper control function cant

    be turned off

    ValidationGroup: Allows a group of controls to be validated together so that the devel-

    oper can enforce validation on a subset of controls on a page

    CompositeControl: A new class that can be inherited from by control developers that

    eases the development and creation of composite server controls

    Styles: Working with CSS Styles has been made easier with the ability to expose Style

    properties into the property grid and have those changes created and stored in the

    ASPX page at design time

    Changes Between Developing Server ControlsUnder ASP.NET 1.x and 2.0

    By utilizing a server control, the display andclient-side logic to handle this new data can becoded once, with developers now focusing on

    updating the business logic

  • 8/8/2019 dotNet - 2006 - 01

    32/5232January 2006 dotnetdevelopersjournal.co

    ASP.NET

    One thing to note for those

    who have developed server con-

    trols under the 1.x paradigm is

    the ClientScriptproperty of the

    Page object. The ClientScript

    property is an object of type

    ClientScriptManagerand should

    be utilized instead of the Page.

    RegisterClientScriptBlock() method

    that has been deprecated. It has afew new arguments, including ask-

    ing for a type in addition to the key

    field to assist in matching up the

    client script to the control, as well

    as the ability to have the method

    automatically output the script tags

    by setting the addScriptTagsargu-

    ment to true, which is shown in this

    example.

    Override the Render Method

    The last step in the control

    creation is to override the render

    method to provide the formatting

    for our control on the page. In this

    example we render the multiple

    controls that make up our compos-

    ite control within a table to be sure

    the way the control gets rendered is

    consistent in any page that may

    use the control. This is also the

    location of where we render any

    Style attributes that are set at

    design time by the page developer

    (see Listing 5).

    Building and Using the Control

    The last step in the process is

    to add our created control to thetoolbox so that we can add it to

    our page by using drag and drop.

    The easiest way to do this is to

    open the toolbox panel, right-

    click on add/remove items, and

    then browse to the bin directory

    containing the assembly for the

    server control. This will add our

    control to the toolbox and from

    there it can be added to a Web

    form like any of the built-in con-

    trols. After adding a control to the

    toolbox we can now create a Web

    project. With the Web project

    newly created, drag and drop the

    phone control from the toolbox to

    a Web form. Lets also add a valida-

    tion summary control and a submit

    button.

    Start the Web project and enter

    in the area code and phone numbe

    without any symbols or format-

    ting. Notice how the number neatl

    formats itself when you move off o

    it provided it has either 7 or 10 dig-

    its. If it doesnt, formatting doesnt

    occur and the form wont submit

    due to our regular expression vali-

    dator. If you have set the Requiredproperty to true, the form will pre-

    vent you from submitting a blank

    number as well.

    Summary

    This fairly simple example dem

    onstrates how easy it is to begin

    creating custom server controls tha

    can be used to provide common

    functionality for your applications

    It demonstrates how to create a

    composite control, apply styles, an

    add custom functionality. Spendin

    the little bit of extra time to develo

    a custom control can result in pro-

    ductivity gains for developers and

    ease making global changes to the

    front end by having a single contro

    to maintain.

    Listing 1

    [AspNetHostingPermission(SecurityAction.

    LinkDemand,

    Level = AspNetHostingPermissionLevel.Minimal),

    DefaultProperty(Text),

    ToolboxData(

    )]

    publicclass PhoneControl : CompositeControl

    {

    private Label phoneLabel;

    private TextBox p