Voice Networking Applications
Prof. Kimmel
Lecture #11
Copyright 2002 Zebadiah Kimmel, All Rights Reserved
Introduction
In this final lecture, we will talk about using C# and ASP .NET to create VoiceXML
applications. This is a huge topic, so I'm just going to provide an overview here.
What is ASP?
ASP, Active Server Pages, is (was) a scripting environment made by Microsoft. It works
in conjunction with Microsoft's web server (IIS). It is a scripting environment because the
actual code is written in JavaScript or VBScript, then interpreted on-the-fly to produce
HTML (or XML) pages. ASP is a crummy development environment, and leads to
horrible coding practices, but it is easy to learn and use.
What is ASP .NET?
ASP .NET is very different than ASP, though you'd never guess it from the name; it is the
use of Microsoft's .NET framework to produce HTML (or XML) pages. ASP .NET is
vastly superior to ASP, and in my opinion substantially superior to Java Servlets/JSPs as
well. Its major downside (a big one) is that ASP .NET is confined solely to Windows.
ASP .NET allows you to use multiple languages—including C#, Visual Basic, and
C++—to produce compiled programs that output HTML (or XML) pages. We are going
to concentrate on C#, because it is very similar to Java. In fact, C# is basically Java with
all the cruddy stuff taken out and a lot of good stuff added in. It is a great language….if
only it were available for non-Microsoft platforms…
Some notes on C#
Like I just said, C# is basically the Java language with all the bad stuff taken out, and a
lot of good stuff put in. If you have ever gotten annoyed with Java's idiosyncracies, then
you will really like C#.
For example, providing get/set access methods in Java is a real pain. If I declare a
variable int x, then I also need to define int getX() and void setX(int x). On the other hand,
C# combines variable declarations and accessors like this:
public class MyClass
{
public int Year
{
get
{
return year;
}
set
{
year=value;
}
}
private int year;
}
After defining MyYearClass, I can elsewhere in the C# world do something like this:
MyClass mine = new MyClass();
mine.Year = 50;
// in Java, this would be mine.setYear(50)
System.Console.WriteLine(mine.Year);
// in Java, this would be System.out.println(mine.getYear())
The C# notation is much easier to use, and more intuitive.
C# includes features from C++, such as operator overloading, that are very useful. For
example, you could define DateTime and Duration classes, then overload the + operator,
to get behavior that looked like this:
DateTime dt1 = new DateTime("January 1, 1970");
duration du = new Duration("31 days");
DateTime dt2 = dt1 + du;
// dt2 is February 1, 1970
C# includes the amazingly useful foreach operator. For example, if parkingLot is an array
of Cars, then you can do the following:
foreach (Car c in parkingLot)
{
Console.WriteLine(c.ToString());
}
C# gives you the ability to use something called an indexer to treat a collection as it were
an array. For example, here is what using a C# Hashtable looks like:
Hashtable hash = new Hashtable();
hash.Add("myKey", "myValue");
Console.WriteLine(hash["myKey"]);
// prints out "myValue"
Notice in the third line that hash is being treated as if it were an array. hash["myKey"] is
just a convenient shorthand notation for the Java equivalent of hash.get("myKey"), but the
convenience really adds up over time.
C# includes classes for handling regular expressions. This is something that has been
missing from Java for years.
There is much, much more to C#. It is really a great language, and what Java should have
become. The O'Reilly book on C# by Jesse Liberty is good if you want to learn more.
The major downside, like I said before, is that if you want to use C#, then you'd better
resign yourself to running your code on Windows only.
Setting up ASP .NET on your computer
While C# runs on a variety of Windows platforms, you will only be able to run ASP
.NET on Win2K or WinXP-Pro. It won't work on Win95, Win98, WinNT, or WinXPHome. Thanks, Microsoft!
Setting up ASP.NET is non-trivial. I started writing instructions on how to do it, and the
instructions were taking up pages and pages and I was still nowhere near being done….so
I'm going to ask you to get a book on this subject if you are really interested. You have to
do the following:




