MS BotFramework数据保存,BotState

下面是整个代码块,基本上是formflow,我正在尝试将数据保存到botState中 .

public class ProfileForm
{
    // these are the fields that will hold the data
    // we will gather with the form
    [Prompt("What is your first name? {||}")]
    public string FirstName;

    [Prompt("What is your last name? {||}")]
    public string LastName;

    [Prompt("What is your gender? {||}")]
    public Gender Gender;

    // This method 'builds' the form 
    // This method will be called by code we will place
    // in the MakeRootDialog method of the MessagesControlller.cs file

    public static IForm<ProfileForm> BuildForm()
    {
        return new FormBuilder<ProfileForm>()

                .Message("Please complete your profile!")
                .OnCompletion(async (context, profileForm) =>

                {
                    BotData bt = new BotData();

                    await context.PostAsync("Your profile is complete.\n\n"+profileForm.FirstName+profileForm.LastName+profileForm.Gender);

                    SessionInfo.botUserData.SetProperty<bool>("ProfileComplete", true);
                    SessionInfo.botUserData.SetProperty<string>("FirstName", profileForm.FirstName);
                    SessionInfo.botUserData.SetProperty<string>("LastName", profileForm.LastName);
                    SessionInfo.botUserData.SetProperty<string>("Gender", profileForm.Gender==Gender.Male? "Male" :"Female");

                    await context.PostAsync("Before Saving");

                    await SessionInfo.userStateClient.BotState.SetPrivateConversationDataWithHttpMessagesAsync(
                        SessionInfo.ChannelID, SessionInfo.ConversationID, SessionInfo.FromID, SessionInfo.botUserData);
                    // Tell the user that the form is complete
                    await context.PostAsync("Your profile is complete.");

                })
                .Build();
    }
}
// This enum provides the possible values for the 
// Gender property in the ProfileForm class
// Notice we start the options at 1 
[Serializable]

public enum Gender

{

    Male = 1, Female = 2

};

我在行 SetPrivateConversationDataWithHttpMessagesAsync() 方法调用时遇到以下错误,请帮忙 .


