Сложные формы Azure Bot Framework FormFlow

Я пытаюсь создать бота с Azure Bot Framework, который будет запрашивать неизвестное количество сложных объектов (для каждого потребуется три ответа). Но я не знаю, как создать форму для каждого из сложных объектов в корневой форме. См. http://docs.botframework.com/sdkreference/csharp/forms.html. В нем говорится: «Чтобы обрабатывать список сложных объектов, вам необходимо создать форму для класса C# верхнего уровня, а также одну для сложного объекта. Вы можете использовать систему диалогов для составления форм вместе». Это то, что я не знаю, как это сделать.

public enum SystemSelection { SharePoint, BizTalk, Azure, Office365 };

public enum RequestType { Bug, SupportRequest, Question };

public enum Importance { Blocking, High, Medium, Low };

[Serializable]
class Declaration
{
    public string Type;
    public string Amount;
    public string Date;

    public static IForm<Declaration> BuildForm()
    {
        return new FormBuilder<Declaration>()
                .Message("Add a declaration")
                .Build();
    }
}

[Serializable]
class SupportRequest
{

    public SystemSelection? SystemSelection;
    public RequestType? RequestType;
    public Importance? Importance;

    public List<Declaration> Declarations;

    public static IForm<SupportRequest> BuildForm()
    {
        IForm<Declaration> aForm = new FormBuilder<Declaration>().Message("Add declaration").Build();

        // now what?

        return new FormBuilder<SupportRequest>()
                .Message("Welcome to the simple support bot!")
                .Build();
    }
}

Контроллер:

  [BotAuthentication]
  public class MessagesController : ApiController
{
    internal static IDialog<SupportRequest> MakeRootDialog()
    {
        // change something here??
        return Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm));
    }

    public async Task<Message> Post([FromBody]Message message)
    {
        if (message.Type == "Message")
        {
            return await Conversation.SendAsync(message, MakeRootDialog);
        }
        else
        {
            return HandleSystemMessage(message);
        }
    }

person JurgenW    schedule 11.05.2016    source источник


Ответы (1)


Вы можете создавать свои диалоги, используя методы класса Chain. Поскольку эти методы также поддерживают синтаксис LINQ, вы можете написать что-то подобное в своем MakeRootDialog для последовательного выполнения SupportRequest диалогового окна и Decalaration диалогового окна:

    internal static IDialog<SupportRequest> MakeRootDialog()
    {
        var dlg = from x in FormDialog.FromForm(SupportRequest.BuildForm)
                  from y in FormDialog.FromForm(Declaration.BuildForm)
                  select x;
        return dlg;
        // return Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm));
    }

Вы также можете связать диалоги вручную следующим образом:

        var dlg = Chain.From(() => FormDialog.FromForm(SupportRequest.BuildForm))
            .ContinueWith<SupportRequest,Declaration>(async (ctx, sr) =>
            {
                var res = await sr;
                return FormDialog.FromForm(Declaration.BuildForm);
            });
person Dmitri Soshnikov    schedule 11.05.2016
comment
Я пробую это с помощью первого метода, но я не могу понять это полностью правильно. Возможно это у меня не хватает навыков в Linq, но бот никогда не просит ввести декларацию. - person JurgenW; 12.05.2016
comment
@JurgenW, на самом деле открывается диалоговое окно «Объявление», но оно ожидает, что пользователь произнесет первое сообщение. Поэтому, если вы введете что-то вроде «Привет» после ввода SupportRequest, вы увидите, что открывается диалоговое окно «Декларация». На данный момент я не уверен на 100%, как это исправить. - person Dmitri Soshnikov; 12.05.2016
comment
Хм, у меня такого не бывает. Когда я добавляю одно свойство в класс бота типа List‹Declaration›, бот сразу говорит: «Это ваш выбор? первый раз говорю привет. У меня нет возможности добавить ввод. - person JurgenW; 13.05.2016