- A First Look at VB 7.0 and the .NET Framework
- A New Ballgame
- Summary
A New Ballgame
Not only do the development tools in Visual Studio .NET share common class libraries and a run-time engine, VC++, C#, and VB are also hosted within a common IDE. Each tool has its own set of project templates that take advantage of various aspects of the system classes. Within VB, this means that you can create a wider array of applications than were previously available. In the PDC Tech Preview, you'll encounter the project types listed in the following table.
Project |
Purpose |
Windows Application |
Used for creating desktop applications. Relies on the System.WinForms namespace. |
Class Library |
Used for creating custom class libraries. |
Windows Control |
Used for creating UI controls for desktop applications. Uses System.WinForms. |
Web Application |
Used to create a web project using ASP+. Relies on System.Web. |
Web Service |
Used to create and expose a web service using SOAP. Relies on the System.Web.Services namespace. |
Web Control |
Used to create controls for use in web applications. Relies on the System.Web.UI namespace. |
Console Application |
Used to create an application that runs at the command prompt. |
Windows Services |
Used to create a service application that runs in the background. Relies on the System.ServiceProcess namespace. |
In order to give you a feel for how VB 7.0 uses the .NET Framework, I'll walk through the creation of a simple web service application.
At its most basic level, a web service application is one that provides an RPC-style calling mechanism over HTTP. A web service consists of a URL listener that receives requests from clients wishing to call methods using the XML-based protocol SOAP (Simple Object Access Protocol). Clients build SOAP messages based on a Service Description Language (SDL) contract (also an XML document) that specifies what methods the web service exposes. The beauty of SOAP is that it allows your code to be called by clients running on any platform due to the platform independence of XML and HTTP. For more information on SOAP and to read the specification, see the articles at (http://msdn.microsoft.com/msdnmag/issues/0300/soap/soap.asp and http://msdn.microsoft.com/xml/general/soapspec.asp).
Unlike creating a web service application manually or using the SOAP Toolkit for Visual Basic 6 (http://msdn.microsoft.com/msdnmag/issues/0800/webservice/webservice.asp), creating one in VB 7.0 is simply a matter of selecting the Web Service project template. After naming the project, VB creates a virtual directory on the IIS server along with an ASP+ file with a .asmx extension to serve as the listener for the web service. For developers familiar with Visual Interdev, the resulting project is in many ways similar to a VID 6.0 project. The .asmx file is associated with a class file that you as a developer modify to expose the methods for the web service. The project uses System.Web.Services classes to provide the underlying code to implement the web service. As a result, you needn't worry about creating the SDL contract or writing code to invoke the requested methods. All you must do is define your methods and compile the application.
For this example, the web service is simply called NorthWindProducts and is used to expose a method called GetProductListing that allows users to query the product catalog of the SQL Server 7.0 Northwind database given a product category id. The method returns XML data to the user. This web service could be used by a client to incorporate the Northwind product catalog into their web sites or other applications.
As mentioned previously, the class file associated with the Products.asmx file contains the definition of the web service as shown below.
Imports System Imports System.Web.Services Imports System.Data Imports NWProductsData Namespace NWProducts Public Class NorthWindProducts Inherits System.Web.Services.WebService Public Function <WebMethod()> GetProductListing(ByVal CatID As Long) As DataSet Dim nwData As New NWProductsData.Products() Return nwData.GetProductListing(CatID) End Function End Class End Namespace
The interesting aspect of this file is its object-oriented nature. The definition of the web service begins by making references to other namespaces that will be used in this file using the Imports keyword. Conceptually, using Imports is similar to adding references to your VB 6.0 project through the Project | References menu option. The web service then defines a namespace called NWProducts that contains the web service class called NorthWindProducts. Note that this class inherits from System.Web.Services.WebService, which provides the underlying functionality necessary to properly invoke the method when called by a client. Finally, like class modules in VB today, the NorthWindProducts class exposes the GetProductListing method by creating a public function. The function, however, returns a DataSet object, which is an XML document provided by the System.Data namespace.
You'll also notice that the GetProductListing method instantiates a class called NWProductsData.Products to retrieve the data. This is a custom class created specifically for this application and referenced through the Imports keyword as NWProductsData. The NWProductsData.Products class uses the System.Data.SQL class to create a connection to SQL Server, call the stored procedure usp_ProdList, and return the resultset as an XML DataSet. The code for this class can be seen in Listing 1. Readers familiar with ADO should be able to see the similarities between the code in Listing 1 and the techniques used to query data using ADO 2.0 or ADO 2.5 today. One feature of the .NET run-time to be aware of when reading Listing 1 is the availability of constructors in the New statement, a concept not available in VB today.
Listing 1 Custom Data Class. This custom data class uses the System.Data.SQL class to connect to SQL Server, call a stored procedure with parameters, and return an XML DataSet.
Imports System Imports System.Data Imports System.Data.SQL Namespace NWProductsData Public Class Products Public Function GetProductListing(ByVal pCatID As Long) As DataSet ' Create Instance of Connection and Command Object Dim sqConnection As New SQLConnection() sqConnection.ConnectionString = _ "database=northwind;uid=sa;server=solutechnet" sqConnection.Open() Dim sqCommand As SQLDataSetCommand = New _ SQLDataSetCommand("usp_ProdList", sqConnection) ' Set the Command as a stored procedure sqCommand.SelectCommand.CommandType = CommandType.StoredProcedure ' Add Parameters to the procedure Dim parameterCatId As SQLParameter = New SQLParameter("@CatID", _ SQLDataType.Int, 4) parameterCatId.Value = pCatID sqCommand.SelectCommand.Parameters.Add(parameterCatId) ' Create and Fill the DataSet Dim objDataSet As DataSet = New DataSet sqCommand.FillDataSet(objDataSet, "usp_ProdList") ' Return the DataSet Return objDataSet End Function End Class
End NamespaceOnce the code is in place, you can compile the web service using the Build menu in the IDE. The class file is compiled into a DLL and placed under the virtual directory. Upon loading the Products.asmx in the browser, the run-time loads the DLL, which produces a test harness page for the component as shown in Figure 1.
Web Service Test Harness. This is the page that results from simply loading the web service's ASP+ page without a query string. The SDL contract is available in addition to allowing each method to be tested.
Entering the parameters and clicking Invoke will call the method of the web service class and return the XML in a separate browser window, as shown in Listing 2. Notice that the DLL can also produce the SDL contract on demand. Obviously client applications can also invoke the web service by building a URL such as: http://iisserver/NWProducts/Products.asmx/GetProductListing?CatID=1.
Listing 2 XML Product Data. This is the data produced by the web service. It is returned as a DataSet object represented as XML. Note that is contains an XML-Data schema automatically produced by ADO+.
<?xml version="1.0" ?> <DataSet> <schema id="DocumentElement" targetNamespace=""
xmlns="http://www.w3.org/1999/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> <element name="usp_ProdList"> <complexType content="elementOnly"> <element name="ProductID" type="int" /> <element name="ProductName" type="string" /> <element name="SupplierID" minOccurs="0" type="int" /> <element name="CategoryID" minOccurs="0" type="int" /> <element name="QuantityPerUnit" minOccurs="0" type="string" /> <element name="UnitPrice" msdata:DataType="System.Currency" minOccurs="0" type="string" /> <element name="UnitsInStock" minOccurs="0" type="short" /> <element name="UnitsOnOrder" minOccurs="0" type="short" /> <element name="ReorderLevel" minOccurs="0" type="short" /> <element name="Discontinued" type="boolean" /> </complexType> <unique name="Constraint1" msdata:PrimaryKey="True"> <selector>.</selector> <field>ProductID</field> </unique> </element> </schema> <DocumentElement> <usp_ProdList> <ProductID>1</ProductID> <ProductName>Chai</ProductName> <SupplierID>1</SupplierID> <CategoryID>1</CategoryID> <QuantityPerUnit>10 boxes x 20 bags</QuantityPerUnit> <UnitPrice>18</UnitPrice> <UnitsInStock>39</UnitsInStock> <UnitsOnOrder>0</UnitsOnOrder> <ReorderLevel>10</ReorderLevel> <Discontinued>False</Discontinued> </usp_ProdList> ... </DocumentElement> </DataSet>