Context.Wait () не сохраняет родительские свойства

Manmax75 спросил: 28 апреля 2018 в 08:39 в: json

Я создаю динамические "сообщения", которые могут быть созданы и объединены вместе во время выполнения.

У меня есть следующие классы

[Serializable]
[JsonObject(IsReference = true)]
public class Node : INode
{
    public virtual int ID { get; set; }
    public virtual string Name { get; set; }
    public virtual bool WaitForInput { get; set; }
    public virtual int OnCompleteID { get; set; }
    public virtual string OnCompleteName { get; set; }
    public virtual Node OnCompleteNode { get; set; }    public virtual async Task OnExcecute(IDialogContext context, Activity activity)
    {        if (OnCompleteNode != null)
            if (WaitForInput)
                context.Wait(OnCompleteNode.OnExcecuteAwait);
            else
                await OnCompleteNode.OnExcecute(context, activity);
    }    public virtual async Task OnExcecuteAwait(IDialogContext context, IAwaitable<object> result)
    {
        Activity activity = await result as Activity;        await OnExcecute(context, activity);
    }
}

Какие следующий класс наследует:

public class MessageNode : Node
{
    /*public override int ID { get; set; }
    public override string Name { get; set; }
    public override bool WaitForInput { get; set; }
    public override int OnCompleteID { get; set; }
    public override string OnCompleteName { get; set; }
    public override Node OnCompleteNode { get; set; }*/    public virtual string Message { get; set; }
    public virtual List<Attachment> Attachments { get; set; }
    public virtual string AttachmentLayoutType { get; set; }    public override async Task OnExcecute(IDialogContext context, Activity activity)
    {
        IMessageActivity reply = context.MakeMessage();
        reply.Text = Message;
        if (Attachments != null)
        {
            reply.Attachments = Attachments;
            reply.AttachmentLayout = AttachmentLayoutType;
        }        await context.PostAsync(reply);        await base.OnExcecute(context, activity);    }
}

Наконец, я собираю данные в моем RootDialog

public Task StartAsync(IDialogContext context)
    {
        Schema.MessageNode preMN1 = new Schema.MessageNode();
        preMN1.Message = "and then one more";
        preMN1.ID = 2;
        preMN1.WaitForInput = true;        Schema.MessageNode preMN = new Schema.MessageNode();
        preMN.Message = "and then";
        preMN.ID = 1;
        preMN.OnCompleteNode = preMN1;
        preMN.WaitForInput = true;        Schema.MessageNode messageNode = new Schema.MessageNode();
        messageNode.Message = "test";
        messageNode.ID = 0;
        messageNode.OnCompleteNode = preMN;
        messageNode.WaitForInput = true;        preMN1.OnCompleteNode = messageNode;        string jTest = JsonConvert.SerializeObject(messageNode);        context.Wait(messageNode.OnExcecuteAwait);        return Task.CompletedTask;
    }

В настоящее время OnExcecuteAwait of messageNode получает называется первым. Что отображает "тест" в чате, все хорошо до сих пор. Поскольку флаг WaitForInput установлен в true, следующий узел в цепочке (preMN) вызывается с context.Wait. Когда пользователь отвечает на вход, текст "а затем" отправляется по желанию, а не перемещается к следующему узлу в цепочке. Он застревает в preMN и продолжает цикл. После отладки я обнаружил, что свойство OnCompleteNode (вместе со всеми виртуальными свойствами, определенными в родительском классе Node) было очищено.

Странно, если я переопределяю виртуальные свойства класса MessageNode, контекст.Wait полностью разрывается, и bot постоянно возвращается к RootDialog.However, если я затем удалю строку "preMN1.OnCompleteNode = messageNode;" поведение работает отлично, и бот заканчивается на последнем узле, как ожидалось. Я предполагаю, что это может быть связано с некоторыми предупреждениями цикла, когда состояние бота сериализовано, но в идеале я хотел бы иметь возможность возвращаться к предыдущему сообщению, если это необходимо.

1 ответ

Manmax75 ответил: 28 апреля 2018 в 01:25

Оказывается, добавление атрибута [Serialized] в класс MessageNode устраняет проблему. Спасибо за отзыв Эрик!