.NET Web Services Made Easy
Interested in .NET? Don’t miss SitePoint’s .NET Feature Guide — it’s an excellent resource!
No doubt you’ve heard of Web Services, even if you’re an ASP, PHP, Java, .NET or XML developer. If you haven’t, or don’t really know what they are, have a look at Kevin Yank’s “Web Services Demystified”.
Web Services are neither a new concept, nor a Microsoft creation. The idea has been around for a long time — Netscape touched on the concept with their IIOP (Internet Inter-ORB Protocol) — and was discussed in an article by the cofounder of Netscape, Marc Andreessen, at the end of 1996.
In this article we’ll explore how you can build and utilise your own Web Service.
Prerequisites
I’m assuming that you have a basic knowledge of .NET, Web forms, and accessing data. I’ll use an MS SQL Server database for this project, but you can also use Microsoft MSDE, which comes with the .NET Framework (if you need help finding this, have a look at the SitePoint Forums), or edit the code to work with an Access database through the OLEDB Namespace.
Usable Protocols
Because Web Services are designed to be as accessible as possible, one of the primary and most important aspects of the architecture is to exchange data in a common format. You can use three protocols to transfer data in a .NET Web Service: Http-Get, Http-Post and SOAP (Simple Object Access Protocol). Let’s go over these protocols now. Because Http-Get and Http-Post are essentially the same thing, we’ll cover them together.
The Http-Get and Http-Post Protocols
Http-Get uses name/value pairs to pass data to and from a Web Service, and, as an HTTP-based protocol, it’s widely accepted. You’ve probably worked with before if you’ve ever used the Request.QueryString()
in ASP or ASP.NET. The Http-Get protocol appends a UUencoded string to the end of a URL, which commonly appears like this:
www.e4ums.com/search.aspx?searchtext=search%
20for%20this&from=index.aspx
Look familiar? Thought so.
Http-Post is also an HTTP-based protocol that uses name/value pairs, but instead of appending the URL, these pairs are passed in request header. If you’ve every used Request.Form()
, then you’ve worked with Http-Post data. The actual HTTP header for an Http-Post request looks like this:
POST search.aspx HTTP1.1
Host: http://www.e4ums.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
searchtext=search%20for%20this&from=index.aspx
SOAP (Simple Object Access Protocol)
This lightweight data exchange protocol uses XML structure to describe objects and their properties and methods. Using HTTP and other Internet technologies, SOAP has seamlessly been integrated into .NET Web Services. Although only designed for one way transmission, SOAP messages can be combined to implement systems like request/response.
A SOAP message might look something like this:
POST search.aspx HTTP/1.1
Host: http://www.e4ums.com
Content-Type: text/xml; charset="utf-8"
Content-Length: nnn
SOAPAction: http://www.e4ums.com/ws
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi=http://www.w3c.org/2001/XMLSchema-instance"
xmlns:xsd=http://www.w3c.org/2001/XMLSchema
xmlns:soap=http://schemas.xmlsoap.org/soap/envelope>
<soap:Body>
<tipOfDay xmlns=http://www.e4ums.com>
<date>05/12/2002</date>
</ tipOfDay >
</soap:Body>
</soap:Envelope>
The SOAP that is returned would look like this:
HTTP/1.1 200 OK
Content-Type: text/xml charset="utf-8"
Content-Length: nnnnn
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi=http://www.w3c.org/2001/XMLSchema-instance"
xmlns:xsd=http://www.w3c.org/2001/XMLSchema
xmlns:soap=http://schemas.xmlsoap.org/soap/envelope>
<soap:Body>
<tipOfDay xmlns=http://www.e4ums.com>
<returnTip>Never stick a light build in your back
pocket</returnTip>
</tipOfDay>
</soap:Body>
</soap:Envelope>
Data Types
Like the functions you create for your site, Web Services accept and return a variety of data types:
- String
- Int
- Boolean
- Byte
- Double
- Datatype
- Enumeration
- Float
- Long
- Short
- Unsignedbyte
- Unsignedint
- Unsignedlong
- Unsignedshort
And, as with normal classes and methods, you decide what data types can be accepted. However, the types that you can accept will be heavily influenced by what protocol is used to consume the Service. SOAP is the most extensible because it’s an XML-based protocol, but because of this it also uses the most bandwidth. Http-Get and Http-Post on the other hand, being name/value pairs, use less bandwidth, but are also more limited.
Our First Simple Web Service
Let’s create a Web Service! We’re going to build a simple script that returns a string — something nice and simple to start with. After that, we’ll move onto bigger and brighter things!
Creating the Web Method
If you’ve worked with .NET before, and you’ve created a custom class, then you’re not that far from creating a Web Method! There isn’t that much difference between the two really: exposed public methods are available through the Web Service, much like the public methods of a class are available to the rest of the application.
Ok, so open your favorite text editor or IDE, and save a blank document as webservice1.asmx. No, I didn’t mistype the extension. .NET Web Services files are saved as .asmx.
Ok, so you’ve waited until now to get your hands on some code, so here you are:
<%@ WebService Language="VB" Class="SitePoint" %>
Imports System.Web.Services
<WebService(NameSpace:="https://www.sitepoint.com/")>
Public Class SitePoint
<WebMethod(Description:="It say hello!!")> Public
Function returnHello() As String
Return "HELLO TO THE BIG WIDE WORLD!"
End Function
End Class
Look a little familiar? Thought so! Let’s go over it.
<%@ WebService Language="VB" Class="SitePoint" %>
The first line looks a little like the normal Page directive, but instead of Page, it’s a WebService directive, which tells the .NET Framework that this class is to be exposed as a Web Service.
Imports System.Web.Services
Next we import the System.Web.Services Namespace so we can access .NET Web Services classes.
<WebService(NameSpace="https://www.sitepoint.com/")>
Public Class SitePoint
This line provides an XML Namespace for the Web Service. Now, if we’d left this line out (it’s optional) it would have bee assigned the Namespace<http://tempuri.org>
. It’s generally a good idea to supply your own Namespace, as this helps to distinguish yours from other Web Services.
<WebMethod(Description:="It say hello!!")>
Public Function returnHello() As String
To create a Web Service, you have to expose part of it. You can do this by using the WebMethod attribute, and by declaring the class and methods as public. In the above line, we declare the returnHello
function as a WebMethod and public, which means that it will be available as a service.
Return "HELLO TO THE BIG WIDE WORLD!"
End Function
End Class
With these lines, we return a simple string, and close the function and class. Now, navigate to the webService1.asmx file and you’ll see that the .NET Framework has automatically rendered it.
Cool, eh? As you can see, the page displays the name of the Web Service at the top of the page and then lists the methods that have been made available, using the WebMethod
attribute. Now click the name of a WebMethod, in this case the returnHello method, and a page describing the Web Service will appear.
You’ll see the method name, along with the description we set in the code. Below this you’ll find a header called Test and a button with Invoke written on it. Don’t hit it yet, we’ll come back to this in a moment!
Below this, you’ll see some sample SOAP, Http-Get and Http-Post requests and responses. They should look a little familiar!
Now hit the Invoke button! A window should pop up that looks something like this:
This is how our exposed service will appear.
Ok, now back to the first page. There’s something we never covered, anyone notice what it was?
This link will open the Service Description, funnily enough, which is called the WSDL document. If you read Kev’s article, congratulations – you know what I’m talking about! If not, shame on you!
Basically, the WSDL (Web Service Description Language) defines the Web Service and how it will be consumed. There are sections that detail how to interact with it using SOAP, Http-Get and Http-Post. Not bad, eh? As you can see, the .NET Framework makes creating Web Services easier than cooking toast!
Ok, we’ve built a simple Web Service that returned a string. Let’s move onto a Web Services that you can actually interact with!
Build an Interactive Web Service
So, here we go then. This time, we’re going to create a fully functional Web Service. But what will it do? Well, we’re going to create a Web Service that exposes two WebMethods, randomQuote()
and addQuote()
. Our Web Service will be a simple quote system, offering users the ability to have a section on their site that will display a random quote and provide users with the ability to add new quotes.
Before we get started, create a new folder in your Web root (usually c:intetpubwwwroot) called quoteWS, and turn it into a new virtual directory.
The Database
We’re going to create a simple database to hold the quotes, and design it in a way that will allow you to easily change it to an Access database. Create a new database and call it quoteDatabase. Here’s what the schema looks like:
Once you’ve made the table, save it as tblQuotes.
Now we’ve made the table, let’s look at our first WebMethod, randomQuote()
randomQuote() Web Method
Before we start our start our WebMethods we have to set up the class we want to expose:
<%@ WebService Language="VB" Class="Quote" %>
Imports System.Web.Services
Imports System
Imports System.Data
Imports System.Data.SqlClient
<WebService(Namespace:="https://www.sitepoint.com/Quote.")> _
Public Class Quote
' Private string to hold the connection details
Private strConnection As String
= "server=localhost;database=quoteDatabase;uid=sa;pwd=;"
End Class
Save the file as quote.asmx. Everything you see should be familiar; first we have the @WebService
directive, and then we import the Namespaces for the classes and methods we’re going to use. Next we declare our XML namespace, and the class we’re going to expose. The only line we have inside the class is a private string that holds our database details.
With the basic bones our service laid down, let’s look at our first WebMethod.
<WebMethod(Description:="Returns a random quote
on each request in the form of a DataSet")> _
Public Function randomQuote() As DataSet
Dim objDataAdapter As New SQLDataAdapter '
DataAdapter that will get the data from the
Dim objConnection As New SQLConnection(strConnection) '
Connection object that will allow the DataAdpater to
connect to the
Dim DS As New DataSet() ' Will store the data
Dim returnDS As New DataSet() ' Will be the DataSet
that is returned
Dim quoteID As Integer ' Will hold the ID number
of the random quote
objDataAdapter = New SQLDataAdapter("SELECT * FROM
tblQuotes", objConnection)
objDataAdapter.Fill(DS, "quoteTable")
quoteID = DS.Tables("quoteTable").Rows.Count * Rnd()
Dim tmpDataTable As New DataTable("returnRow")
tmpDataTable = DS.Tables("quoteTable").Clone
tmpDataTable.ImportRow(DS.Tables("quoteTable").Rows(quoteID))
returnDS.Tables.Add(tmpDataTable)
Return returnDS
End Function
Let’s quickly review the code. When we declare the WebMethod, we supply a description, the function name, and what we’re going to return.
<WebMethod(Description:="Returns a random quote
on each request in the form of a DataSet")> _
Public Function randomQuote() As DataSet
The next few lines declare the objects and variables we’re going to use:
Dim objDataAdapter As New SQLDataAdapter '
DataAdapter that will get the data from the
Dim objConnection As New SQLConnection(strConnection) '
Connection object that will allow the DataAdpater to
connect to the database
Dim DS As New DataSet() ' Will store the data
Dim returnDS As New DataSet() ' Will be the DataSet
that is returned
Dim quoteID As Integer ' Will hold the ID number
of the random quote
The next lines return the data from the database:
objDataAdapter = New SQLDataAdapter("SELECT * FROM
tblQuotes", objConnection)
objDataAdapter.Fill(DS, "quoteTable")
Now that we have a DataSet containing our quotes, we have to select one of them randomly. For this we use the row numbers from the DataSet and the rnd()
function. There are better, more reliable ways to do this, but for speed and ease, we’re going with this option.
quoteID = DS.Tables("quoteTable").Rows.Count * Rnd()
We then create a DataTable to hold the row we want to return. We clone the table that’s holding the current quotes, and then copy the row over.
Dim tmpDataTable As New DataTable("returnRow")
tmpDataTable = DS.Tables("quoteTable").Clone
tmpDataTable.ImportRow(DS.Tables("quoteTable").Rows(quoteID))
Because we can’t return the DataTable through the Web Service, we have to insert it into a DataSet.
returnDS.Tables.Add(tmpDataTable)
Then finally we return the DataSet.
Return returnDS
With that, we’ve finished our WebMethod that returns our random quote! Why not surf along and test it out?
addQuote() WebMethod
Now we can return the quotes, we’re going to build the functionality to allow someone to add a quote:
<WebMethod(Description:="Allows anyone
to add a quote to the database" _
& "<br />Takes 3 inputs" _
& "<br /><strong>1. quoteConent</strong> - Content
of the quote" _
& "<br /><strong>2. submittedBy</strong> - Name of the
person who submitted the quote (50 chars)" _
& "<br /><strong>3. webSite</strong> - Web Site of the
person who submitted the quote (50 chars)" _
& "<br /><br />Returns true or false depending if
the quote was successfully added")> _
Public Function addQuote(quoteContent As String,
submittedBy As String, webSite As String) As Boolean
Dim objConnection As New SQLConnection(strConnection)
Dim objCmd As SQLCommand
Dim objParam As SQLParameter
Try
objCmd = New SQLCommand("INSERT INTO tblQuotes
(displayContent, submittedBy, webSite) VALUES
(@displayContent, @submittedBy, @webSite)", objConnection)
objParam = objCmd.Parameters.Add(New SQLParameter
("@displayContent", SQLDBType.Text))
objParam.Value = quoteContent
objParam = objCmd.Parameters.Add(New SQLParameter
("@submittedBy", SQLDBType.VarChar, 50))
objParam.Value = submittedBy
objParam = objCmd.Parameters.Add(New SQLParameter
("@webSite", SQLDBType.VarChar, 50))
objParam.Value = webSite
objCmd.Connection.Open()
objCmd.ExecuteNonQuery()
objCmd.Connection.Close
Return True
Catch ex As Exception
Return False
End Try
End Function
If you’ve ever used ASP.NET, the above code should be very familiar (so should everything else really!). The first thing we do, as you already know, is declare the WebMethod. But this time you’ll notice that the description is longer. As you can see, it supports HTML, which means that you can supply a detailed description with your Web Service! We take three inputs, quoteContent, submittedBy and website) and return a Boolean (True or False).
<WebMethod(Description:="Allows anyone to
add a quote to the database" _
& "<br />Takes 3 inputs" _
& "<br /><strong>1. quoteConent</strong> - Content of the quote" _
& "<br /><strong>2. submittedBy</strong> -
Name of the person who submitted the quote (50 chars)" _
& "<br /><strong>3. webSite</strong> - Web Site
of the person who submitted the quote (50 chars)" _
& "<br /><br />Returns true or false depending if
the quote was successfully added")> _
Public Function addQuote(quoteContent As String,
submittedBy As String, webSite As String) As Boolean
Next, we declare all the objects we’re going to use:
Dim objConnection As New SQLConnection(strConnection)
Dim objCmd As SQLCommand
Dim objParam As SQLParameter
Then we insert the data supplied into the database using a Try...Catch...Finally
block. As you can see, we do not validate of the data, which means the client would have to.
Try
objCmd = New SQLCommand("INSERT INTO tblQuotes
(displayContent, submittedBy, webSite) VALUES
(@displayContent, @submittedBy, @webSite)", objConnection)
objParam = objCmd.Parameters.Add(New SQLParameter
("@displayContent", SQLDBType.Text))
objParam.Value = quoteContent
objParam = objCmd.Parameters.Add(New SQLParameter
("@submittedBy", SQLDBType.VarChar, 50))
objParam.Value = submittedBy
objParam = objCmd.Parameters.Add(New SQLParameter("@webSite",
SQLDBType.VarChar, 50))
objParam.Value = webSite
objCmd.Connection.Open()
objCmd.ExecuteNonQuery()
objCmd.Connection.Close
Return True
Catch ex As Exception
Return False
End Try
It’s as simple as that! If we surf along to our quote.asmx file now, we’ll see something like this:
Why not try the Web Services we created? They’re both fully functional!
Consuming Our Web Service
Now we’ve created a simple Web Service, let’s look at consuming it.
For someone to use a Web Service, they have to make a proxy client, which is then allowed access to all the exposed WebMethods. This can be coded by hand, but the .NET Framework includes a tool that will do this for you. We’ll look at that shortly; the first thing we have to do is get ready to consume the Web Service.
The first thing we have to do is set up a new folder for the consumer site, so in your Web root (usually c:inetpubwwwroot) create a folder called consumerSite. Now, enter that folder and make a folder called bin.
Now we’ll look at creating our proxy class.
WSDL.exe
This is a command-line utility (more information on the command-line at WebmasterBase.com) that’s used to generate proxy classes using any of the useable protocols. WSDL.exe assesses the Web Service and generates a proxy class in VB.NET, C# or Jscript, which then compiles the class into a DLL that’s available to the consumer site.
Let’s create our proxy class now. Open the command prompt and type:
wsdl http://localhost/quoteWS/quote.asmx?wsdl /l:vb /n:Quote
/nologo /out:C:inetpubwwwrootconsumerSitebinquote_proxy.vb
If you browse to the bin directory, you’ll find the file quote_proxy.vb! Cool, eh? You can find out more about the WSDL tool by entering this:
wsdl /?
Now we need to compile it into a DLL, so the site can use it:
vbc /t:library /out:C:inetpubwwwrootconsumerSitebinquote.dll
/r:System.Web.Services.dll, System.dll, system.xml.dll, system.data.dll
c:inetpubwwwrootconsumerSitebinquote_proxy.vd
Consuming The randomQuote() WebMethod
Ok, now that we’ve created our proxy class for the Web Service, we can look at actually consuming it!
The first WebMethod we’re going to consume is the randomQuote()
. Open your text editor and enter this code:
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="Quote" %>
<script language="VB" runat="server">
Sub Page_Load(ByVal obj As Object, ByVal e As EventArgs)
If ( NOT isPostBack ) Then
generateQuote(obj, e)
End If
End Sub
Sub generateQuote(ByVal obj As Object, ByVal e As EventArgs)
Dim randomQuote As New quote.quote()
Dim getQuote As DataSet = randomQuote.randomQuote()
returnQuote.DataSource = getQuote
returnQuote.DataBind()
End Sub
Function checkWebSite(byVal submittedBy As String,
byVal website As String) As String
Dim returnString As String
If ( Regex.isMatch(website, "b(www|http)S+b") ) Then
returnString = Regex.Replace(website,
"b(www|http)S+b", "<a href=""$0"" target=""_blank"">"
& submittedBy & "</a>")
Else
returnString = submittedBy
End If
Return returnString
End Function
</script>
<html>
<head>
<title>Quote Web Service!</title>
<meta http-equiv="Content-Type" content=
"text/html; charset=iso-8859-1">
<style>
.body { font-family: Verdana, Arial, Helvetica; font-size: 11; }
</style>
</head>
<body>
<form name="form1" runat="server">
<ASP:Repeater ID="returnQuote" runat="server">
<itemTemplate>
<table width="500" style="border:
1 solid #8080C0" class="body">
<tr>
<td>Quote Number: <%# DataBinder.Eval
(Container.DataItem, "quoteID") %></td>
</tr>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem,
"displayContent") %>
</td>
</tr>
<tr>
<td>
<%# checkWebSite(DataBinder.Eval
(Container.DataItem, "submittedBy"), DataBinder.Eval
(Container.DataItem, "website")) %>
</td>
</tr>
</table>
</itemTemplate>
</ASP:Repeater>
<br>
<ASP:LinkButton id="newQuoteButton" runat="server"
OnClick="generateQuote" Text="Get Another!" CssClass="body" />
</form>
</body>
</html>
Save this file as default.asopx, browse along to the consumerSite URL, and you should see something like this:
How cool is that! Let’s go over the code.
In the first few lines we have our page directive and the Namespaces we want to import. As you can see, we are importing our Web Service proxy. This allows use easy access to the methods.
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="Quote" %>
Next we have our Page_Load
function, which contains some code to kick up the generateQuote()
function, but only if the page has not been posted back.
Sub Page_Load(ByVal obj As Object, ByVal e As EventArgs)
If ( NOT isPostBack ) Then
generateQuote(obj, e)
End If
End Sub
We have our generateQuote()
function now. This creates an instance of the Web Service, and creates a new DataSet using the returned data. Then we bind it to a repeater class.
Sub generateQuote(ByVal obj As Object, ByVal e As EventArgs)
Dim randomQuote As New quote.quote()
Dim getQuote As DataSet = randomQuote.randomQuote()
returnQuote.DataSource = getQuote
returnQuote.DataBind()
End Sub
Let’s jump to the Repeater Web Control. We didn’t have to use this Web Control, but for simplicity, we’ll stick with it.
Inside the Control, we have a table that holds out returned quote — quite simple really. You might notice, though, that one of the lines is slightly different.
<ASP:Repeater ID="returnQuote" runat="server">
<itemTemplate>
<table width="500" style="border: 1 solid #8080C0" class="body">
<tr>
<td>Quote Number: <%# DataBinder.Eval
(Container.DataItem, "quoteID") %></td>
</tr>
<tr>
<td>
<%# DataBinder.Eval(Container.DataItem,
"displayContent") %>
</td>
</tr>
<tr>
<td>
<%# checkWebSite(DataBinder.Eval
(Container.DataItem, "submittedBy"), DataBinder.Eval
(Container.DataItem, "website")) %>
</td>
</tr>
</table>
</itemTemplate>
</ASP:Repeater>
The line in bold is a little different to the rest. Instead of sending the data straight to the browser, it sends it to a function called checkWebSite()
. This function checks to see if the website is a link. If it is, the function returns a link using the website and submittedBy value, and if it’s not, it simply returns the submittedBy
value.
Function checkWebSite(byVal submittedBy
As String, byVal website As String) As String
Dim returnString As String
If ( Regex.isMatch(website, "b(www|http)S+b") ) Then
returnString = Regex.Replace(website,
"b(www|http)S+b", "<a href=""$0"" target=""_blank"">"
& submittedBy & "</a>")
Else
returnString = submittedBy
End If
Return returnString
End Function
And that’s how you consume the randomQuote()
WebMethod! Nice and easy! Now, let’s move onto the addQuote()
WebMethod.
Consuming The addQuote() WebMethod
The addQuote()
WebMethod allows the user to add quotes to the database. If you remember, the WebMethod didn’t validate the data, so we’ll include some simple validation.
Open a new document in your text editor and add the following:
<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="Quote" %>
<script runat="server">
Sub addQuote(byVal obj As Object, byVal e As EventArgs)
If ( page.isValid) Then
Dim randomQuote As New quote.quote()
Dim addOK As Boolean = randomQuote.AddQuote
(quoteContentTxt.Text, submittedByTxt.Text, websiteTxt.Text)
If ( addOK ) Then
result.Text = "Quote was successfully added!"
quoteContentTxt.Text = ""
submittedByTxt.Text = ""
websiteTxt.Text = ""
Else
result.Text = "Quote was not added!"
End If
End If
End Sub
</script>
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html;
charset=iso-8859-1" />
<style>
.body {
FONT-SIZE: 11px; FONT-FAMILY: Verdana, Arial, Helvetica
}
</style>
</head>
<body>
<form name="addQuoteForm" runat="server">
<ASP:Label id="result" CssClass="body" Font-Bold="true"
runat="server"></ASP:Label>
<table style="border: 1 solid #8080C0" class="body">
<tr>
<td valign="top">Quote Content:</td>
<td width="10"> </td>
<td>
<asp:textbox id="quoteContentTxt" runat="server" TextMode=
"MultiLine" Width="290px" Height="121px">
</asp:textbox>
<asp:RequiredFieldValidator id="quoteContentValidator"
runat="server" ControlToValidate=
"quoteContentTxt" Display="Dynamic"
ErrorMessage="<br />You must supply a
quote!"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td valign="top">Your Name:</td>
<td> </td>
<td>
<asp:textbox id="submittedByTxt" runat="server"
TextMode="SingleLine"></asp:textbox>
<asp:RequiredFieldValidator id="submittedByValidator"
runat="server" ControlToValidate="submittedByTxt"
Display="Dynamic" ErrorMessage="<br />
You must supply your name!"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td> Web Site:</td>
<td> </td>
<td>
<asp:textbox id="websiteTxt" runat="server"
TextMode="SingleLine"></asp:textbox>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>
<asp:button id="addQuoteButton" onclick="addQuote"
runat="server" Text="Add Quote!"></asp:button>
</td>
</tr>
</table>
</form>
</body>
</html>
Now save it as addQuote.aspx, and surf to it. You should see this:
Try it! Cool, eh? Let’s go over the code.
The first few lines were the exact same as the previous page: they contained our page directive and imported the namespaces.
<%@ Page Language="VB" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="Quote" %>
We’ll skip the actual code right now and jump to the form. As you can see, it’s a standard Web Form, using 3 textboxes, 1 button and 2 validators. The validators only check the quoteContentTxt
and submttedByTxt
to make sure they have some content.
<form name="addQuoteForm" runat="server">
<ASP:Label id="result" CssClass="body" Font-Bold="true"
runat="server"></ASP:Label>
<table style="border: 1 solid #8080C0" class="body">
<tr>
<td valign="top">Quote Content:</td>
<td width="10"> </td>
<td>
<asp:textbox id="quoteContentTxt" runat="server"
TextMode="MultiLine" Width="290px"
Height="121px"></asp:textbox>
<asp:RequiredFieldValidator id="quoteContentValidator"
runat="server" ControlToValidate="quoteContentTxt"
Display="Dynamic" ErrorMessage="<br />You must
supply a quote!"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td valign="top">Your Name:</td>
<td> </td>
<td>
<asp:textbox id="submittedByTxt" runat="server"
TextMode="SingleLine"></asp:textbox>
<asp:RequiredFieldValidator id="submittedByValidator"
runat="server" ControlToValidate="submittedByTxt"
Display="Dynamic" ErrorMessage="<br />You must
supply your name!"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td> Web Site:</td>
<td> </td>
<td>
<asp:textbox id="websiteTxt" runat="server"
TextMode="SingleLine"></asp:textbox>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>
<asp:button id="addQuoteButton"
onclick="addQuote" runat="server"
Text="Add Quote!"></asp:button>
</td>
</tr>
</table>
</form>
When the submit button is clicked, the addQuote()
function is fired. It first checks to make sure that the page is valid, the creates an instance of the Quote Web Service. Then it creates a new Boolean that will hold the result of the addQuote()
call. If it’s retuned true, then the quote was added, and if it’s retuned false, then the quote wasn’t added.
Sub addQuote(byVal obj As Object, byVal e As EventArgs)
If ( page.isValid) Then
Dim randomQuote As New quote.quote()
Dim addOK As Boolean = randomQuote.AddQuote
(quoteContentTxt.Text, submittedByTxt.Text, websiteTxt.Text)
If ( addOK ) Then
result.Text = "Quote was successfully added!"
quoteContentTxt.Text = ""
submittedByTxt.Text = ""
websiteTxt.Text = ""
Else
result.Text = "Quote was not added!"
End If
End If
End Sub
Finishing Up
Congratulations, you’ve just made you’re first Web Service! While what we covered was very simple, you can always add more functionality to this base, such as returning the number of quotes, or building in the ability to edit or delete quotes. The only limit to what you can do is how much you can be bothered programming!
Web Services are a new and exciting way to open up Websites to the public or your customers! There is no real limit to what you can do with Web Services, and with .NET’s platform independence, you can use Web Services that have been generated in any language!
The example we covered was a very simple one, but it should show you want is possible! There are a myriad of resources for Web Services, the most obvious one being the .NET SDK, and Microsoft’s newly released Web Enhancements Package for .NET.
This article is part of SitePoint’s .NET Feature Guide — an excellent resource for aspiring and experienced .NET developers. Don’t miss it!