对象引用未设置为对象的实例 . 在Microsoft.Bot.Builder.FormFlow.FormDialog1 . <MessageReceived> d__14.MoveNext()---从抛出异常的先前位置开始的堆栈跟踪结束---在系统的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Dialogs.Internals.DialogTask.ThunkResume1.d4.MoveNext()中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) - 堆栈结束从抛出异常的先前位置追踪 - 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(System任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处于System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)at at Microsoft.Bot.Builder.Internals.Fibers.Wait2 . <Microsoft-Bot-Builder-Internals-Fibers-IWait <C> -PollAsync> d19.MoveNext() - 从抛出异常的上一个位置开始的堆栈跟踪结束 - 在S位于Microsoft.Bot.Builder.Internals.Fibers的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)中的ystem.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() . Frame1 . &lt; Microsoft-Bot-Builder-Internals-Fibers-IFrameLoop&lt; C&gt; -PollAsync&gt; d__9.MoveNext()---从抛出异常的先前位置开始的堆栈跟踪---在System.Runtime.ExceptionServices处 . 位于Microsoft.Bot.Builder.Internals.Fibers.Fiber1的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)中的ExceptionDispatchInfo.Throw() . <Microsoft-Bot -Builder-Internals-Fibers-IFiberLoop <C> -PollAsync> d16.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在Microsoft.Bot.Builder的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处 . 内部s.Fibers.Wait2.Microsoft.Bot.Builder.Internals.Fibers.IAwaiter&lt; T&gt; .GetResult()在Microsoft.Bot.Builder.Dialogs.Chain.FromDialog1 . <ResumeAsync> d3.MoveNext() - 堆栈跟踪结束从抛出异常的先前位置 - 在Microsoft的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处.Bot.Builder.Dialogs.Internals.DialogTask.ThunkResume1 . &lt; Rest&gt; d__4.MoveNext()---从抛出异常的上一个位置开始的堆栈跟踪结束---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw( )位于Microsoft.Bot.Builder.Internals.Fibers.Wait2的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) . <Microsoft-Bot-Builder-Internals -Fibers-IWAIT <C> -PollAsync> d19.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.CompilerServices上System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Internals.Fibers.Frame1.-PollAsync> d9.MoveNext()中的.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.ExceptionServices.ExceptionDispatchInfo .Throw()at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)at Microsoft.Bot.Builder.Internals.Fibers.Fiber1 . <Microsoft-Bot- Builder-Internals-Fibers-IFiberLoop <C> -PollAsync> d__16.MoveNext()---从抛出异常的上一个位置开始的堆栈跟踪结束---在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at Microsoft.Bot.Builder.Internals.Fibers.Wait2.Microsoft.Bot.Builder.Internals.Fibers.IAwaiter.GetResult()at Microsoft.Bot.Builder.Dialogs.Chain.LoopDialog1 . <ResumeAsync> d__3.MoveNext() - - 从之前的堆栈跟踪结束抛出异常的位置---在Microsoft的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处.Bot.Builder.Dialogs.Internals.DialogTask.ThunkResume1.d4.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.CompilerServices上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处 . 位于Microsoft.Bot.Builder.Internals.Fibers.Wait2的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的TaskAwaiter.ThrowForNonSuccess(任务任务) . <Microsoft-Bot-Builder-Internals-Fibers-IWait <C> - PollAsync> d19.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.CompilerServices.TaskAwaiter.ThrowFor的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处位于Microsoft.Bot.Builder.Internals.Fibers.Frame1的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的NonSuccess(任务任务) . &lt; Microsoft-Bot-Builder-Internals-Fibers-IFrameLoop&lt; C&gt; -PollAsync&gt ; d__9.MoveNext()---抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Internals.Fibers.Fiber1中的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) . <Microsoft-Bot-Builder-Internals-Fibers-IFiberLoop <C> -PollAsync> d16.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 位于System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebugge的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() Microsoft.Bot.Builder.Dialogs.Internals.DialogTask中的rNotification(任务任务) . <Microsoft-Bot-Builder-Dialogs-Internals-IDialogStack-PollAsync> d20.MoveNext() - 从抛出异常的上一个位置开始的堆栈跟踪结束 - 位于Microsoft.Bot.Builder.Dialogs的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() . Internals.DialogTask . <Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync> d221.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务),位于Microsoft.Bot.Builder.Dialogs.Internals.ReactiveDialogTask.d31.MoveNext的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) ()---抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处 . Microsoft.Bot.Builder.Dialogs.Internals.ScoringDialogTask1.d31.MoveNext()中的CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw ()Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)中的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) . <Microsoft-Bot-Builder- Dialogs-Internals-IPostToBot-PostAsync> d31.MoveNext()---从抛出异常的先前位置开始的堆栈跟踪结束---在Microsoft.Bot.Builder.Dialogs.Internals.PersistentDialogTask . &l t; Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync&gt; d__31.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)处的.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)at atMicrosoft.Bot.Builder.Dialogs.Internals.SerializingDialogTask . <Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync> d41.MoveNext() - 从抛出异常的上一个位置的堆栈跟踪结束 - 在System.Runtime . System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)中的ExceptionServices.ExceptionDispatchInfo.Throw()位于Microsoft.Bot.Builder.Dialogs.Internals.ExceptionTranslationDialogTask.d21的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) . MoveNext()---抛出异常的前一个位置的堆栈跟踪结束---在System.Runtime的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Dialogs.Internals.LocalizedDialogTask中的.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) . <Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync> d__21.MoveN ext() - 抛出异常的前一个位置的堆栈跟踪结束 - 在System.Runtime.CompilerServices.TaskAwaiter的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Dialogs.Internals.PostUnhandledExceptionToUserTask.d5`1.MoveNext()中的.HandleNonSuccessAndDebuggerNotification(任务任务) - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在Microsoft.Bot.Builder.Dialogs.Internals . PostUnhandledExceptionToUserTask.d51.MoveNext()---抛出异常的上一个位置的堆栈跟踪结束---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess上的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()(任务任务)在Microsoft.Bot.Builder.Dialogs.Internals.LogPostToBot的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) . <Microsoft-Bot-Builder-Dialogs-Internals-I PostToBot-PostAsync> d__31.MoveNext() - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在系统的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处Microsoft.Bot.Builder.Dialogs.Conversation.d4.MoveNext()中的.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) - 从抛出异常的先前位置开始的堆栈跟踪结束 - 在System.Runtime.ExceptionServices.ExceptionDispatchInfo中 . 在Microsoft.Bot.Builder.Dialogs.Conversation.d2.MoveNext()的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)中抛出() - 结束从抛出异常的先前位置堆栈跟踪 - 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSucces的System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()处s(任务任务)位于System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(任务任务)位于LUISBotAppTesting.MessagesController.d__1.MoveNext()

回答(1)

2 years ago

理解这个问题有点难,但我想提一下,函数 botUserData.SetProperty<>() 不保存属性,它只是编辑当前对象的属性 . 您应该使用 BotState.SetUserData() 并将对象传递给他以保存它 .
以下是保存bot状态的工作示例:

public static bool saveData(Activity activity, string key, string value)
{
    StateClient stateClient = activity.GetStateClient();
    BotData userData = stateClient.BotState.GetUserData(activity.ChannelId, activity.From.Id);
    userData.SetProperty<string>(key, value);
    BotData updateResponse = stateClient.BotState.SetUserData(activity.ChannelId, activity.From.Id, userData);
    return value == updateResponse.GetProperty<string>(key);
}