【问题标题】:Bot Framework is calling constructor of object again between dialogsBot Framework 在对话框之间再次调用对象的构造函数
【发布时间】:2020-03-19 02:15:13
【问题描述】:

大家好,很抱歉这是我第一次发布问题,因为我无法找到解决方案。我正在 MS-Bot 框架中制作一个聊天机器人,并尝试将对象“项目”传递给另一个对话框:

return await stepContext.BeginDialogAsync(nameof(searchProject2), new Project(new string[]{"ixnID"}, new string[]{"1"}), cancellationToken);

但是,当我在下一个对话框中执行此操作时,在 TextPrompt 中输入消息后,机器人会立即崩溃并返回 NullReferenceException 错误:

     [OnTurnError] unhandled error : Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
   at ixnChatbot.Project..ctor(String[] rawFields, String[] values) in C:\Users\a\ixnChatbot\Models\Project.cs:li
ne 24
   at lambda_method(Closure , Object[] )
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObjectUsingCreatorWithParameters(JsonReader reader, JsonObjectContract contract, JsonProperty containerProperty, ObjectConstructor`1 cr
eator, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonPro
perty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract,
JsonProperty containerMember, Object existingValue) .............

调试后,我发现构造函数被调用了两次,即使在将 Project 传递到新对话框之后,我的任何代码都无法访问它。这是构造函数和它使用的类中的变量:

protected readonly int ixnID;
private Dictionary<string, int> fields = new Dictionary<string, int>();
private string[] values;

protected string fieldGetterQueryWholeTable
    = "SELECT COLUMN_NAME FROM information_schema.columns WHERE table_name in('IXN_database_entries')";
protected string searchQuery;

public Project(string[] rawFields, string[] values)
{
    this.values = values;

    for (int i = 0; i < rawFields.Length; i++)
    {
        fields.Add(rawFields[i], i);
    }

    ixnID = Int32.Parse(values[fields["ixnID"]]);
    searchQuery =
        "SELECT * FROM IXN_database_entries i WHERE i.ixnID = " + ixnID;
}

这是正在使用的瀑布步骤。如您所见,我还没有接触过传入的对象:

private async Task<DialogTurnResult> oneAsync(WaterfallStepContext stepContext,
    CancellationToken cancellationToken)
{ 
    var promptOptions = new PromptOptions { Prompt = MessageFactory.Text("What would you like to know about this project?") };
    return await stepContext.PromptAsync(nameof(TextPrompt), promptOptions, cancellationToken);
}

private async Task<DialogTurnResult> twoAsync(WaterfallStepContext stepContext,
    CancellationToken cancellationToken)
{
    await stepContext.Context.SendActivityAsync(stepContext.Result.ToString());
    return await stepContext.ReplaceDialogAsync(InitialDialogId, null, cancellationToken);
}

错误发生在这两个瀑布步骤之间。我能够调试并发现由于某种原因,机器人正在重新调用 Project 类中的构造函数,但是第二次调用它时,作为参数传入的列表“rawField”为空,这就是它的原因抛出此 NullReference 错误。

我的问题是,如何阻止框架这样做?我不明白为什么传入对象会导致这种错误,并且在使用字符串等原始类型时似乎不会发生。我搜索了一段时间,没有发现任何类似的问题。任何帮助将不胜感激!

【问题讨论】:

    标签: c# oop dialog botframework chatbot


    【解决方案1】:

    所以我找到了解决方案(哎呀),以防万一有人遇到这个问题。

    我刚刚向 Project 类添加了一个空的构造函数,这样当它被调用时,它的参数就不会出现 null 错误。

    public Project()
        {
    
        }
    

    这也有效:

    [JsonConstructor]
    private Project()
    {
    
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      相关资源
      最近更新 更多