Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Lookup Area Codes by Zip Codes with an ASP.NET Custom Control

4.38/5 (5 votes)
8 Nov 20067 min read 1   585  
This article describes the construction of a simple custom control used to lookup an area code and a city/state location based upon a selected zip code; the lookup is performed through the use of an available public web service.

Introduction

This article describes the construction of a simple custom control used to lookup an area code and a city/state location based upon a selected zip code; the lookup is performed through the use of an available public web service. The article includes the source code for this custom control as well as a demonstration site used to test the control.

The custom control contains a zip code property. Once set, the control will pass the zip code as an argument to a web method which will, if the zip code is valid, return the city, state, and area code associated with the zip code. The control will display the zip code, area code, and location whenever the zip code property is set or changed.

The demonstration web site included with this example provides an interface to change the zip code property for the control and to update the content displayed in the control. The web service is provided through www.webservicex.com, and is available for use at no cost.

Image 1

Figure 1: Area Code Custom Control in Use

Getting Started

The files included with this project include a web control library project and a demonstration web site. In order to get started, open the included zip file and install the two projects onto your file system. Open IIS, and create a virtual directory for the web application. Open the solution into Visual Studio 2005 and make any changes necessary to bring both projects into the solution.

Once properly configured, your solution explorer should show these projects, references, and files:

Image 2

Figure 2: Solution Explorer with Web App and Control Library

In examining the solution, note that the “AreaCodeLookup” control library contains only a single control and that control is called “AreaCodeLookup”. This project also includes a web reference that points to the http://www.webservicex.net site; this public site supports the web service used to capture the area code and location information associated with the user supplied zip code.

The web application contains only a single web page (default.aspx) and includes a reference to the “AreaCodeLookup” DLL.

The web application serves as a container used to test the custom control; the default.aspx page contains an instance of the custom control as well as an interface for submitting zip codes to the control.

The Code: AreaCodeLookup

The “AreaCodeLookup” custom control is constructed to retrieve the information from the web service upon initialization and to use that information to populate a collection of properties; each of the properties is set to contain one of the values collected from the web service.

The web service returns the requested data in the form of an XML node; this node is imported into an XML document which is parsed to obtain the individual values used to populate the member variables. These member variables are in turn used to display the area code and location information when the page is rendered.

In examining the code, note that, aside from the default imports, only the System.XML class has been added. The class itself inherits from the WebControl class.

VB
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Text
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Xml


<DefaultProperty("ZipCode"), _
   ToolboxData("<{0}:AreaCodeLookup runat=server>" & _ 
   "</{0}:AreaCodeLookup>")> _
Public Class AreaCodeLookup
    Inherits WebControl

Following the class declaration, a region entitled “Declarations” is created and within that region are the declarations for any of the private member variables used within the control. In this case, there is only a single member variable as I opted to store all of the property values directly into view state.

VB
#Region "Declarations"
     Private mGetAreaCode As net.webservicex.www.USZip

#End Region

After the variable declarations, there is another region defined (Methods) and within that region is the code used to capture the data from the web service, and to read the XML returned by that service and use the values to populate the properties. The initialization handler calls a subroutine called “GetAreaCode” each time the control is initialized. GetAreaCode accepts a single argument in the form of a string bearing the zip code.

Inside the GetAreaCode subroutine, a new XML node is created. This node is populated with the return value derived from calling the web services “GetInfoByZip” web method. This node is checked to determine whether or not it is empty; if it is empty, the properties are set to contain an indication that the supplied zip code was invalid and the GetAreaCode subroutine is exited. If the node is not empty, an XML document is created and the node is imported into that document. This XML document is then parsed and its values are captured into the object’s properties. When the control is rendered the properties are displayed to the user.

The code contained in the Methods region is as follows:

