如何使用带有C#的bot框架将用户数据从一个对话框组件保存到另一个对话框组件

时间:2019-07-10 17:39:05

标签: bots

我刚刚开始用C#开发聊天机器人。我想开发一个使用4个组件的对话,因此其他3个组件是基于一个组件的,而所有这些组件都是从主类调用的。我的类us​​erInfo如下

public class UserInfo
{
    public WillkommenInfo Willkommen { get; set; }

    public BeschwerdeInfo Beschwerde { get; set; }

    public TerminInfo Termin { get; set; }

    public FrageInfo Frage { get; set; }
}

public class WillkommenInfo
{
    public string Name { get; set; }
}

public class TerminInfo
{
    public string Ansprechpartner { get; set; }

    public string Location { get; set; }

    public string Date { get; set; }
}

public class FrageInfo
{
    public string Question { get; set; }
}

调用所有方法的主类摘录如下

public MainDialog(UserState userState)
        : base(nameof(MainDialog))
{
        _userState = userState;

        _userInfoAccessor=userState.CreateProperty<UserInfo("UserInfo");

        AddDialog(new WillkommenDialog());
        AddDialog(new TopLevelDialog());
        AddDialog(new BeschwerdeDialog());
        AddDialog(new TerminDialog());

        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new 
     WaterfallStep[]
        {
            InitialStepAsync,
            MenuStepAsync,
            HandleChoiceAsync,
            LoopBackAsync,
        }));

        InitialDialogId = nameof(WaterfallDialog);
    }

    private static async Task<DialogTurnResult> InitialStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
    {
        return await stepContext.BeginDialogAsync(nameof(WillkommenDialog), null, cancellationToken);
    }

    private  async Task<DialogTurnResult> MenuStepAsync(
    WaterfallStepContext step,
    CancellationToken cancellationToken = default(CancellationToken))
    {
        List<string> choice = new List<string> {  "Frage", "Terminanfrage", "Beschwerde", "Beenden" };
        await step.Context.SendActivityAsync(
        MessageFactory.SuggestedActions(choice, $"Wie kann ich Ihnen behilflich sein?"),
        cancellationToken: cancellationToken);
        return Dialog.EndOfTurn;

    }

    private async Task<DialogTurnResult> HandleChoiceAsync(
    WaterfallStepContext stepContext,
    CancellationToken cancellationToken = default(CancellationToken))
    {
        UserInfo userInfo = await _userInfoAccessor.GetAsync(stepContext.Context, null, cancellationToken);
       string choice = (stepContext.Result as string)?.Trim()?.ToLowerInvariant();

        switch (choice)
        {
            case "frage":
                return await stepContext.BeginDialogAsync(nameof(TopLevelDialog), userInfo.Willkommen, cancellationToken);
            case "terminanfrage":
                return await stepContext.BeginDialogAsync(nameof(TerminDialog), userInfo.Willkommen, cancellationToken);
            case "beschwerde":
                return await stepContext.BeginDialogAsync(nameof(BeschwerdeDialog), userInfo.Willkommen, cancellationToken);
            case "beenden":
                await stepContext.Context.SendActivityAsync($"Danke sehr für Ihre Teilnahme\n" +
                    $"Auf wiedersehen!");
                await stepContext.Context.SendActivityAsync($"Vielen Dank für Ihre Teilnahme. Ich hoffe ich konnte Ihnen behilflich sein. Auf Wiedersehen!");
                return await stepContext.EndDialogAsync(null, cancellationToken);

            default:
                await stepContext.Context.SendActivityAsync(
                     MessageFactory.Text($"Tut mir leid, ich verstehe diesen Befehl nicht. Bitte wählen Sie eine Option aus der Liste aus."), cancellationToken);
                return await stepContext.ReplaceDialogAsync(nameof(MainDialog), null, cancellationToken);
        }
    }

机器人的OnTurnAsync方法如下

