Я только начал разработку чат-бота на C #. Я хочу разработать диалог, который использует 4 компонента, поэтому остальные 3 основаны на одном, и все эти компоненты вызываются из основного класса. Мой класс userInfo выглядит следующим образом
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?