VB
#Region "Methods"
     Private Sub AreaCodeLookup_Init(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Init

        AreaCode = ""

        'get the area code for the current zip
        GetAreaCode(ZipCode)

    End Sub

    Public Sub GetAreaCode(ByVal zip As String)

        Try

            mGetAreaCode = New net.webservicex.www.USZip
            Dim xn As XmlNode = mGetAreaCode.GetInfoByZIP(zip)

            If xn.HasChildNodes = False Then
                AreaCode = "XXX"
                ZipCode = "INVALID"
                City = "XXX"
                State = "XX"
                Exit Sub
            End If

            Dim xdoc As New XmlDocument
            xdoc.AppendChild(xdoc.ImportNode(xn, True))


            Dim wsNodes As XmlNodeList
            Dim wsNode As XmlNode

            ' get area code
            wsNodes = xdoc.GetElementsByTagName("AREA_CODE")

            For Each wsNode In wsNodes
                AreaCode = wsNode.ChildNodes(0).Value
            Next

            ' get city name
            wsNodes = xdoc.GetElementsByTagName("CITY")

            For Each wsNode In wsNodes
                City = wsNode.ChildNodes(0).Value
            Next

            ' get state name
            wsNodes = xdoc.GetElementsByTagName("STATE")

            For Each wsNode In wsNodes
                State = wsNode.ChildNodes(0).Value
            Next

        Catch

            AreaCode = "XXX"
            ZipCode = "INVALID"
            City = "XXX"
            State = "XX"

        End Try

    End Sub

#End Region

The next region defined in the code is called “Properties”. Properties contains a collection of one public property and three private properties. The public property is used to contain the zip code; the other private properties contain the area code, city, and state. All property values are maintained in view state, these properties are:

VB
#Region "Properties"
     <Category("Zip Code")> _
    <Browsable(True)> _
    <Description("Enter the five number zip code.")> _
    Public Property ZipCode() As String
        Get
            Dim s As String = CStr(ViewState("ZipCode"))
            If s Is Nothing Then
                Return String.Empty
            Else
                Return s
            End If
        End Get

        Set(ByVal Value As String)
            ViewState("ZipCode") = Value
        End Set
    End Property

    Private Property AreaCode() As String
        Get
            Dim s As String = CStr(ViewState("AreaCode"))
            If s Is Nothing Then
                Return String.Empty
            Else
                Return s
            End If
        End Get

        Set(ByVal Value As String)
            ViewState("AreaCode") = Value
        End Set
    End Property

    Private Property City() As String
        Get
            Dim s As String = CStr(ViewState("City"))
            If s Is Nothing Then
                Return String.Empty
            Else
                Return s
            End If
        End Get

        Set(ByVal Value As String)
            ViewState("City") = Value
        End Set
    End Property

    Private Property State() As String
        Get
            Dim s As String = CStr(ViewState("State"))
            If s Is Nothing Then
                Return String.Empty
            Else
                Return s
            End If
        End Get

        Set(ByVal Value As String)
            ViewState("State") = Value
        End Set
    End Property

#End Region

The attributes of category, browsable, and description are used to provide design time support for the custom control. The category and description text will be displayed in the IDE’s property editor whenever this control is selected by the developer using the control.

Having captured the values from the XML string returned from the web service, and having populated the properties using the values contained in the XML, the only remaining step is to render the control. A region entitled, “Rendering” follows and it contains the code necessary to render the control on the page.

The code used to render the control is pretty simple; the HtmlTextWriter is used to define a table and set up its characteristics (cell padding in this example), each row of the table contains two cells, a label and its associated value are placed into each of those two cells. The City and State properties are combined into a Location string and displayed adjacent to the label reading “Location”. Once all of the data has been written into the table, the ending tag is rendered and the control is complete.

Naturally, you can change the configuration of the table or remove some of the data returned from the web service by making changes in the definition of the HTML as defined through the HtmlTextWriter. If accessibility is an issue, you may wish to render the control based upon the user of a “div” in lieu of the table. The rendering operation is wrapped up in a Try-Catch block; if the rendering operation fails, the catch block will display some placeholder text. The RenderContents subroutine is overridden and the HTML is formatted within this subroutine through the use of the HtmlTextWriter.

VB
#Region "Rendering"
     Protected Overrides Sub RenderContents(ByVal _
                        output As HtmlTextWriter)

        Try

            output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "3")
            output.RenderBeginTag(HtmlTextWriterTag.Table)

            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.AddAttribute(HtmlTextWriterAttribute.Align, "left")
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write("<b>Zip Code: </b>")
            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write(ZipCode)
            output.RenderEndTag()

            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.AddAttribute(HtmlTextWriterAttribute.Align, "left")
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write("<b>Area Code: </b>")
            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write(AreaCode)
            output.RenderEndTag()

            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.AddAttribute(HtmlTextWriterAttribute.Align, "left")
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write("<b>Location: </b>")
            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Td)
            output.Write(City & ", " & State)
            output.RenderEndTag()

            output.RenderEndTag()
            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.RenderBeginTag(HtmlTextWriterTag.Tr)

            output.RenderEndTag()

            output.RenderEndTag()

        Catch ex As Exception

            output.Write("Area Code From Zip")

        End Try

    End Sub

#End Region

The Code: The Demo Site’s Default Page

The default.aspx page contained within the demo site serves only a test container for the control. The page contains a Label control used to title the page, a textbox used to capture zip codes, and a button to submit requests. The property editor may be used in the IDE to set the zip code property or, as is indicated in the submit button event handler, the zip code property may be edited while the web application is in use.

Image 3

Figure 3: Setting the Zip Code Property at Design Time

The button click event handler’s code is as follows:

VB
Protected Sub btnLookup_Click(ByVal sender As Object, _
          ByVal e As System.EventArgs) _
          Handles btnLookup.Click

    If Not String.IsNullOrEmpty(txtZip.Text.ToString()) Then
        Try

            Dim chr() As Char = txtZip.Text.ToCharArray()
            Dim iLoop As Integer
            For iLoop = 0 To chr.Length - 1
                If Char.IsLetter(chr(iLoop)) Then
                    txtZip.Text = "INVALID"
                    Exit Sub
                End If
            Next

            AreaCodeLookup1.ZipCode = txtZip.Text
            AreaCodeLookup1.GetAreaCode(txtZip.Text)

        Catch ex As Exception

        End Try
    End If

End Sub

Image 4

Figure 4: After Entering an Invalid Zip Code

The handler is pretty straight forward, the contents of the text box used to capture the zip code is first checked to make sure it is not empty. If isn’t empty, the contents are checked to make sure that the value does not contain characters. If characters are encountered the text box text is set to display INVALID and the event handler subroutine is exited. If the text box contains a valid entry, the custom control’s zip code property is set and then the control’s GetAreaCode subroutine is called with text box text value passed in as the zip code argument.

From there, the custom control will, through the web service, update the area code, city, and state values which will in turn be displayed on the page through the control.

Summary

This project was intended to describe a useful, easy to build custom control. While this demonstration was limited to describing the AreaCodeLookup custom control, the same approach applied herein would work with a variety of other custom controls. The project itself describes some of the procedures that may be used to communicate with a web service through a custom control.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here