public override async Task OnTurnAsync(ITurnContext turnContext, 
CancellationToken cancellationToken = default(CancellationToken))
    {

        await base.OnTurnAsync(turnContext, cancellationToken);
        if (turnContext.Activity.Type is ActivityTypes.Message)
        {
            await UserState.LoadAsync(turnContext, false, cancellationToken);
            var userStateAccessors = UserState.CreateProperty<UserInfo>(nameof(UserInfo));
            var userInfo = await userStateAccessors.GetAsync(turnContext, () => new UserInfo());
            await ConversationState.SaveChangesAsync(turnContext, false, cancellationToken);
            await UserState.SaveChangesAsync(turnContext, false, cancellationToken);
        }
    }

问题是我无法保存他在WillkommenDialog对话框的第一步中输入的用户名,这应该是该对话框其他3个组件的基础。 willkommen对话框组件如下

public WillkommenDialog()
    : base(nameof(WillkommenDialog))
    {
        AddDialog(new TextPrompt(NamePrompt, ValidateNameAsync));

        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {

            NameStepAsync,
            FinalStepAsync,

    }));

        InitialDialogId = nameof(WaterfallDialog);
    }

    private async Task<DialogTurnResult> NameStepAsync
        (WaterfallStepContext step,
         CancellationToken cancellationToken = default(CancellationToken))
    {
        step.Values[UserProfile] = new UserInfo();
        return await step.PromptAsync(
            NamePrompt,
            new PromptOptions
            {
                Prompt = MessageFactory.Text("Geben Sie bitte Ihren Namen 
ein."),
            },
            cancellationToken);
    }
    private async Task<DialogTurnResult> FinalStepAsync(
        WaterfallStepContext step,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        string name = step.Result as string;
        ((WillkommenInfo)step.Values[WillkommenKey]).Name = name;
        var reply = step.Context.Activity.CreateReply();
        var card = new HeroCard();
        card.Title = $"Willkommen **{name}**!";
        card.Subtitle = $"Erfahrung macht den Unterschied.";
        card.Images = new List<CardImage>() { new CardImage("https://docs.microsoft.com/en-us/azure/bot-service/bot-builder-compositcontrol?view=azure-bot-service-4.0&tabs=csharp") };
        reply.Attachments = new List<Attachment>() { card.ToAttachment() };
        await step.Context.SendActivityAsync(reply, cancellationToken: cancellationToken);
        return await step.EndDialogAsync((WillkommenInfo)step.Values[WillkommenKey], cancellationToken);
    }

从Termin组件中提取的代码,如下所示,我希望它能获得用户的名字

public TerminDialog()
        : base(nameof(TerminDialog))
    {

        AddDialog(new TextPrompt("ansprechpartner", AnsprechpartnerValidateAsync));
        AddDialog(new ChoicePrompt("location"));
        AddDialog(new DateTimePrompt("reservationDate", DateValidatorAsync));

        AddDialog(new WaterfallDialog(nameof(WaterfallDialog), new WaterfallStep[]
        {
            AnsprechpartnerStepAsync,
            LocationStepAsync,
            ReservationDateStepAsync,
            FinalStepAsync,

    }));


        InitialDialogId = nameof(WaterfallDialog);
    }

    private static async Task<DialogTurnResult> AnsprechpartnerStepAsync(
        WaterfallStepContext step,
        CancellationToken cancellationToken = default(CancellationToken))
    {
        var userInfo = (UserInfo)step.Result;
        string greeting = $"Hallo **{userInfo.Willkommen}**";
        string prompt = $"{greeting}. Geben Sie bitte den Namen Ihres Ansprechpartners ein.";

        return await step.PromptAsync(
            "ansprechpartner",
            new PromptOptions
            {
                Prompt = MessageFactory.Text($"{greeting} geben Sie bitte den Namen Ihres Ansprechpartners ein."),
                RetryPrompt = MessageFactory.Text($"{greeting} geben Sie bitte den Namen Ihres Ansprechpartners ein."),

            },
            cancellationToken);
    }

有人可以通过告诉我如何获取3个组成部分(Frage,Termin和Beschwerde)来获得他们已经输入到willkommen对话组件中的所有用户名的帮助吗?

0 个答案:

没有答案