Unlike traditional ASP.NET programming, the Speech SDK is primarily a client-side programming platform. Although its controls are instantiated and their properties manipulated on the server-side, controlling flow from one control to another is primarily a client-side task.
The controls offer opportunities to post back to the server automatically, including the SemanticItem's AutoPostBack
property and an automatic postback when all QAs on a page are satisfied. As a convention, though, we chose to only post back when we needed to access data or business layer functions
. Most of our code is written through client-side event handlers, using SpeechCommon.Submit()
to post back explicitly when data was needed from the server.
Because JScript lacks many of the scoping restrictions found in C# or VB.NET, it is possible when programming on the client-side to perform a certain task in many different places. The SpeechCommon object is accessible from any client-side script' its Submit() method can be executed from event handlers, prompt functions, or any helper routines as well. For this and other reasons, we have followed a set of guidelines for the usage of these various components:
- Prompt Functions Are Only For Generating Prompts: Never perform an action inside a prompt function that is not directly related to the generation and formatting of a prompt: no navigation flow, semantic item manipulation, etc. Besides good practice, the other key reason for reserving prompt functions only for generating prompts is validation. If prompt functions contain calls to SpeechCommon or other in-memory objects, those objects must be declared and their references included in the "Validation References" for the prompt function. If these references are not included, validation will fail for the function. As a rule, the only functions referenced by prompt functions are in PromptGenerator.js. One exception to this rule was necessary. Navigator application controls do not expose events that are equivalent to OnClientActive, or which fire each time a prompt function is about to be executed. For QA controls, we use OnClientActive to call HandleNoRecoAndSilence, which monitors consecutive invalid input for a QA. We expect future versions of the SDK to expose this type of event in the Navigator control, but until then, we call HandleNoRecoAndSilence from PromptGenerator.GenerateNavigator.
- No Inline Prompts: Inline prompts may seem attractive when the prompt text never changes, but they introduce a maintenance issue when being used with recorded prompts. Unlike prompt functions, which reference prompt databases through the values in web.config, inline prompts explicitly copy these values into the prompt tags. Should the location of the prompt database change (as it will most likely do between development, staging, and production) each inline prompt must be modified in addition to the web.config file. Since the cost of using a prompt function is so low, we avoided inline prompts altogether.
- Control of Flow Handled In Event Handlers: Flow control is the most important function of event handlers and client activation functions. Most applications that have any complexity require a more complicated flow control than the standard question-and-answer format afforded by laying QA controls down in sequence on a page. For the most part, we achieved this control by manipulating the semantic state within event handlers.
We used the following naming conventions throughout our application for consistency:
- QA Controls: The QA Control can be used for a variety of purposes. We distinguish these purposes by their function: traditional question-and-answer controls fill a semantic item with the result of user input, confirmations confirm a pre-filled semantic item, and statements are output-only; they do not accept user input.
- Question-And-Answer: <name>QA (e.g. AddToCartQA)
- Confirm: <name>Confirm (e.g. NumberOfItemsConfirm)
- Statement: <name>Statement (e.g. RestartBrowseStatement)
- Navigator Controls: <name>Nav (e.g. CategoryNav)
- Commands: <name>Command (e.g. BrowseCommand)
- Semantic Items: si<name> (e.g. siProductID)
JScript and C# server-side code use naming conventions standard in those environments.