Install IIS (Internet Information Services)
Configure IIS
Install Microsoft Data Access Components (if you are going to use any databases)
Install either the .NET Framework (which includes a whole buncha stuff
including ASP.NET) or just ASP.NET on its own
Chapter 1 of the book Beginning ASP.NET using C#, by Ullman et al, has detailed
instructions on how to get ASP.NET working on your machine. Remember you can only
run ASP.NET on Win2K or WinXP-Pro.
A Simple ASP .NET Page
This ASP.NET-generated VoiceXML page asks the user for a five-digit zip code, then
submits that zip code to another ASP.NET page. (ASP.NET files end in .aspx.) Because
of a bug in Nuance (described in Lecture 6), we can't have any whitespace between the
<% Response.ContentType> tag and the <?xml> tag.
<%@ Page language="c#"%>
<% Response.ContentType="text/xml"; %><?xml version="1.0"?>
<!DOCTYPE vxml PUBLIC '-//Nuance/DTD VoiceXML 1.0b//EN'
'http://voicexml.nuance.com/dtd/nuancevoicexml-1-2.dtd'>
<vxml version="1.0">
<form>
<field name="zipCode" type="digits" >
<prompt count="1" bargein="true"
Tell me a five digit zip
</prompt>
<prompt count="2" bargein="true"
I didn't understand you.
code.
</prompt>
<filled>
<prompt>
timeout="1s">
code.
timeout="1s">
Please tell me a five digit zip
OK.
</prompt>
<goto expr="'handle_zip_code.aspx?zipCode='+zipCode" />
</filled>
</field>
</form>
</vxml>
You can see that this ASP.NET page looks very similar to a JSP page. It begins with a
page directive, declaring the page language to be C#. Then the content type of the
response is set to XML. (In contrast to a JSP, the name of the Response object is
capitalized.) The rest of the file is regular VoiceXML code.
Just like a JSP, this page is compiled by .NET as needed. Unlike Java, the C# code is not
compiled to byte-code, but rather to an intermediate language called Microsoft
Intermediate Language (MSIL). From the point of view of the developer, though,
ASP.NET's as-needed compilation looks and feels like JSP's as-needed compilation.
A More Complicated ASP.NET Page
The following example is more complicated (and contrived), to show you more aspects of
making an ASP.NET page. This page could be called handle_zip_code.aspx, and could
be the page to receive the zip code HTTP query from the previous example.
<%@ Page language="c#" Debug="true" %>
<%@ Import Namespace="System" %>
<script language="c#" runat="server">
public int GetFirstDigit()
{
Application.Lock();
Application["zipCode"]=Request.QueryString["zipCode"];
Application.UnLock();
int FirstDigit =
Convert.ToInt32(Application["zipCode"].ToString().Substring(0, 1));
return FirstDigit;
}
</script>
<% Response.ContentType="text/xml"; %><?xml version="1.0"?>
<!DOCTYPE vxml PUBLIC '-//Nuance/DTD VoiceXML 1.0b//EN'
'http://voicexml.nuance.com/dtd/nuancevoicexml-1-2.dtd'>
<vxml version="1.0">
<form>
<block>
<prompt bargein="false">
The first digit of your zip code is
<%
int FirstDigit = GetFirstDigit();
Response.Write(FirstDigit);
%>
.
</prompt>
<%
if ( FirstDigit > 5 )
Response.Write("<goto next=\"page_one.aspx\" />");
else
Response.Write("<goto next=\"page_two.aspx\" />");
%>
</block>
</form>
</vxml>
There is a lot going on here. First, notice that the page directive sets Debug to be true.
This means that when an error occurs, the web page response from .NET will detail the
error. These .NET error reports are very useful and substantially more complete and
helpful than Tomcat's error results.
Next, you see an Import directive. As you would expect, this is just like Java's import
keyword, with .NET's namespace equivalent to Java's package. Importing the System
namespace gives us access to I/O libraries, such as string operations. There are many
namespaces, corresponding to the various Java packages, although the .NET namespaces
tend to be more complete and better organized than their Java equivalents—Microsoft
had the opportunity to learn from Sun's mistakes.
The <script> tag
Next, we have a <script> statement. In .NET, the <script> tag is quite an interesting
construct. If we just put in a <script> like this:
<script>
blah blah blah….
</script>
…Then the <script> tag will be sent unchanged down to the client browser. This is how
you send, for example, JavaScript code to a client web browser.
But if we put in a <script> like this:
<script language="c#" runat="server">
blah blah blah…
</script>
…Then the <script> tag is executed on the server, before any part of the page is sent
down to the client browser. The client browser never sees the content of the <script> tag.
This is a very clever construct, part of Microsoft's strategy of blending client and server
together. It is clever because of this fact: simply by setting an attribute of an XML tag, we
can control whether code is executed on a client or a server. This motif occurs
throughout ASP.NET.
Because a <script> tag that is run server-side is executed before the page gets sent to the
client browser, it should contain only declarative code (such as function declarations). In
the example above, we define a function called GetFirstDigit(), that extracts the first digit
of a received zip code. I included some extra code in GetFirstDigit() to demonstrate a
couple of things….
First, an "Application" objects exists that you can use to store information across the
entire web application. It can be locked and unlocked for purposes of synchronization. In
the example above, I extract the incoming zipCode parameter from the Request object,
then place that parameter into the Application object so that the zipCode can be accessed
anywhere in the web application. A Session object also exists, which does what you
would expect (stores information during a single client-server session). Although
analogues to ASP.NET's Application and Session exist in JSP, the .NET constructs are
easier and more intuitive to use.
Second, a "Convert" class exists that provides all sorts of conversion methods: for
example, Convert.ToBoolean(), Convert.ToDateTime(), Convert.ToDecimal(), and so on.
This is a lot easier than Java's solution to the conversion problem, which is to force the
developer to wander through tons of classes trying to find conversion methods.
Inline code blocks
I mentioned that server-side <script> tags execute before the page is sent back to the
browser. To execute code while the page is being sent downstream, you use an inline
code block, which looks just like its JSP equivalent:
<%
blah blah blah…
%>
As you look through the example above, you can see that the remainder of the page looks
very similar to a JSP page. The main difference is that the request and response Java
objects have turned into capitalized Request and Response .NET objects.
What exactly is an ASP.NET page?
Recall that every JSP is actually really a Java Servlet; Tomcat converts each JSP into a
Servlet as needed. Does ASP.NET do something similar with aspx files?
The answer (as you would expect) is yes. Each aspx file that you write is compiled on an
as-needed basis into a subclass of the System.Web.UI.Page class. Like Java's servlet
class, the .NET Page class has lots of methods that your ASP.NET pages inherit and can
therefore use at will. ASP.NET has the added advantage that its pages can inherit from
each other (as discussed further below).
I'm just going to mention one of the Page methods that you can use. The Page_Load
method (which is empty by default) is executed when the page loads. You can override
this method by declaring your own method of the same name in the <script> tag, like
this:
<script language="c#" runat="server">
void Page_Load()
{
blah blah blah…
}
</script>
Whatever you put inside that method will then automatically execute when the page
loads. This is useful for variable initialization. More sophisticated versions of Page_Load
that receive event information, and lots of other Page methods besides, are also available.
Another ASP.NET Example
The Request and Response objects also provide useful methods. Here is a little example:
<%@ Page language="c#" debug="true" %>
<%
Response.ContentType="text/html";
Response.AddHeader("Expires", "-1");
Response.AddHeader("Content-Expires", "-1");
Response.Redirect("http://www.mapquest.com/maps/map.adp?zipcode="
+ Application["zipCode"] );
%>
This redirects the client browser to a MapQuest page for the zipCode that is stored in the
Application object. (Remember that this is a contrived example; in real life it probably
wouldn't make much sense to store just a little zipCode in the Application object.)
ASP.NET Server Controls
Tomcat provides various XML tags (in the jsp: namespace) that you can embed in JSP
pages. You can also build your own JSP tags. Similarly, ASP.NET provides various
XML tags (in the asp: namespace) that you can embed in aspx pages, and you can build
your own ASP.NET tags.
Some of these ASP.NET tags are used to generate HTML controls, such as text boxes,
drop-down lists, and buttons. Because the HTML for these tags is generated dynamically
on the server-side, these tags are called HTML server controls. Here is an example:
<%@ Page language="c#" debug="true" %>
<% Response.ContentType="text/html"; %>
<script runat="server" language="c#">
void Page_Load()
{
Message.Text = "Hello World";
}
</script>
<html>
<body>
<asp:label id="Message" runat="server" />
</body>
</html>
The <asp:label> tag is handled before anything is sent to the client browser (because its
runat attribute is "server"). When ASP.NET sees this tag, it creates an internal object
called Message (of class System.Web.UI.WebControls.Label). The Page_Load() method,
which executes before anything is sent to the client browser, sets the textual content of
the label to "Hello World". The end result is that "Hello World" appears in the browser
window.
Notice that Message.Text="Hello World" in C# is equivalent to
Message.setText("Hello World") in Java, as per our previous discussion of get/set
accessors.
ASP.NET provides a variety of built-in server controls, including buttons, check boxes,
tables, calendars, images, and advertisement rotators.
Model-View-Controller in ASP.NET
You can see even in these little examples that we are faced with the same problem we
had with JSPs: the mixing of "pure code" (in this case, C#) with HTML/XML. Is there a
way to separate program logic (programmatic statements, including conditional branches)
from program presentation (the visual—or, in VoiceXML, audio—presentation of results
to an end user)?
The answer of course is yes, but ASP .NET handles this problem differently than does
JSP. ASP.NET solves the problem by providing two mechanisms:


So-called code-behind files, which are "pure C# code" files that are associated
with aspx files.
A wide variety of built-in server control tags, and the ability to build your own
tags/controls (so-called custom controls).
The model-view-controller equivalence between JSP and ASP.NET is therefore:
view: JSP file  aspx file
controller: Java Servlet  code-behind file
model: JavaBean  server/custom control (confusing name, unfortunately)
A full exploration of these topics is infeasible here, but here is a short example.
Code-Behind
A code-behind file is similar to a Java Servlet. Here is a code-behind file called
MyCodeBehind.cs. It defines an ASP.NET page that inherits from class Page.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
public class MyCodeBehind : Page
{
public TextBox user;
public Label message;
public void HandleButtonClick(object sender, EventArgs e)
{
message.Text = "Hello " + user.Text;
}
}
Here is an aspx page that uses the code-behind file. Let's call this file
MyCodeBehind.aspx.
<%@ Page Inherits="MyCodeBehind" Src="MyCodeBehind.cs" %>
<html>
<body>
<form action="MyCodeBehind.aspx" method="POST" runat="server">
<asp:TextBox id="user" runat="server" />
<asp:Label id="message" runat="server" />
<asp:Button text="Submit" OnClick="HandleButtonClick"
runat="server" />
</form>
</body>
</html>
This ASP.NET page displays a text entry box to enter a user name, and a Submit button.
When the user presses the Submit button, the page re-appears, but with added text that
says "Hello Bill" (or whatever the user name is).
<asp:TextBox>, <asp:Label>, and <asp:Button> are all server control tags that are built
into ASP.NET. By setting their runat attribute to "server", we make sure that those tags
are processed on the server-side by ASP.NET, instead of being passed down as-is to a
client browser (which probably wouldn't know what to do with them).
The page directive lets ASP.NET know that this aspx file is inherited from our custom
class (MyCodeBehind), and that it should watch out for any server controls that are
defined in the custom class, as opposed to the aspx file. In this example, the textbox and
label are defined in MyCodeBehind.cs. By marking the textbox and label using the id
attribute, we alert ASP.NET to this fact.
One nice thing about the way all of this works is that you can create ASP.NET pages that
are subclasses of other pages, which makes control of program flow easier to manage.
This is in distinction to JSP, where it is difficult/impossible (I admit that I don't know
how to do it) to create JSP pages that are subclasses of Java Servlets. Also, ASP.NET
automatically compiles a code-behind file for you, while Tomcat does not automatically
compile a servlet for you.
In the example above, you can clearly see that program logic is encapsulated in a C# .cs
file (Control), and program presentation is encapsulated in an ASP.NET .aspx file
(View). Again, this is analogous to the Java system of encapsulating program logic in a
Java .java file, and program presentation in a JSP .jsp file.
Encapsulating program data can be done via so-called custom controls. These controls,
which are (as you would expect) C# classes, are much more wide-ranging than
JavaBeans: for example, they can contain presentation information as well as pure data,
and the way you use get/set accessors is much more sophisticated than in Java. Because
they are somewhat complicated to describe, I'm not going to talk about them here.
Summary
This lecture was meant to give you an overview of what it is like to create VoiceXML (or
HTML) documents in C# using Microsoft's ASP.NET. In general, ASP.NET provides a
number of elegant and easy-to-use enhancements over Java Servlets/JSPs, and C# is (in
my opinion) clearly a superior language to Java. The price you pay for using C# and
ASP.NET, however, is that your code is under the control of one company and runs on
only one platform. You have to decide yourself whether the trade-off is worth it.