C# Botframework V4:关于输入表单卡的问题
你好,我有这张输入表格卡。它正在正确渲染,但如何获得其结果?我怎样才能使bot在继续下一步之前等待用户提交?放置stepContext.NextAsync将自动触发下一步。但是删除它会导致错误,因为它需要返回一些内容C# Botframework V4:关于输入表单卡的问题,c#,botframework,adaptive-cards,C#,Botframework,Adaptive Cards,你好,我有这张输入表格卡。它正在正确渲染,但如何获得其结果?我怎样才能使bot在继续下一步之前等待用户提交?放置stepContext.NextAsync将自动触发下一步。但是删除它会导致错误,因为它需要返回一些内容 public InitialQuestions(string dialogId, IEnumerable<WaterfallStep> steps = null) : base(dialogId, steps) { AddS
public InitialQuestions(string dialogId, IEnumerable<WaterfallStep> steps = null)
: base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
var cardAttachment = CreateAdaptiveCardAttachment(_cards);
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
// how can i wait for user to click submit before going to next step?
return await stepContext.NextAsync();
// return await stepContext.PromptAsync(
// "textPrompt",
// new PromptOptions
// {
// Prompt = MessageFactory.Text(""),
// },
// cancellationToken: cancellationToken);
});
AddStep(async (stepContext, cancellationToken) =>
{
// next step
});
}
private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
谢谢各位
编辑:这是我找到的答案,供以后参考
AddStep(async (stepContext, cancellationToken) =>
{
var state = await (stepContext.Context.TurnState["BasicAccessors"] as BasicAccessors).BasicStateAccessor.GetAsync(stepContext.Context);
var jsonString = (JObject)stepContext.Context.Activity.Value;
BasicState results = JsonConvert.DeserializeObject<BasicState>(jsonString.ToString());
state.Occupation = results.Occupation;
state.Married = results.Married;
state.Birthday = results.Birthday;
return await stepContext.NextAsync();
});
AddStep(异步(stepContext,cancellationToken)=>
{
var state=await(stepContext.Context.TurnState[“BasicAccessors”]作为BasicAccessor)。BasicStateAccessor.GetAsync(stepContext.Context);
var jsonString=(JObject)stepContext.Context.Activity.Value;
BasicState results=JsonConvert.DeserializeObject(jsonString.ToString());
状态.职业=结果.职业;
州。已婚=结果。已婚;
state.birth=结果.birth;
返回wait-stepContext.NextAsync();
});
让我按相反顺序回答您的问题:
我怎样才能使bot在继续下一步之前等待用户提交?放置stepContext.NextAsync将自动触发下一步。但是删除它会导致错误,因为它需要返回一些内容
public InitialQuestions(string dialogId, IEnumerable<WaterfallStep> steps = null)
: base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
var cardAttachment = CreateAdaptiveCardAttachment(_cards);
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
// how can i wait for user to click submit before going to next step?
return await stepContext.NextAsync();
// return await stepContext.PromptAsync(
// "textPrompt",
// new PromptOptions
// {
// Prompt = MessageFactory.Text(""),
// },
// cancellationToken: cancellationToken);
});
AddStep(async (stepContext, cancellationToken) =>
{
// next step
});
}
private static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
是的,这是真的,你需要从你的步骤中返回一些东西,但是正如你指出的,你还没有准备好让它进入下一步。答案是您希望在此时使用提示!现在我看到这里有一些代码被注释掉了,可能让人困惑的是,今天,没有关于使用卡片的具体提示。相反,您确实希望使用通用的TextPrompt
,我们将在该提示符上设置活动,而不仅仅是简单的文本
记住这一点,您可以在上面保留代码,即使用CreateReply
构建带有卡附件的活动,但是,您希望将其设置为TextPrompt
的Prompt
属性的值,而不是使用SendActivityAsync
自己发送该活动,如下所示:
AddStep(异步(stepContext,cancellationToken)=>
{
return wait stepContext.PromptAsync(
“我的提示”,
新提示
{
Prompt=新活动
{
类型=ActivityTypes.Message,
附件=新列表()
{
创建AdaptiveCardAttachment(_卡),
},
},
},
cancellationToken:cancellationToken);
});
好的,这就是问题的一半。考虑到这一点,让我们回到问题的第一部分:
你好,我有这张输入表格卡。它正在正确渲染,但如何获得其结果
您的自适应卡正在使用提交
操作,这意味着您将收到一个包含活动
的值
属性中表单值的活动,但是,由于我们在上面使用了TextPrompt
,因此TextPrompt
的默认验证行为将验证是否为活动
的Text
部分提供了某个值,而在本例中不会提供该值。因此,为了解决这个问题,当您配置TextPrompt
时,您确实希望提供自己的PromptValidator
,如下所示:
Add(newtextprompt(“myPrompt”),newpromptValidator(异步(pvc,ct)=>true));
这基本上意味着无论发生什么,输入都是有效的。如果您愿意,您可以通过实际检查值的详细信息来使其更丰富,但现在应该取消对您的阻止
现在,回到您的waterwall对话框
中,您的下一步将接收活动
,其值
属性将是一个作业对象
,您可以直接使用该属性,也可以调用作业对象::ToObject
将其转换为您创建的表示表单输入的特定类:
AddStep(异步(stepContext,cancellationToken)=>
{
//这将为您提供传入值的JObject表示
var rawValues=(JObject)stepContext.Context.Activity.Values;
//您可以将其转换为类似这样的强类型
//其中MyFormValues是您定义的类
var myFormValues=rawValues.ToObject();
});
最后,我想说,在回答您的问题时,我记录了一系列反馈,我打算发送给产品团队,以改善API设计和文档方面的这种情况,因为很明显,这不是显而易见的或最佳的。先生,“ToObject”中有一个错误这需要nuget软件包吗?我有一个名为“职业、生日、已婚”的类“BasicState”。很抱歉,我在回答的代码中留下了一个到JObject
的演员阵容,现在正在更新。谢谢先生,抱歉,这是我第一次使用json。你能教我如何直接访问这些json值吗?简单的回答是,你可以像使用字典一样使用它来访问你需要的每个值,但我保证如果你搜索这个网站,关于如何使用JObject
,会有很多问题/答案。我用drew爵士的答案编辑了我的问题。我的答案正确吗?还是为并发用户保存?