将漫游器会话存储到Azure sql数据库。未记录启动响应

时间:2019-01-04 14:17:12

标签: c# sql azure botframework bots

我使用Botframework v3创建了一个机器人,该机器人将对话记录到一个Azure SQL数据库中。它可以使用机器人模拟器来工作。僵尸程序记录的问题和用户响应记录在azure sql数据库中。

但是,当我使用Bot注册通道将Bot从Visual Studio部署到Azure时。 (我已经多次部署其他类型的机器人,并且通常可以正常工作)当我在(测试网络聊天)Azure门户中使用该机器人时,它失败了–收到消息“抱歉我的机器人有问题”和用户类型无法发送。

所发送的消息/用户键入的确实被记录在sql数据库中。但是,自动程序询问的问题不会记录在sql数据库中

SqlActivityogger类:

public class SqlActivityLogger : IActivityLogger
    {
    SqlConnection connection;

    public SqlActivityLogger(SqlConnection conn)
    {
        this.connection = conn;
    }
    public async Task LogAsync(IActivity activity)
    {
        string fromId = activity.From.Id;
        string toId = activity.Recipient.Id;
        string message = activity.AsMessageActivity().Text;

        //when creating the sql database make sure you create a table userChatLog table in the db in portal.azure.com
        string insertQuery = "INSERT INTO userChatLog(fromId, toId, message) VALUES (@fromId,@toId,@message)";

        // Passing the fromId, toId, message to the the user chatlog table 
        SqlCommand command = new SqlCommand(insertQuery, connection);
        command.Parameters.AddWithValue("@fromId", fromId);
        command.Parameters.AddWithValue("@toId", toId);
        command.Parameters.AddWithValue("@message", message);



        // Insert to Azure sql database
        command.ExecuteNonQuery();

        //command.ExecuteNonQuery();
        //Debug.WriteLine("Insertion successful of message: " + activity.AsMessageActivity().Text);
    }
}

Global.asax

 public class WebApiApplication : System.Web.HttpApplication
{
    SqlConnection connection = null;
    protected void Application_Start()
    {
        //setting up sql string connection string

        SqlConnectionStringBuilder sqlbuilder = new SqlConnectionStringBuilder();
        sqlbuilder.DataSource = "##########";
        sqlbuilder.UserID = "#####";
        sqlbuilder.Password = "#####";
        sqlbuilder.InitialCatalog = "######";

        connection = new SqlConnection(sqlbuilder.ConnectionString);
        connection.Open();
        Debug.WriteLine("Connection success");


        Conversation.UpdateContainer(builder =>
        {
            builder.RegisterType<SqlActivityLogger>().AsImplementedInterfaces().InstancePerDependency().WithParameter("conn", connection);
        });

        GlobalConfiguration.Configure(WebApiConfig.Register);
    }

    protected void Application_End()
    {

        connection.Close();
        Debug.WriteLine("Connection to database closed");
    }

}

三明治课

public enum SandwichOptions
{
    BLT, BlackForestHam, BuffaloChicken, ChickenAndBaconRanchMelt, ColdCutCombo, MeatballMarinara,
    OvenRoastedChicken, RoastBeef, RotisserieStyleChicken, SpicyItalian, SteakAndCheese, SweetOnionTeriyaki, Tuna,
    TurkeyBreast, Veggie
};
public enum LengthOptions { SixInch, FootLong };
public enum BreadOptions { NineGrainWheat, NineGrainHoneyOat, Italian, ItalianHerbsAndCheese, Flatbread };
public enum CheeseOptions { American, MontereyCheddar, Pepperjack };
public enum ToppingOptions
{
    Avocado, BananaPeppers, Cucumbers, GreenBellPeppers, Jalapenos,
    Lettuce, Olives, Pickles, RedOnion, Spinach, Tomatoes
};
public enum SauceOptions
{
    ChipotleSouthwest, HoneyMustard, LightMayonnaise, RegularMayonnaise,
    Mustard, Oil, Pepper, Ranch, SweetOnion, Vinegar
};

[Serializable]
public class SandwichOrder
{
    public SandwichOptions? Sandwich;
    public LengthOptions? Length;
    public BreadOptions? Bread;
    public CheeseOptions? Cheese;
    public List<ToppingOptions> Toppings;
    public List<SauceOptions> Sauce;

    public static IForm<SandwichOrder> BuildForm()
    {
        OnCompletionAsyncDelegate<SandwichOrder> processOrder = async (context, state) =>
        {
            await context.PostAsync("This is the end of the form, you would give a final confirmation, and then start the ordering process as needed.");
        };

        return new FormBuilder<SandwichOrder>()
                .Message("Welcome to the simple sandwich order bot!")
                .OnCompletion(processOrder)
                .Build();
    }
};

感谢帮助。我很久以来一直在试图解决这个问题,但不明白为什么它不起作用。

更新: 使用ngrok进行调试后,出现以下错误:

{
  "message": "An error has occurred.",
  "exceptionMessage": "String or binary data would be truncated.
The statement has been terminated.",
  "exceptionType": "System.Data.SqlClient.SqlException",
  "stackTrace": "   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry)
   at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
   at FormBot.Models.SqlActivityLogger.<LogAsync>d__2.MoveNext() in C:\\FormSqlTest1-src\\Models\\SqlActivityLogger.cs:line 42
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Bot.Builder.Dialogs.Internals.LogPostToBot.<Microsoft-Bot-Builder-Dialogs-Internals-IPostToBot-PostAsync>d__3.MoveNext() in D:\\a\\1\\s\\CSharp\\Library\\Microsoft.Bot.Builder\\ConnectorEx\\IActivityLogger.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Bot.Builder.Dialogs.Conversation.<SendAsync>d__11.MoveNext() in D:\\a\\1\\s\\CSharp\\Library\\Microsoft.Bot.Builder.Autofac\\Dialogs\\Conversation.cs:line 182
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Bot.Builder.Dialogs.Conversation.<SendAsync>d__6.MoveNext() in D:\\a\\1\\s\\CSharp\\Library\\Microsoft.Bot.Builder.Autofac\\Dialogs\\Conversation.cs:line 108
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at Microsoft.Bot.Sample.FormBot.MessagesController.<Post>d__1.MoveNext() in C:\\FormSqlTest1-src\\Controllers\\MessagesController.cs:line 35
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Threading.Tasks.TaskHelpersExtensions.<CastToObject>d__3`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"
}

错误:“字符串或二进制数据将被截断。”

但是我只是在打单打招呼

任何建议...非常感谢您的任何帮助。谢谢

1 个答案:

答案 0 :(得分:0)

我实际上曾经遇到过SQL截断错误,尽管不是在使用Bot Framework时遇到的。记录CHARVARCHAR列的最大长度非常重要,这样可以确保写入到这些列的所有内容都在限制范围内。如有必要,应先截断字符串,然后再将其发送到数据库。

确定了列的最大长度后,请在LogAsync方法中设置一个断点,以便在记录每个活动时可以查看每个活动的详细信息。您说您只是在输入诸如“ hello”之类的短消息,但请记住,登录失败的不是您的消息,而是机器人的消息。由于尚不清楚您的机器人在模拟器中运行时,还是在其他通道上运行时,您的机器人发送的消息之间在操作上有什么区别,因此请同时注意fromIdtoId,特别是如果表中的这些列包含不同的长度。不同的渠道会生成不同的ID,在模拟器中,机器人的ID通常只有一位数字。

TL; DR:找出fromId表中toIdmessageuserChatLog列的最大长度,然后调试代码并查看值是当它破裂时。