如何在构建表单之前获取用户输入。例如,如果用户在表单流中的任何时候键入“exit”,我想将用户输入保存到状态变量中并检查它是否等于“退出”,如果是,则返回null或执行一些代码。
namespace MyBot.Helpers
{
public enum Person
{
// [Describe("I am a Student")]
IAmStudent,
// [Describe("I am an Alumni")]
IAmAlumni,
// [Describe("Other")]
Other
};
public enum HardInfo { Yes, No };
[Serializable]
public class FeedBackClass
{
public bool AskToSpecifyOther = true;
public string OtherRequest = string.Empty;
[Prompt("May I Have Your Name?")]
[Pattern(@"^[a-zA-Z ]*$")]
public string Name { get; set; }
[Prompt("What is your Email Address?")]
public string Email { get; set; }
[Prompt("Please Select From The Following? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public Person? PersonType { get; set; }
[Prompt("Please Specify Other? {||}")]
public string OtherType { get; set; }
[Prompt("Was The Information You Are Looking For Hard To Find? {||}")]
[Template(TemplateUsage.NotUnderstood, "What does \"{0}\" mean?", ChoiceStyle = ChoiceStyleOptions.Auto)]
public HardInfo? HardToFindInfo { get; set; }
public static IForm<FeedBackClass> MYBuildForm()
{
var status = "exit";
if (status == null) {
return null;
}
else
{
return new FormBuilder<FeedBackClass>()
.Field(nameof(Name), validate: ValidateName)
.Field(nameof(Email), validate: ValidateContactInformation)
.Field(new FieldReflector<FeedBackClass>(nameof(PersonType))
.SetActive(state => state.AskToSpecifyOther)
.SetNext(SetNext))
.Field(nameof(OtherType), state => state.OtherRequest.Contains("oth"))
.Field(nameof(HardToFindInfo)).Confirm("Is this your selection?\n{*}")
.OnCompletion(async (context, state) =>
{
await context.PostAsync("Thanks for your feedback! You are Awsome!");
context.Done<object>(new object());
})
.Build();
}
答案 0 :(得分:1)
如果用户键入&#34;退出&#34;在表单流程中的任何时候,我想将用户输入保存到状态变量中并检查它是否等于&#34;退出&#34;如果是,则返回null或执行一些代码。
您似乎希望实现全局处理程序来处理&#34;退出&#34;命令。 Scorables可以拦截发送给Conversation的每条消息,并根据您定义的逻辑对消息应用分数,这可以帮助您实现它,您可以尝试。
有关详细信息,请参阅Global message handlers using scorables或此Global Message Handlers Sample
以下代码段对我有用,您可以参考它。
<强> ExitDialog:强>
public class ExitDialog : IDialog<object>
{
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync("This is the Settings Dialog. Reply with anything to return to prior dialog.");
context.Wait(this.MessageReceived);
}
private async Task MessageReceived(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if ((message.Text != null) && (message.Text.Trim().Length > 0))
{
context.Done<object>(null);
}
else
{
context.Fail(new Exception("Message was not a string or was an empty string."));
}
}
}
<强> ExitScorable:强>
public class ExitScorable : ScorableBase<IActivity, string, double>
{
private readonly IDialogTask task;
public ExitScorable(IDialogTask task)
{
SetField.NotNull(out this.task, nameof(task), task);
}
protected override async Task<string> PrepareAsync(IActivity activity, CancellationToken token)
{
var message = activity as IMessageActivity;
if (message != null && !string.IsNullOrWhiteSpace(message.Text))
{
if (message.Text.ToLower().Equals("exit", StringComparison.InvariantCultureIgnoreCase))
{
return message.Text;
}
}
return null;
}
protected override bool HasScore(IActivity item, string state)
{
return state != null;
}
protected override double GetScore(IActivity item, string state)
{
return 1.0;
}
protected override async Task PostAsync(IActivity item, string state, CancellationToken token)
{
var message = item as IMessageActivity;
if (message != null)
{
var settingsDialog = new ExitDialog();
var interruption = settingsDialog.Void<object, IMessageActivity>();
this.task.Call(interruption, null);
await this.task.PollAsync(token);
}
}
protected override Task DoneAsync(IActivity item, string state, CancellationToken token)
{
return Task.CompletedTask;
}
}
<强> GlobalMessageHandlersBotModule:强>
public class GlobalMessageHandlersBotModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder
.Register(c => new ExitScorable(c.Resolve<IDialogTask>()))
.As<IScorable<IActivity, double>>()
.InstancePerLifetimeScope();
}
}
注册模块:
Conversation.UpdateContainer(
builder =>
{
builder.RegisterModule(new ReflectionSurrogateModule());
builder.RegisterModule<GlobalMessageHandlersBotModule>();
});
测试结果: