How It Works
The following section is devoted to the architecture of the system. We start with an explanation of common user controls and common script files. Then we'll go into detail on the Buy Stock feature, which provides a good encapsulation of many of the programming techniques used throughout the application. Finally, we'll review some of the coding conventions and practices we used as best-practice techniques for development.
Common Files: User Controls
Two ASP.NET user controls are included on almost every page in our application. Together they encapsulate much of the functionality of the site, and each deserves discussion. Implementing user controls, whether in a regular ASP.NET application or while using the ASP.NET Speech controls, can provide a consistent user experience while saving a great deal of code.
: The GlobalSpeechElements user control is used on every page of the application except for Goodbye.aspx and RepresentativeXfer.aspx, which do little more than read a prompt and transfer the user away. It contains the main stylesheet control that defines common properties for the speech controls used throughout the application, as well as global command controls and common script files that provide client-side functional components.
: The Speech SDK style control is a powerful way of defining global application settings and assigning globally scoped functionality. In the FMStocks sample we have four different styles:
: This style is applied to all command controls. Its one attribute sets the AcceptCommandThreshold
at .6, meaning that any command must be recognized with at least a 60 percent confidence rating to be accepted.
: This style is applied only to the six global styles contained in GlobalSpeechElements.aspx
. This style inherits the attributes of BaseCommandStyle and adds a dynamically set scope attribute. We want global commands to apply to all controls on any page they are included in, so we set the scope to be the parent page's ID at runtime.
<command scope='<%# GetParentPageID() %>'>
: This style is applied to all QA controls that accept user input (QA controls that do not accept user input are called "Statements" and use the StatementQA
style below). In addition to setting timeout and confidence thresholds, this style also defines the OnClientActive
event handler for all QA controls. HandleNoRecoAndSilence
is a JScript event handler that monitors a user's unsuccessful attempts to say a valid response and transfers the user to customer service after enough unsuccessful events. It is described in the section on Common Script files below.
: For QA controls that do not accept user input, we want to disable BargeIn
the act of interrupting a prompt before it ends with a responseand turn on PlayOnce
, which ensures the prompt is not repeated. Normal QA controls are activated when their semantic item is empty; since Statement QA controls have no semantic item, the control would be played over and over again if PlayOnce
was turned off.
: The global commands in GlobalSpeechElements
(described in the Navigation Design section) each have a command grammar file associated with them that define how the command is activated.
Commands fall into two categories: those that affect the current prompt (HelpCmd
), and those that trigger an event (RepresentativeCmd
). For the former, the prompt function looks for a particular "Type" value in its lastCommandOrException
parameter and creates an appropriate command. For the latter, the command's associated OnClientCommand
event handler is executed.
Common Script File Includes
is an ideal place to include references to all global script files. These files constitute all global client-side event handlers and prompt generation/formatting routines for the application. Since they are included in the control, individual pages can rely on their availability without explicitly including them.
<script type="text/jscript" src="routines.js"></script>
<script type="text/jscript" src="speech.js"></script>
<script type="text/jscript" src="debug.js"></script>
<script type="text/jscript" src="PromptGenerator.js"></script>
<script type="text/jscript" src="FMStocks7V.js"></script>
The SelectableNavigator user control is used on any page that needs a dynamically generated list of items from which the user may select. While the Navigator application control included in the Speech SDK can read a list of items, it does not allow the user to select one of the items in the list. The SingleItemChooser application control does allow the user to select an item, but it is unwieldy for large lists. The SelectableNavigator contains a Navigator application control, as well as a QA control and a Command control.
: The prompt of the InitialStatement QA is used to tell the user something about the list. Originally, we had this initial statement as part of what the navigator says for its first item. However, if the user mumbles, this initial statement and the first item are lost. Since we wanted to ensure the user heard the first item, we separated the initial statement from the first item. This way, even if the user mumbles during the initial statement, they will still hear the first item after the system recovers.
: The Navigator takes care of the tasks associated with reading and navigating through the list of items associated with the control.
: This command, scoped to TheNavigator, allows the user to select an item. The grammar for this command may be specified dynamically by setting the IsDynamic
property of the SelectableNavigator to true
(the default). The grammar always contains at least "select" and "that one" to select the current (most-recently read) item but if this flag is set, the grammar also contains the items found in the first field specified in the DataHeaderFields
property. Thus, if the user is on the first item and says the name of the fifth item, the fifth item is selected.
Because user controls have no designer support, all properties are set programmatically in the code-behind file. In addition, this means dragging the user control onto a page does not add additional speech mark-up to the page as does dragging one of the Speech SDK's controls, such as a QA, onto the page. This isn't normally a problem since you will usually want other speech controls on the page, such as a semantic map. However, something else you don't automatically get is a prompt function file to keep the prompt function for the SelectableNavigator. Again, this isn't normally a problem so long as there are other controls on the page that will want a prompt function. For instance, using the Property Builder for a QA to add a prompt function will automatically add a prompt function file if one does not already exist for the page. After doing so, you may add a prompt function to that file yourself for a SelectableNavigator on the same page.
: The SelectableNavigator fires this event if the user says "Cancel" while in the SelectableNavigator. Since the Navigator's built-in cancel command deactivates the Navigator, RunSpeech will skip the SelectableNavigator during subsequent iterations.
: The SelectableNavigator fires the event if the user selects an item, either by saying "Select" or the name of an item if IsDynamic
. Return true
from this handler to deactivate the SelectableNavigator.
The client- and server-side properties and methods exposed by the SelectableNavigator are documented in SelectableNavigator.html