c# – Botframework V4:关于输入表格卡的问题
作者:互联网
你好,我有这个输入表格卡.它渲染得很好,但我怎样才能得到它的结果呢?我怎样才能让机器人在进行下一步之前等待用户提交?放置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;
}
这是卡
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"text": "What is your Occupation?"
},
{
"type": "Input.Text",
"id": "Occupation",
"placeholder": "Occupation"
},
{
"type": "TextBlock",
"text": "Are you married? "
},
{
"type": "Input.ChoiceSet",
"id": "Married",
"value": "true",
"choices": [
{
"title": "Yes",
"value": "true"
},
{
"title": "No",
"value": "false"
}
],
"style": "expanded"
},
{
"type": "TextBlock",
"text": "When is your birthday?"
},
{
"type": "Input.Date",
"id": "Birthday",
"value": ""
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Submit",
"data": {
"id": "1234567890"
}
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
多谢你们.
编辑:为了将来参考其他人这是我找到的答案.
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();
});
解决方法:
让我以相反的顺序回答你的问题:
And how can i make it so that the bot wait for the user to submit before proceding to the next step? Putting stepContext.NextAsync will automatically trigger the next step. But removing it will cause an error because it needs to return something.
是的,这是真的,你需要从你的步骤返回一些东西,但正如你所指出的那样,你尚未准备好继续前进到下一步.答案是你想在这一点上使用提示!现在我看到你有一些代码在这里注释掉了,也许令人困惑的是,今天,没有具体的提示使用卡片.相反,您确实希望使用通用的TextPrompt,我们将其上的活动设置为除简单文本之外的其他内容.
考虑到这一点,您将使用CreateReply将代码保持在上面,以使用卡附件构建您的活动,但是,您不希望自己使用SendActivityAsync发送该活动,而是将其设置为TextPrompt的Prompt属性的值,如此:
AddStep(async (stepContext, cancellationToken) =>
{
return await stepContext.PromptAsync(
"myPrompt",
new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
Attachments = new List<Attachment>()
{
CreateAdaptiveCardAttachment(_cards),
},
},
},
cancellationToken: cancellationToken);
});
好的,这就是问题的一半.考虑到这一点,让我们回到你问题的第一部分:
Hello i have this input forms card. It is rendering properly but how can i get its results?
好吧,你的自适应卡正在使用提交操作,这意味着你将收到一个活动,其中包含活动的Values属性中的表单值,但是因为我们在TextPrompt的默认验证行为之上使用了TextPrompt验证为Activity的Text部分提供了一些值,在这种情况下不会.因此,要解决这个问题,在配置TextPrompt时,您确实想要提供自己的PromptValidator< T>像这样:
Add(new TextPrompt("myPrompt", new PromptValidator<string>(async (pvc, ct) => true)));
这基本上说无论如何输入都是有效的.如果您想通过实际检查值的详细信息,您可以使其更丰富,但这应该取消阻止您.
现在,回到您的WaterfallDialog中,下一步将接收Activity,其Value属性将是一个JObject,您可以直接使用它,也可以调用JObject :: ToObject< T>将它转换为您创建的表示表单输入的特定类:
AddStep(async (stepContext, cancellationToken) =>
{
// This will give you a JObject representation of the incoming values
var rawValues = (JObject)stepContext.Context.Activity.Values;
// You can convert that to something more strongly typed like so
// where MyFormValues is a class you've defined
var myFormValues = rawValues.ToObject<MyFormValues>();
});
我想简单地回答这个问题,在回答你的问题时,我已经记录了一堆反馈,我打算发送给产品团队,以便在API设计和文档方面改善这种情况,因为很明显,这不是显而易见的或最佳的.
标签:c,botframework,adaptive-cards 来源: https://codeday.me/bug/20190701/1345711.html