如何在构建Microsoft Bot Framework Form Builder表单前及流程中获取用户输入?
Great question! Catching user inputs like "exit" at any point in a FormFlow process and acting on them is a common requirement, and it's straightforward to implement with FormBuilder's extensibility features. Here's how to do it step by step:
1. Capture User Input & Store in State
First, you'll need to intercept every user message sent to the form, save it to a state variable, and check if it matches your exit command. Use the MessageReceived method on FormBuilder to inject this custom logic.
Example Form Class
Let's start with a simple sample form to work with:
public class UserProfileForm { [Prompt("Please enter your full name: {||}")] public string FullName { get; set; } [Prompt("What's your email address? {||}")] public string Email { get; set; } [Prompt("How many years of experience do you have? {||}")] public int ExperienceYears { get; set; } }
Add Custom Message Handling
When building your form, add the MessageReceived handler to capture input, save it to state, and handle the exit command:
public static IForm<UserProfileForm> BuildUserProfileForm() { return new FormBuilder<UserProfileForm>() .MessageReceived(async (dialogContext, formState) => { // Get and normalize the user's input string userInput = dialogContext.Activity.Text?.Trim().ToLower(); // Save input to user-specific state (persists across conversations for this user) dialogContext.UserData.SetValue("LastUserInput", userInput); // Check if the input is the exit command if (userInput == "exit") { // Send a confirmation message to the user await dialogContext.PostAsync("You've exited the form process successfully."); // Return null to terminate the FormFlow immediately return null; } // If not an exit command, let FormFlow continue processing normally return formState; }) .Build(); }
2. Handle Form Termination in Your Dialog
When the user exits the form, the FormDialog will either return null or throw an OperationCanceledException—you can handle both cases in the resume method:
public async Task StartAsync(IDialogContext context) { // Launch the form dialog var formDialog = FormDialog.FromForm(BuildUserProfileForm(), FormOptions.PromptInStart); context.Call(formDialog, AfterFormCompletion); } private async Task AfterFormCompletion(IDialogContext context, IAwaitable<UserProfileForm> result) { try { var completedForm = await result; // Logic for when the form is filled out successfully await context.PostAsync($"Thanks {completedForm.FullName}! We've saved your details."); } catch (OperationCanceledException) { // This catches cases where the form was canceled (including our exit command) await context.PostAsync("Form process was canceled. Feel free to start again anytime!"); } // End the dialog context.Done<object>(null); }
Key Notes
- Normalize Input: Using
Trim().ToLower()ensures commands like "Exit", "EXIT", or " exit " are all recognized. - State Storage: Use
dialogContext.UserDatafor user-specific state, ordialogContext.ConversationDataif you need the input stored per conversation. - Flexible Logic: You can extend this handler to support other custom commands (like "help" or "restart") by adding more condition checks.
内容的提问来源于stack exchange,提问作者Loai Tayem

