我尝试继承PromptString类并循环提示,直到用户提供正确的输入。
我编写了以下代码来验证用户是否指定了有效日期。
这是我的自定义提示类,我要验证用户是否输入了正确的日期,如果他输入了正确的日期,它应该只是退出对话框,否则它应该再次重新提示输入。< / p>
namespace CustomPromptDemo.Models
{
public class CustomPrompt : PromptString
{
public CustomPrompt(string Prompt = "Please enter a date", string Retry = "Please enter a valid date!!!", int RetryCount = 3) : base(Prompt, Retry, RetryCount)
{
}
protected override IMessageActivity MakePrompt(IDialogContext context, string prompt, IReadOnlyList<string> options = null, IReadOnlyList<string> descriptions = null, string speak = null)
{
return base.MakePrompt(context, prompt, options, descriptions, speak);
}
bool ValidateIfDateOrNot(string Query)
{
try
{
DateTime date = default(DateTime);
DateTimeModel model = DateTimeRecognizer.GetInstance().GetDateTimeModel(Culture.English);
List<ModelResult> parsedResults = model.Parse(Query);
var resolvedValue = (parsedResults.SelectMany(x => x.Resolution).FirstOrDefault().Value as List<Dictionary<string, string>>).SelectMany(x => x).Where(x => x.Key.Equals("value")).Select(y => y.Value).FirstOrDefault();
return DateTime.TryParse(resolvedValue, out date);
}
catch (Exception ex)
{
throw;
}
}
protected override async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> message)
{
IMessageActivity msg = await message;
if (ValidateIfDateOrNot(msg.Text))
{
await context.PostAsync("Valid date!");
context.Done<object>(null);
}
else
{
await context.PostAsync("Please enter a valid date!");
await base.MessageReceivedAsync(context, message);
}
}
protected override bool TryParse(IMessageActivity message, out string result)
{
return base.TryParse(message, out result);
}
}
}
这是我的RootDialog
namespace CustomPromptDemo.Dialogs
{
[Serializable]
public class RootDialog : IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
return Task.CompletedTask;
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
CustomPrompt c = new CustomPrompt();
c.
}
}
}
我有多种方法可供选择,如下面的截图所示。
我无法调用我制作的自定义提示。 感谢任何帮助。谢谢。
答案 0 :(得分:1)
您可以像使用PromptDialog.Text一样使用它,请参阅GitHub来源:
public class PromptDialog
{
public static void Text(IDialogContext context, ResumeAfter<string> resume, string prompt, string retry = null, int attempts = 3)
{
var child = new PromptString(prompt, retry, attempts);
context.Call<string>(child, resume);
}
所以在你的情况下:
[Serializable]
public class RootDialog : IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
return Task.CompletedTask;
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<object> result)
{
var prompt = new CustomPrompt();
context.Call<string>(prompt, ResumeAfterPromptString);
}
private async Task ResumeAfterPromptString(IDialogContext context, IAwaitable<string> result)
{
// Do what you want here... But your customPrompt should return a string
context.Done<object>(null);
}
}
顺便说一句,您还必须使CustomPrompt
可序列化:
[Serializable]
public class CustomPrompt : PromptDialog.PromptString
如果ValidateIfDateOrNot
没问题,你应该返回你的字符串而不是null。
编辑:最后一件事,你应该看看GitHub项目中提供的关于你正在使用的识别器的样本,here,这是解析日期的一个很好的例子,就像你想要的那样
答案 1 :(得分:1)
我在我的机器人中构建了一些非常相似的东西,提示用户输入图像,然后如果他们没有输入有效图像则继续循环:
[Serializable]
public class PhotoInputDialog : IDialog<string>
{
public ICustomInputValidator<IMessageActivity> Validator { get; private set; }
public string InputPrompt { get; private set; }
public string WrongInputPrompt { get; private set; }
public static PhotoInputDialog Create
(string inputPrompt, string wrongInputPrompt, ICustomInputValidator<IMessageActivity> validator)
{
return new PhotoInputDialog()
{ InputPrompt = inputPrompt, WrongInputPrompt = wrongInputPrompt, Validator = validator };
}
public async Task StartAsync(IDialogContext context)
{
await context.PostAsync(InputPrompt);
context.Wait(InputGiven);
}
private async Task InputGiven(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (!Validator.IsValid(message))
{
await context.PostAsync(WrongInputPrompt);
context.Wait(InputGiven);
}
else
context.Done(message.Attachments.First().ContentUrl);
}
}
工作原理:
当我创建对话框时,我提交了一个用于验证结果的验证器类,这是我创建的用于验证特定长度的文本输入的验证器类。它不是100%必要的,但它现在很好并且可以重复使用:
[Serializable()]
public class TextCustomInputValidator : ICustomInputValidator<string>
{
private int MinLength, MaxLength;
public TextCustomInputValidator(int minLength, int maxLength)
{
MinLength = minLength;
MaxLength = maxLength;
}
public bool IsValid(string input)
{
return input.Length >= MinLength && input.Length <= MaxLength;
}
}
在Bot框架中有很多不同的方法来做Bot,所以可能有其他方法可行。我想到的另一个问题是使用FormFlow,因为它有一个日期输入验证器:https://docs.botframework.com/en-us/csharp/builder/sdkreference/dc/db8/class_microsoft_1_1_bot_1_1_builder_1_1_form_flow_1_1_advanced_1_1_recognize_date_time.html
答案 2 :(得分:1)
您可以使用DateTimePrompt,或者如果您真的想进一步控制简单的TextPrompt并为其提供自定义验证器,则可以:
1,Maths,85
在对话框中,您可以启动提示,提供重试提示,以便在重试失败时显示单独的消息:
AddDialog(new DateTimePrompt(nameof(DateTimePrompt), DateTimePromptValidator));
如果您希望使用多种语言的日期来处理高级案件,我建议您看一下Microsoft的Recognizers-Text,该语言当前在LUIS:语言理解智能服务中提供预构建实体。