There are walkthroughs in the VS help for building a trivial Web Service and accessing it. The building one is Walkthrough: Creating an XML Web Service Using Visual Basic or Visual C#.
The instructions are clear, and if you follow them exactly, things will probably work -- if you have Visual Studio and the server software included. It turns out that's not entirely likely. The first thing that bit me was in creating the project. VS wouldn't create the project. After digging through the help a little bit, I found out that the problem was that I didn't have IIS installed on my laptop. So I dug out the server CDs (thank you Microsoft Press!) and installed IIS. That allowed me to set up the project.
After following the rest of the instructions, I was ready to run the Web Service (a simple Fahrenheit to Centigrade conversion). When Internet Explorer encounters a Web Service (a .asmx file), it automatically interrogates the service and gins up a form that can be used to inspect and drive the service. Very cool. Except that it didn't work. Instead, it kept saying that it couldn't find the service. So back to digging through the help looking for ideas. I finally found one: if you install IIS after Visual Studio, something isn't set up right to let VS run your service. There's a fixer that you have to run on one of the CDs that come with VS. So I ran that after only a few tries typing in the million or so characters required to run the fixer from the setup.
Then, it worked just fine. The form comes up looking like this:
And if you click on the ConvertTemperature button, you get this:
(I typed the 212 into the form.) And if you click the Convert button, you get a new window that looks like this:
So cool, the web service works on my local machine.
Supposedly all you have to do to deploy a web service is to copy the files to the deployment location. So I did that, and tried to open the file on XProgramming.com. Instead of bringing up the web forms above, it acted like it was trying to download the file. That started an email exchange with my ISP, culminating in a phone call from him last night. (Don't you wish that your ISP's support was so good that they called you when there was a problem?) We had a little discussion about what was happening on my machine, and on his. Finally he decided that my new web services directory needed to be shown as one with "execute" access rather than just downloading. (Or something like that. I'll write him a note and get the exact words.) Anyway, he set that bit and the Web Service worked on XProgramming just as it does on my local machine. Try it.
There's another walkthrough in Visual Studio, for accessing a Web Service: Walkthrough: Accessing an XML Web Service Using Visual Basic or Visual C#. It, too, is pretty clear, with one exception so far.
The walkthrough tells you to set up a "Web Reference" for the project, pointing to the Web Service you want to access. No problem, you just type in its local URI. That's a little tricky, because the window you have to type it into doesn't let you browse for it (though the help suggests that it does). But just typing in "http://localhost/TempConvert1/Service1.asmx" works just fine. Then the help tells you to "Rename the Web reference to ConvertSvc, which is the namespace you will use for accessing this Web reference. For more information, see Managing Project Web References." Well, what it means by that is to rename the top level of the reference, which will in this case say "localhost", to "ConvertSvc". This allows you to set up the code in a ButtonClick to look like this:
private void Button1_Click(object sender, System.EventArgs e) {
ConvertSvc.Service1 ws = new ConvertSvc.Service1();
double dFahrenheit = Convert.ToDouble(TextBox1.Text);
double dCelsius = ws.ConvertTemperature(dFahrenheit);
Label1.Text = dCelsius.ToString();
}
If you don't do that rename, you would need to say localhost.Service1 rather than ConvertSvc.Service1. I found that out by typing all possible combinations of characters to get the above code to compile, until I found that localhost.Service1 worked, then by guessing that they wanted me to rename the top level of the web reference (which is obvious, perhaps, in retrospect, but I was there and I can tell you it wasn't obvious in the moment).
The complete accessing program is pretty short and sweet. It looks like this:
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace TempConvertClient1
{
///
/// Summary description for WebForm1.
///
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Label Label1;
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Button Button1;
private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN: This call is required by the ASP.NET Web Form Designer.
//
InitializeComponent();
base.OnInit(e);
}
///
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
private void InitializeComponent()
{
this.Button1.Click += new System.EventHandler(this.Button1_Click);
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
private void Button1_Click(object sender, System.EventArgs e) {
ConvertSvc.Service1 ws = new ConvertSvc.Service1();
double dFahrenheit = Convert.ToDouble(TextBox1.Text);
double dCelsius = ws.ConvertTemperature(dFahrenheit);
Label1.Text = dCelsius.ToString();
}
}
}
And here's the HTML for the form:
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="TempConvertClient1.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>WebForm1</title>
<meta content="Microsoft Visual Studio 7.0" name="GENERATOR">
<meta content="C#" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<asp:label id="Label1" style="Z-INDEX: 101; LEFT: 282px; POSITION: absolute; TOP: 156px" runat="server"></asp:label><asp:textbox id="TextBox1" style="Z-INDEX: 102; LEFT: 198px; POSITION: absolute; TOP: 106px" runat="server"></asp:textbox><asp:button id="Button1" style="Z-INDEX: 103; LEFT: 195px; POSITION: absolute; TOP: 152px" runat="server" Text="Convert"></asp:button></form>
</body>
</HTML>
In use, the form looks like this:
At this writing, I haven't figured out what has to be done to connect this form to my web site instead of my local site. Clearly adding the remote web reference would do it, but that would be tricky if I wasn't on line at the time. (On the other hand, in general, the compiler can't be sure what the service can do unless it can see it.) Anyway, when I make that work, I'll expand this report a little bit.
The main lesson, as always is that it would be good to have a pair who already knows how to do things. That wasn't possible for me this time. Additionally:
I'm really glad I decided to do this walkthrough in its simplest possible form, following the instructions as exactly as possible. If I had changed anything at all, I'd have been in the weeds more than I was. This way, I could be pretty sure that the app should work and that if it didn't, it was in my configuration, not in my code.
I needed to have IIS installed. I bet I'm going to need SQL Server later. I'll keep that in mind for when I get to doing that sort of application in this series.
I'm not sure how I could have found the need for the VS fix any sooner. However, it is referenced several times on microsoft.public.framework.aspnet.webservices. If you happen to be looking there, which if you're doing Web Services, you'd be wise to do: there are some smart people there.
My ISP is very helpful, though not experienced specifically with .NET. I'm his first .NET client. But he's smart and thoughtful (and can you even believe that he called me to help out?). As a beginner, I'll take all the help I can get.
Though I didn't get any help on this particular exercise from the XP community, they've certainly been chipping in with ideas and links on this series so far. It's almost as good as having someone come and pair with me. Special thanks to all those who have given assistance!