。 versionAttempts
フィールドがprivate static
あるか
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow.Advanced;
using System.Threading.Tasks;
namespace BugFormFlowBot2
{
[Serializable]
[Template(TemplateUsage.EnumSelectOne, "Which {&} were you working with? {||}")]
[Template(TemplateUsage.EnumSelectMany, "Which {&} were you working with? {||}", ChoiceStyle = ChoiceStyleOptions.PerLine)]
public class BugReport
{
public string Product { get; set; }
public string Version { get; set; }
public List<PlatformOptions> Platform { get; set; }
[Prompt("What is the {&}")]
[Describe("Description of the Problem")]
public string ProblemDescription { get; set; }
[Numeric(1, 3)]
public int Priority { get; set; }
private static int versionAttempts = 0;
public static IForm<BugReport> BuildForm()
{
return new FormBuilder<BugReport>()
.Message("Welcome to Bug Report bot!")
.Field(new FieldReflector<BugReport>(nameof(Product))
.SetType(null)
.SetDefine((state, field) =>
{
foreach (var prod in GetProducts())
field
.AddDescription(prod, prod)
.AddTerms(prod, prod);
return Task.FromResult(true);
}))
.Field(nameof(Version),
validate: async (state, response) =>
{
var result = new ValidateResult { IsValid = true, Value = response };
foreach (var segment in (response as string ?? "").Split('.'))
{
int digit;
if (!int.TryParse(segment, out digit))
{
result.Feedback =
"Version number must be numeric segments, optionally separated by dots. e.g. 7.2, 10, or 3.56";
result.IsValid = false;
if (++versionAttempts > 2)
throw new TooManyAttemptsException("Too many attempts at the version number.");
break;
}
}
return await Task.FromResult(result);
})
.Field(nameof(Platform))
.AddRemainingFields()
.Confirm(async (bugReport) =>
{
var response = new PromptAttribute(
$"You entered {bugReport.Product}, {bugReport.Version}, {bugReport.Platform}" +
$"{bugReport.ProblemDescription}, {bugReport.Priority}. Is this Correct?");
return await Task.FromResult(response);
})
.OnCompletion(async (context, bugReport) =>
{
await context.PostAsync("Thanks for the report!");
})
.Build();
}
static List<string> GetProducts()
{
return new List<string>
{
"Office",
"SQL Server",
"Visual Studio"
};
}
}
}
は注意:ただし、この問題を回避するには、このような独自のフィールド検証を実行することです。次に、Version
フィールドの検証と、それがTooManyAttemptsException
をスローする方法を確認します。
FormFlowがすべての例外をラップするので、これは完全に問題を解決するわけではありません。FormCanceledException
です。次のコードはそれを処理する方法を示しています。
using System;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using System.Net.Http;
using System.Net;
namespace BugFormFlowBot2
{
[BotAuthentication]
public class MessagesController : ApiController
{
internal static IDialog<BugReport> MakeRootDialog()
{
return Chain.From(() => FormDialog.FromForm(BugReport.BuildForm))
.Loop();
}
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity?.Type == ActivityTypes.Message)
try
{
await Conversation.SendAsync(activity, MakeRootDialog);
}
catch (FormCanceledException fcEx) when(fcEx.InnerException is TooManyAttemptsException)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
Activity reply = activity.CreateReply(
$"Too Many Attempts at {fcEx.Last}. " +
$"Completed Steps: {string.Join(", ", fcEx.Completed)}");
await connector.Conversations.ReplyToActivityAsync(reply);
}
catch (FormCanceledException fcEx)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
Activity reply = activity.CreateReply(
$"Form cancelled at {fcEx.Last}. " +
$"Completed Steps: {string.Join(", ", fcEx.Completed)}");
await connector.Conversations.ReplyToActivityAsync(reply);
}
return Request.CreateResponse(HttpStatusCode.OK);
}
}
}
お知らせPost
でFormCanceledException
ハンドラ、TooManyAttemptsException
が発生したときにあなたが知ることができ、when(fcEx.InnerException is TooManyAttemptsException)
を使用。面白いことに、FormCanceledException
は、完了したフィールドに関する詳細情報を提供し、例外時のフォームの状態に関する詳細情報を提供します。
このコードは、BotDemos GitHubリポジトリのBugFormFlowBot2プロジェクトにあります。
ありがとうございます。あなたのケースでは "バージョン"フィールドは文字列なので、ユーザーがこのフィールドに任意のputを渡すと、validateメソッドが呼び出されます。私の場合、フィールドはEnum型です。したがって、 "validate:"メソッドが呼び出されていない場合は、エラーメッセージが直接表示されます。あらかじめ定義されたオプションがあるEnum型フィールドの場合、validateメソッドは呼び出されません。 – user1899731
これは私の列挙型フィールドです。[Template(TemplateUsage.NotUnderstood、 "私は理解できません\" {0} \ "、"再試行、\ "{0} \"を取得しません。])]) public CustomerTypeOptions?顧客タイプ;私はテンプレートメッセージを直接取得します – user1899731